OpenCV:同态滤波器 [英] OpenCV : homomorphic filter

查看:2639
本文介绍了OpenCV:同态滤波器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用同态滤波器来处理水下图像。我试图用在互联网上找到的代码编码,但我总是一个黑色的图像...我试图规范化我的结果,但没有工作。

i want to use a homomorphic filter to work on underwater image. I tried to code it with the codes found on the internet but i have always a black image... I tried to normalized my result but didn't work.

在这里我的功能:

void HomomorphicFilter::butterworth_homomorphic_filter(Mat &dft_Filter, int D, int n, float high_h_v_TB, float low_h_v_TB)
{
Mat single(dft_Filter.rows, dft_Filter.cols, CV_32F);
Point centre = Point(dft_Filter.rows/2, dft_Filter.cols/2);
double radius;
float upper = (high_h_v_TB * 0.01);
float lower = (low_h_v_TB * 0.01);

//create essentially create a butterworth highpass filter
//with additional scaling and offset
for(int i = 0; i < dft_Filter.rows; i++)
{
    for(int j = 0; j < dft_Filter.cols; j++)
    {
        radius = (double) sqrt(pow((i - centre.x), 2.0) + pow((double) (j - centre.y), 2.0));
        single.at<float>(i,j) =((upper - lower) * (1/(1 + pow((double) (D/radius), (double) (2*n))))) + lower;
    }
}
//normalize(single, single, 0, 1, CV_MINMAX);
//Apply filter
mulSpectrums( dft_Filter, single, dft_Filter, 0);
}

void HomomorphicFilter::Shifting_DFT(Mat &fImage)
{
//For visualization purposes we may also rearrange the quadrants of the result, so that the origin (0,0), corresponds to the image center.
Mat tmp, q0, q1, q2, q3;

/*First crop the image, if it has an odd number of rows or columns.
Operator & bit to bit by -2 (two's complement : -2 = 111111111....10) to eliminate the first bit 2^0 (In case of odd number on row or col, we take the even number in below)*/
fImage = fImage(Rect(0, 0, fImage.cols & -2, fImage.rows & -2));
int cx = fImage.cols/2;
int cy = fImage.rows/2;

/*Rearrange the quadrants of Fourier image so that the origin is at the image center*/
q0 = fImage(Rect(0, 0, cx, cy));
q1 = fImage(Rect(cx, 0, cx, cy));
q2 = fImage(Rect(0, cy, cx, cy));
q3 = fImage(Rect(cx, cy, cx, cy));

/*We reverse each quadrant of the frame with its other quadrant diagonally opposite*/
/*We reverse q0 and q3*/
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);

/*We reverse q1 and q2*/
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
}

void HomomorphicFilter::Fourier_Transform(Mat frame_bw, Mat &image_phase, Mat &image_mag)
{
Mat frame_log;
frame_bw.convertTo(frame_log, CV_32F);
/*Take the natural log of the input (compute log(1 + Mag)*/
frame_log += 1;
log( frame_log, frame_log); // log(1 + Mag)

/*2. Expand the image to an optimal size
The performance of the DFT depends of the image size. It tends to be the fastest for image sizes that are multiple of 2, 3 or 5.
We can use the copyMakeBorder() function to expand the borders of an image.*/
Mat padded;
int M = getOptimalDFTSize(frame_log.rows);
int N = getOptimalDFTSize(frame_log.cols);
copyMakeBorder(frame_log, padded, 0, M - frame_log.rows, 0, N - frame_log.cols, BORDER_CONSTANT, Scalar::all(0));

/*Make place for both the complex and real values
The result of the DFT is a complex. Then the result is 2 images (Imaginary + Real), and the frequency domains range is much larger than the spatial one. Therefore we need to store in float !
That's why we will convert our input image "padded" to float and expand it to another channel to hold the complex values.
Planes is an arrow of 2 matrix (planes[0] = Real part, planes[1] = Imaginary part)*/
Mat image_planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
Mat image_complex;
/*Creates one multichannel array out of several single-channel ones.*/
merge(image_planes, 2, image_complex);

/*Make the DFT
The result of thee DFT is a complex image : "image_complex"*/
dft(image_complex, image_complex);

/***************************/
//Create spectrum magnitude//
/***************************/
/*Transform the real and complex values to magnitude
NB: We separe Real part to Imaginary part*/
split(image_complex, image_planes);
//Starting with this part we have the real part of the image in planes[0] and the imaginary in planes[1]
phase(image_planes[0], image_planes[1], image_phase);
magnitude(image_planes[0], image_planes[1], image_mag);
}

void HomomorphicFilter::Inv_Fourier_Transform(Mat image_phase, Mat image_mag, Mat &inverseTransform)
{
/*Calculates x and y coordinates of 2D vectors from their magnitude and angle.*/
Mat result_planes[2];
polarToCart(image_mag, image_phase, result_planes[0], result_planes[1]);

/*Creates one multichannel array out of several single-channel ones.*/
Mat result_complex;
merge(result_planes, 2, result_complex);

/*Make the IDFT*/
dft(result_complex, inverseTransform, DFT_INVERSE|DFT_REAL_OUTPUT);

/*Take the exponential*/
exp(inverseTransform, inverseTransform);
}

这里是我的主要代码:

    /**************************/
    /****Homomorphic filter****/
    /**************************/
    /**********************************************/
    //Getting the frequency and magnitude of image//
    /**********************************************/
    Mat image_phase, image_mag;
    HomomorphicFilter().Fourier_Transform(frame_bw, image_phase, image_mag);
    /******************/
    //Shifting the DFT//
    /******************/
    HomomorphicFilter().Shifting_DFT(image_mag);
    /********************************/
    //Butterworth homomorphic filter//
    /********************************/
    int high_h_v_TB = 101;
    int low_h_v_TB = 99;
    int D = 10;// radius of band pass filter parameter
    int order = 2;// order of band pass filter parameter
    HomomorphicFilter().butterworth_homomorphic_filter(image_mag, D, order, high_h_v_TB, low_h_v_TB);
    /******************/
    //Shifting the DFT//
    /******************/
    HomomorphicFilter().Shifting_DFT(image_mag);
    /*******************************/
    //Inv Discret Fourier Transform//
    /*******************************/
    Mat inverseTransform;
    HomomorphicFilter().Inv_Fourier_Transform(image_phase, image_mag, inverseTransform);
    imshow("Result", inverseTransform);

如果有人能解释我的错误,我会很感激:)。谢谢你,对不起我的可怜的英语。

If someone can explain me my mistakes, I would appreciate a lot :). Thank you and sorry for my poor english.

编辑:现在,我有东西,但它不是完美的...我修改了2件事在我的代码。
我在dft之后应用log(mag + 1),而不是在输入图像上。
我删除了idft之后的exp()。

EDIT : Now, i have something but it's not perfect ... I modified 2 things in my code. I applied log(mag + 1) after dft and not on the input image. I removed exp() after idft.

这里的结果(我只能发布2个链接...):

here the results (i can post only 2 links ...) :

我的输入图片:
最终结果:

my input image : final result :

在看过几个主题之后,我在我的Butterworth筛选器和我的dft /移位后的幅度上找到类似的结果。
不幸的是,我的最终结果不是很好。为什么我有这么多的噪音?

after having seen several topics, i find similar results on my butterworth filter and on my magnitude after dft/shifting. Unfortunately, my final result isn't very good. Why i have so much "noise" ?

推荐答案

我是这样做的方法来平衡相机更换时的照明,黑暗!

I was doing this method to balance illumination when camera was changed caused the Image waw dark!

我试图对频率进行FFT以过滤图像!它是工作,但使用太多的时间。(2750 * 3680RGB图像)。我在空间域。

I tried to FFT to the frequency to filter the image! it's work.but use too much time.(2750*3680RGB image).so I do it in Spatial domain.

这里是我的代码!

//IplImage *imgSrcI=cvLoadImage("E:\\lean.jpg",-1);
Mat imgSrcM(imgSrc,true);
Mat imgDstM;

Mat imgGray;
Mat imgHls;
vector<Mat> vHls;

Mat imgTemp1=Mat::zeros(imgSrcM.size(),CV_64FC1);
Mat imgTemp2=Mat::zeros(imgSrcM.size(),CV_64FC1);

if(imgSrcM.channels()==1)
{
    imgGray=imgSrcM.clone();
}
else if (imgSrcM.channels()==3)
{
    cvtColor(imgSrcM, imgHls, CV_BGR2HLS);
    split(imgHls, vHls);
    imgGray=vHls.at(1);
}
else
{
    return -1;
}
imgGray.convertTo(imgTemp1,CV_64FC1);
imgTemp1=imgTemp1+0.0001;
log(imgTemp1,imgTemp1);

GaussianBlur(imgTemp1, imgTemp2, Size(21, 21), 0.1, 0.1, BORDER_DEFAULT);//imgTemp2是低通滤波的结果
imgTemp1 = (imgTemp1 - imgTemp2);//imgTemp1是对数减低通的高通
addWeighted(imgTemp2, 0.7, imgTemp1, 1.4, 1, imgTemp1, -1);//imgTemp1是压制低频增强高频的结构

exp(imgTemp1,imgTemp1);
normalize(imgTemp1,imgTemp1,0,1,NORM_MINMAX);
imgTemp1=imgTemp1*255;

imgTemp1.convertTo(imgGray, CV_8UC1);

//imwrite("E:\\leanImgGray.jpg",imgGray);
if (imgSrcM.channels()==3)
{
    vHls.at(1)=imgGray;
    merge(vHls,imgHls);
    cvtColor(imgHls, imgDstM, CV_HLS2BGR);

}
else if (imgSrcM.channels()==1)
{
    imgDstM=imgGray.clone();
}

cvCopy(&(IplImage)imgDstM,imgDst);
//cvShowImage("jpg",imgDst);

return 0;

这篇关于OpenCV:同态滤波器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆