OpenCV实现同态滤波
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                OpenCV实现同态滤波
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.                        
                                同態(tài)濾波是屬于圖像增強的一個小算法,其原理和代碼實現(xiàn)在眾多博客中均有提及,再此,只對學習中一些自認為有用的知識點進行總結。
實現(xiàn)和學習過程中的一些總結:
- 同態(tài)濾波類似于灰度變換,都是對灰度級進行動態(tài)范圍壓縮和對比度增強來改善圖像的外觀。
 - 圖像f(x,y)f(x,y)f(x,y)可以表示為其照射分量i(x,y)i(x,y)i(x,y)和反射分量r(x,y)r(x,y)r(x,y)的乘積,即:f(x,y)=i(x,y)r(x,y)f(x,y)=i(x,y)r(x,y)f(x,y)=i(x,y)r(x,y)
 - 照射分量對應圖像中的低頻部分,在光源中來說對應漫反射光,反射分量對應圖像中高頻部分,在光源中對于鏡面反射光。
 - 在算法開始,先要對圖像進行對數(shù)處理,若f(x,y)f(x,y)f(x,y)中有任何零值,則必須將圖像加1,以避免In(0)In(0)In(0)的出現(xiàn),然后從最終結果中減去1。
 
一些未出現(xiàn)的工具函數(shù)可以參考我之前的博客:圖像基礎頻率域濾波
代碼實現(xiàn)如下:
//func: 創(chuàng)建濾波傳遞函數(shù) //size: 擴展后圖像的大小 //gamma_L: 控制低頻下限 //gamma_H: 控制高頻上限 //c,D0: 控制濾波函數(shù)剖面的偏斜度 cv::Mat calc_Homomorphic(cv::Size size, double gamma_L, double gamma_H, double c, double D0) {cv::Mat result(size, CV_64FC1);int cx = size.width / 2;int cy = size.height / 2;for (int i = 0; i < result.rows; ++i){double* p = result.ptr<double>(i);for (int j = 0; j < result.cols; ++j){double d_2 = std::pow(i - cy, 2) + std::pow(j - cx, 2);//同態(tài)濾波傳遞函數(shù)p[j] = (gamma_H - gamma_L) * (1 - std::exp(-c * d_2 / (D0 * D0))) + gamma_L;}}//創(chuàng)建雙通道圖像,便于與復數(shù)圖像相乘cv::Mat planes[] = { result.clone(), result.clone() };cv::Mat Homomorphic;merge(planes, 2, Homomorphic);return Homomorphic; }//************************main入口*************************//int main() {std::string path = "PET_image.tif";cv::Mat src = cv::imread(path, cv::IMREAD_GRAYSCALE);if (!src.data) {std::cout << "Could not open or find the image" << std::endl;return -1;}//源圖像轉化為對數(shù)形式cv::Mat srclogMat;src.convertTo(srclogMat, CV_64FC1);srclogMat = srclogMat + cv::Scalar::all(1);cv::log(srclogMat, srclogMat);//擴展圖像,擴展部分使用零填充cv::Mat paddedMat;int m = cv::getOptimalDFTSize(src.rows);int n = cv::getOptimalDFTSize(src.cols);//on the border add zero valuescv::copyMakeBorder(srclogMat, paddedMat, 0, m - src.rows, 0, n - src.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));cv::Mat paddedMatdouble;paddedMat.convertTo(paddedMatdouble, CV_64FC1);//使傅里葉變換中心化Dftshift(paddedMatdouble, paddedMatdouble);//創(chuàng)建一個復數(shù)圖像F(u, v)cv::Mat complexF;cv::dft(paddedMatdouble, complexF, cv::DFT_COMPLEX_OUTPUT);//創(chuàng)建同態(tài)濾波傳遞函數(shù)double gamma_L = 0.25, gamma_H = 2.0;double c = 1.0, D0 = 160;cv::Mat Homomorphic = calc_Homomorphic(paddedMat.size(), gamma_L, gamma_H, c, D0);cv::Mat complexFH;cv::Mat iDft;//采用對應像素相乘G(u, v) = H(u, v) * F(u, v)cv::multiply(complexF, Homomorphic, complexFH);cv::idft(complexFH, iDft, cv::DFT_REAL_OUTPUT | cv::DFT_SCALE);//最后不要忘了再完成一次移動Dftshift(iDft, iDft);//之前進行了對數(shù)變換,現(xiàn)在要變換回來cv::exp(iDft, iDft);iDft = iDft - cv::Scalar::all(1);cv::Mat result = iDft(cv::Rect(0, 0, src.cols, src.rows)).clone();//截斷負值,歸一化并轉換為ucharMinusToZero(result, result);normalize(result, result, 0, 1, cv::NORM_MINMAX);result.convertTo(result, CV_8UC1, 255);cv::imwrite("ascend_ET.png", result);cv::waitKey(0);return 0; }測試結果:
總結
以上是生活随笔為你收集整理的OpenCV实现同态滤波的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 通过SQL Server 2008 访问
 - 下一篇: asp不同编码下 UTF-8 GB231