【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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章