【14】基于C++的OpenCV同态滤波

同态滤波的主要目的是为了消除光照不均,将空间域的图像信息转换为频率域进行处理,通过滤波器对频率域图像进行滤波,降低光照不均匀现象的影响,完成滤波后,再将图像转换到空间域中。

【1】源码

//同态滤波
#include"HomoFilter.h"
#include <iostream>
#include<opencv2/core.hpp>
#include<opencv.hpp>
#include<time.h>
#include <math.h>


using namespace cv;
using namespace std;

Mat HomoFilter(Mat inputImg) {
	Mat homoImg = inputImg.clone();
	Mat orginalImg = inputImg.clone();
	homoImg.convertTo(homoImg, CV_64FC1);
	int rows = homoImg.rows;
	int cols = homoImg.cols;
	int m = rows % 2 == 1 ? rows + 1 : rows;
	int n = cols % 2 == 1 ? cols + 1 : cols;
	copyMakeBorder(homoImg, homoImg, 0, m - rows, 0, n - cols, BORDER_CONSTANT, Scalar::all(0));
	rows = homoImg.rows;
	cols = homoImg.cols;
	Mat homo_result_Img(rows, cols, CV_64FC1);
	//1. ln
	for (int i = 0; i < rows; i++) {
		double *srcdata = homoImg.ptr<double>(i);
		double *logdata = homoImg.ptr<double>(i);
		for (int j = 0; j < cols; j++) {
			logdata[j] = log(srcdata[j] + 0.0001);
		}
	}
	//2. dct 离散余弦变换
	Mat mat_dct = Mat::zeros(rows, cols, CV_64FC1);
	dct(homoImg, mat_dct);
	//3. 高斯同态滤波器
	Mat H_u_v;
	double gammaH = 3;//>1   高频增益
	double gammaL = 0.1;//<1   低频增益
	double C = 0.6; //斜面锐化常数 斜率
	double  d0 = (homoImg.rows / 2) * (homoImg.rows / 2) + (homoImg.cols / 2) * (homoImg.cols / 2);//截止频率
	//double  d0 = 150;//5-200  截止频率 越大越亮
	double  d2 = 0;
	H_u_v = Mat::zeros(rows, cols, CV_64FC1);
	for (int i = 0; i < rows; i++) {
		double * dataH_u_v = H_u_v.ptr<double>(i);
		for (int j = 0; j < cols; j++) {
			d2 = pow((i- homoImg.rows / 2), 2.0) + pow((j- homoImg.cols / 2), 2.0);
			dataH_u_v[j] = (gammaH - gammaL) * (1 - exp(-C * (d2 / d0))) + gammaL;
		}
	}
	H_u_v.ptr<double>(0)[0] = 1.1;
	mat_dct = mat_dct.mul(H_u_v);
	//4. idct
	idct(mat_dct, homo_result_Img);
	//exp
	for (int i = 0; i < rows; i++) {
		double *srcdata = homo_result_Img.ptr<double>(i);
		double *dstdata = homo_result_Img.ptr<double>(i);
		for (int j = 0; j < cols; j++) {
			dstdata[j] = exp(srcdata[j]);
		}
	}
	homo_result_Img.convertTo(homo_result_Img, CV_8UC1);
	return homo_result_Img;
}

//YUV空间
Mat YHomoFilter(Mat orginalImg)
{
	int original_rows = orginalImg.rows;
	int original_cols = orginalImg.cols;
	Mat dst(original_rows, original_cols, CV_8UC3);
	cvtColor(orginalImg, orginalImg, COLOR_BGR2YUV);
	vector <Mat> yuvImg;
	split(orginalImg, yuvImg);
	Mat nowY = yuvImg[0];
	Mat newY = HomoFilter(nowY);
	Mat tempY(original_rows, original_cols, CV_8UC1);
	for (int i = 0; i < original_rows; i++) {
		for (int j = 0; j < original_cols; j++) {
			tempY.at<uchar>(i, j) = newY.at<uchar>(i, j);
		}
	}
	yuvImg[0] = tempY;
	merge(yuvImg, dst);
	cvtColor(dst, dst, COLOR_YUV2BGR);
	return dst;
}

int main() 
{
	Mat src = imread("04.jpg");
	Mat homoImg=YHomoFilter(src);
	imwrite("04homoImg.jpg", homoImg);
	//Mat  allImg=SpliteImg(src);

	waitKey(0);
	return 0;
}

【2】结果

    

【3】参考

(1)经典的同态滤波算法的优化及其应用参数配置。

(2)同态滤波 原理及C++实现

(3)https://github.com/lilingyu/homofilter/blob/master/hello_opencv/homo_filter.cpp

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值