Gaussian Filter from DFT

本文介绍了一个使用C++与OpenCV实现的高斯高通滤波器创建及应用过程。作者从DFT代码出发,详细展示了如何通过自定义函数生成高斯高通滤波器,并将其应用于图像的频域处理中,最终通过逆DFT得到处理后的图像。


I've done anything that i got, I just want to create a Gaussian Filter from DFT code that I've done. Here is the code :

//#include <stdafx.h>

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <stdio.h>
#include <iostream>

using namespace cv;
using namespace std;

double pixelDistance(double u, double v)
{
    return cv::sqrt(u*u + v*v);
}

double gaussianCoeff(double u, double v, double d0)
{
    double d = pixelDistance(u, v);
    return cv::exp((-d*d) / (2 * d0*d0));
}

cv::Mat createGaussianHighPassFilter(cv::Size size, double cutoffInPixels)
{
    Mat ghpf(size, CV_64F);

    cv::Point center(size.width / 2, size.height / 2);

    for (int u = 0; u < ghpf.rows; u++)
    {
        for (int v = 0; v < ghpf.cols; v++)
        {
            ghpf.at<double>(u, v) = gaussianCoeff(u - center.y, v - center.x, cutoffInPixels);
        }
    }

    return ghpf;
}


void translateImg(Mat& imgIn, Mat& imgOut)
{
    int i, j;

    for (i = 0; i < imgIn.rows; i++)
        for (j = 0; j < imgIn.cols; j++)
            imgOut.at<double>(i, j) = imgIn.at<double>(i, j) * pow(-1.0, i + j);
}
void scaleImg(Mat& imgIn, Mat& imgOut, float scaleFactor)
{
    int i, j;

    for (i = 0; i < imgIn.rows; i++)
        for (j = 0; j < imgIn.cols; j++)
            imgOut.at<double>(i, j) = (double)scaleFactor * log(1.0 + imgIn.at<double>(i, j));
}

void consoleOut(cv::Mat outMat, int rows = 5, int cols = 5)
{
    rows = ((rows == -1 || rows >= outMat.rows) ? outMat.rows : rows);
    cols = ((cols == -1 || cols >= outMat.cols) ? outMat.cols : cols);

    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            cout << outMat.at<double>(i, j);
            cout << " ";
        }
        cout << endl;
    }
}

double calcMSE(Mat& imgOrig, Mat& imgReconst)
{
    int valOrig = 0, valReconst = 0;
    double MSE = 0.0;

    for (int i = 0; i < imgOrig.rows; i++)
    {
        for (int j = 0; j < imgOrig.cols; j++)
        {
            valOrig = imgOrig.at<unsigned char>(i, j);
            valReconst = imgReconst.at<unsigned char>(i, j);

            MSE += pow((double)(valOrig - valReconst), 2.0);
        }
    }
    return (MSE / (imgOrig.rows * imgOrig.cols));
}

string convertInt(int number) // converts integer to string
{
    stringstream ss;
    ss << number;
    return ss.str();
}

int main(unsigned int argc, char* const argv[])
{
    int dftH, dftW;
    cv::Mat imgIn;

    imgIn = cv::imread("fri.pgm", 0); //grayscale
    imshow("Original Image", imgIn);
    waitKey();

    dftH = cv::getOptimalDFTSize(imgIn.rows);
    dftW = cv::getOptimalDFTSize(imgIn.cols);

    Mat imgMod;
    Mat imgPrecFFT(dftH, dftW, CV_64FC1, Scalar::all(0));
    imgIn.convertTo(imgMod, CV_64FC1);
    imgPrecFFT = imgMod(cv::Range::all(), cv::Range::all()).clone();

    // translate image
    std::vector<Mat> imgsTrans;
    imgsTrans.push_back(Mat_<double>(imgIn.size(), CV_64FC1));
    imgsTrans.push_back(Mat_<double>(imgIn.size(), CV_64FC1));
    imgsTrans[1].setTo(Scalar::all(0), Mat());
    translateImg(imgPrecFFT, imgsTrans[0]);

    Mat imgPrecTransFFT(imgIn.size(), CV_64FC2, Scalar::all(0));
    cv::merge(imgsTrans, imgPrecTransFFT);

    // dft
    cv::Mat imgFFT;
    dft(imgPrecTransFFT, imgFFT, DFT_COMPLEX_OUTPUT);
    cv::Mat imgDispFFT;

    // gaussian filter
    Mat ghpf = createGaussianHighPassFilter(Size(128, 128), 16.0);
    imshow("Gaussian Filter", ghpf);
    mulSpectrums(imgFFT, ghpf, imgFFT, 0, 0);
    waitKey();

    // calculate magnitude
    Mat imgMagnitude(imgIn.size(), CV_64FC1);
    std::vector<Mat> chans;
    cv::split(imgFFT, chans);
    cv::magnitude(chans[0], chans[1], imgMagnitude);

    // scale magnitude image
    Mat imgMagnitudeScaled(imgIn.size(), CV_64FC1);
    scaleImg(imgMagnitude, imgMagnitudeScaled, 10.0);

    // display magnitude image
    cv::Mat imgDisp;
    cv::convertScaleAbs(imgMagnitudeScaled, imgDisp);
    imshow("Magnitude Output", imgDisp);
    waitKey();

    // inverse dft
    cv::split(imgFFT, chans);
    chans[1].zeros(imgIn.size(), CV_64FC1);
    cv::merge(chans, imgFFT);
    cv::Mat invFFT;
    cv::idft(imgFFT, invFFT, DFT_REAL_OUTPUT + DFT_SCALE);

    // translate image back to original location
    cv::split(invFFT, imgsTrans);
    Mat imgAfterTrans(imgIn.size(), CV_64FC1);
    translateImg(imgsTrans[0], imgAfterTrans);
    imgAfterTrans.convertTo(imgDisp, CV_8UC1);

    imshow("After Inverse Output", imgDisp);
    waitKey();

    // calculate and output mean-squared error between input/output images
    double MSE = calcMSE(imgIn, imgDisp);
    cout << endl << "MSE: " << MSE << endl;
    waitKey();

    return 0;
}

I've try mulspectrum but it said it's error, then how can I merge the Gaussian Filter with the DFT one?   


 
                         
                                                                           
   

<think>嗯,用户的问题是关于为什么在已经有数据的情况下还需要添加噪声以及生成新数据。首先,我需要理解用户的具体情况。用户提到有一个Excel文件,里面有四个症状(A、B、C、D)的Raman和SERS数据,还有DFT图像。他们已经拥有这些数据,但可能需要重新生成代码,可能之前的代码有问题或者不符合需求。 首先,用户的问题分为两部分:为什么要加噪声,以及为什么已经有数据了还要生成新数据。我需要从这两个方面来回答。 关于加噪声的原因,常见的情况包括增强模型的鲁棒性,防止过拟合,模拟真实环境中的噪声,数据增强等。用户可能有自己的数据,但如果在实际应用中数据可能存在噪声,那么训练时加入噪声可以让模型更好地处理这种情况。此外,如果数据量不足,通过添加噪声可以生成更多的训练样本,提高模型的泛化能力。 然后是为什么需要生成数据。用户已经有一个包含多个分表格的Excel文件,但可能数据量不够,或者数据分布不均衡。例如,某些症状的数据可能较少,导致模型训练时偏向多数类。生成新数据可以平衡数据集,提高模型的性能。此外,如果用户要验证模型的泛化能力,可能需要更多的测试数据,或者需要不同的数据分布来测试模型。 接下来,用户提到需要重新生成代码,根据他们的信息。我需要考虑用户的数据格式,Excel文件中的八个分表格,四种症状的Raman和SERS数据,以及DFT图像。可能需要编写代码来读取这些数据,进行处理(如加噪声),然后生成新的数据集。同时,可能需要使用DFT图像,可能需要图像处理相关的步骤。 需要确认用户的数据结构,例如每个分表格的列名、数据格式,以及DFT图像的存储方式。如果用户提供的数据结构不明确,可能需要假设或建议用户提供更多细节。此外,生成代码可能需要使用Python库如pandas读取Excel,numpy进行数据增强,可能用到图像处理库如PIL或OpenCV处理DFT图像。 在编写代码时,应该包括读取Excel中的各个表格,对每个症状的Raman和SERS数据添加噪声,生成新的数据,并保存到新的Excel文件或另外的格式中。同时,如果需要处理DFT图像,可能需要为图像添加噪声,如高斯噪声,并将其保存。 可能用户之前生成的代码没有正确处理这些步骤,或者没有考虑到数据增强的具体需求,比如噪声的类型和强度。因此,重新生成代码需要更准确地根据用户的数据结构和需求来调整参数,比如噪声水平、生成的数据量等。 另外,用户可能关心如何将生成的数据与原有数据结合使用,是否需要划分训练集和测试集,或者如何进行交叉验证。代码可能需要包含这些步骤,或者用户需要进一步的指导。 总结来说,回答需要分两部分:解释加噪声的原因和数据生成的必要性,然后根据用户的数据结构提供相应的代码示例,并说明代码的逻辑和如何调整参数。同时,需要提醒用户可能需要根据实际数据结构修改代码,比如Excel表格的具体名称、列名等。</think>**针对您的问题,我将分两部分解释原因,并提供示例代码框架:** **一、为什么要加噪声?** 1. **提升模型鲁棒性**:真实检测中常存在仪器噪声、环境干扰,添加噪声可模拟真实场景 2. **防止过拟合**:当数据量较小时,噪声相当于数据增强,避免模型"死记硬背"原始数据 3. **特征稳定性验证**:检验DFT特征是否在噪声干扰下仍保持可分性 **二、已有数据为何要生成新数据?** 1. **数据量不足**:深度学习通常需要>1000样本/类,临床数据常存在小样本问题 2. **数据分布补偿**:原始数据可能存在采集偏差(如不同设备/操作者导致的分布差异) 3. **多模态融合**:结合Raman光谱(1D)和DFT图像(2D)需要统一数据格式 **示例代码框架(需根据实际数据结构调整):** ```python import pandas as pd import numpy as np from scipy import ndimage def add_spectral_noise(data, noise_level=0.05): """为光谱数据添加高斯噪声""" noise = np.random.normal(0, noise_level*np.std(data), data.shape) return data + noise def augment_dft_image(img, sigma=0.5): """为DFT图像添加随机模糊和噪声""" blurred = ndimage.gaussian_filter(img, sigma=np.random.uniform(0.1, sigma)) noisy = blurred + np.random.poisson(blurred*0.1) return np.clip(noisy, 0, 1) # 读取原始数据 excel_path = "your_data.xlsx" dfs = pd.read_excel(excel_path, sheet_name=None) # 数据增强参数 NUM_AUGMENT = 5 # 每样本生成副本数 NOISE_LEVELS = {'Raman':0.08, 'SERS':0.12} # 不同模态噪声系数 # 生成增强数据 augmented_data = [] for sheet_name, df in dfs.items(): # 提取光谱数据(假设列为'wavenumber'和'intensity') spectral_data = df[['wavenumber', 'intensity']].values # 提取DFT图像路径(假设'image_path'列) image_paths = df['image_path'] for _ in range(NUM_AUGMENT): # 添加光谱噪声 modality_type = sheet_name.split('_')[-1] # 假设表名格式如"A_Raman" noisy_spectra = add_spectral_noise( spectral_data[:,1], NOISE_LEVELS[modality_type] ) # 增强DFT图像 original_image = load_image(image_paths[0]) # 需实现图像加载函数 augmented_image = augment_dft_image(original_image) # 保存增强后的数据 augmented_entry = { 'wavenumber': spectral_data[:,0], 'intensity': noisy_spectra, 'dft_image': augmented_image, 'label': sheet_name.split('_')[0] } augmented_data.append(augmented_entry) # 转换为DataFrame并保存(需根据数据结构调整) pd.DataFrame(augmented_data).to_excel("augmented_data.xlsx") ``` **需要您确认的数据细节:** 1. Excel表格的具体结构(列名、数据格式) 2. DFT图像的存储方式(单独文件路径还是嵌入Excel) 3. 症状标签的编码方式(ABCD对应何种疾病分类) **建议后续步骤:** 1. 提供部分数据样例(可脱敏) 2. 说明最终应用场景(分类/回归?临床诊断/机理研究?) 3. 明确硬件环境(是否使用GPU加速) 我可以根据这些信息进一步优化数据增强策略和代码实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值