void my_HomoFilter(Mat srcImg, Mat &dst)
{
srcImg.convertTo(srcImg, CV_64FC1);
dst.convertTo(dst, CV_64FC1);
//1. ln
for (int i = 0; i < srcImg.rows; i++)
{
double* srcdata = srcImg.ptr<double>(i);
double* logdata = srcImg.ptr<double>(i);
for (int j = 0; j < srcImg.cols; j++)
{
logdata[j] = log(srcdata[j] + 0.0001);
}
}
//spectrum
//2. dct
Mat mat_dct = Mat::zeros(srcImg.rows, srcImg.cols, CV_64FC1);
dct(srcImg, mat_dct);
//3. linear filter
Mat H_u_v;
double gammaH = 1.5;
double gammaL = 0.5;
double C = 1;
double d0 = (srcImg.rows / 2)*(srcImg.rows / 2) + (srcImg.cols / 2)*(srcImg.cols / 2);
double d2 = 0;
H_u_v = Mat::zeros(srcImg.rows, srcImg.cols, CV_64FC1);
double totalWeight = 0.0;
for (int i = 0; i < srcImg.rows; i++)
{
double * dataH_u_v = H_u_v.ptr<double>(i);
for (int j = 0; j < srcImg.cols; j++)
{
d2 = pow((i), 2.0) + pow((j), 2.0);
dataH_u_v[j] = (gammaH - gammaL)*(1 - exp(-C*d2 / d0)) + gammaL;
totalWeight += dataH_u_v[j];
}
}
H_u_v.ptr<double>(0)[0] = 1.1;
//imshow("before filter", mat_dct);
mat_dct = mat_dct.mul(H_u_v);
idct(mat_dct, dst);
#if 0
//spatial high high pass filter
Mat tmp = Mat::zeros(srcImg.rows, srcImg.cols, CV_64FC1);
GaussianBlur(srcImg, tmp, Size(9, 9), 1.5, 1.5);
const double alpha = 0.5;
for (int i = 0; i < srcImg.rows; i++)
{
double* srcdata = srcImg.ptr<double>(i);
double* blurdata = tmp.ptr<double>(i);
double* dstdata = dst.ptr<double>(i);
for (int j = 0; j < srcImg.cols; j++)
{
dstdata[j] = (1 + alpha)*srcdata[j] - alpha*blurdata[j];
//dstdata[j] = blurdata[j];
}
}
#endif
//5. exp
for (int i = 0; i < srcImg.rows; i++)
{
double* srcdata = dst.ptr<double>(i);
double* dstdata = dst.ptr<double>(i);
for (int j = 0; j < srcImg.cols; j++)
{
dstdata[j] = exp(srcdata[j]);
}
}
//imshow("dst", dst);
dst.convertTo(dst, CV_8UC1);
}
void main()
{ /* -- 第一步:读入图像矩阵 -- */
Mat image = imread("lena.jpg", 0);
Mat result = image.clone();
my_HomoFilter(image, result);
cout << "";
}