1. 程式人生 > >OpenCV實現Gabor濾波

OpenCV實現Gabor濾波


不同中心震盪頻率下在Gabor函式


程式碼:根據http://blog.csdn.net/watkinsong/article/details/7876361實現

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cmath>
#include <iostream>

using namespace cv;
using namespace std;

const double PI = 3.14159265;

// ref: http://blog.csdn.net/watkinsong/article/details/7876361
Mat getMyGabor(int width, int height, int U, int V, double Kmax, double f,
	double sigma, int ktype, const string& kernel_name)
{
	//CV_ASSERT(width % 2 == 0 && height % 2 == 0);
	//CV_ASSERT(ktype == CV_32F || ktype == CV_64F);

	int half_width = width / 2;
	int half_height = height / 2;
	double Qu = PI*U/8;
	double sqsigma = sigma*sigma;
	double Kv = Kmax/pow(f,V);
	double postmean = exp(-sqsigma/2);

	Mat kernel_re(width, height, ktype);
	Mat kernel_im(width, height, ktype);
	Mat kernel_mag(width, height, ktype);

	double tmp1, tmp2, tmp3;
	for(int j = -half_height; j <= half_height; j++){
		for(int i = -half_width; i <= half_width; i++){
			tmp1 = exp(-(Kv*Kv*(j*j+i*i))/(2*sqsigma));
			tmp2 = cos(Kv*cos(Qu)*i + Kv*sin(Qu)*j) - postmean;
			tmp3 = sin(Kv*cos(Qu)*i + Kv*sin(Qu)*j);

			if(ktype == CV_32F)
				kernel_re.at<float>(j+half_height, i+half_width) = 
					(float)(Kv*Kv*tmp1*tmp2/sqsigma);
			else
				kernel_re.at<double>(j+half_height, i+half_width) = 
					(double)(Kv*Kv*tmp1*tmp2/sqsigma);

			if(ktype == CV_32F)
				kernel_im.at<float>(j+half_height, i+half_width) = 
					(float)(Kv*Kv*tmp1*tmp3/sqsigma);
			else
				kernel_im.at<double>(j+half_height, i+half_width) = 
					(double)(Kv*Kv*tmp1*tmp3/sqsigma);
		}
	}

	magnitude(kernel_re, kernel_im, kernel_mag);

	if(kernel_name.compare("real") == 0)
		return kernel_re;
	else if(kernel_name.compare("imag") == 0)
		return kernel_im;
	else if(kernel_name.compare("mag") == 0)
		return kernel_mag;
	else
		printf("Invalid kernel name!\n");
}

void construct_gabor_bank()
{
	double Kmax = PI/2;
	double f = sqrt(2.0);
	double sigma = 2*PI;
	int U = 7;
	int V = 4;
	int GaborH = 129;
	int GaborW = 129;

	Mat kernel;
	Mat totalMat;
	for(U = 0; U < 8; U++){
		Mat colMat;
		for(V = 0; V < 5; V++){
			kernel = getMyGabor(GaborW, GaborH, U, V,
				Kmax, f, sigma, CV_64F, "real");

			//show gabor kernel
			normalize(kernel, kernel, 0, 1, CV_MINMAX);
			printf("U%dV%d\n", U, V);
			//imshow("gabor", kernel);
			//waitKey(0);

			if(V == 0)
				colMat = kernel;
			else
				vconcat(colMat, kernel, colMat);
		}
		if(U == 0)
			totalMat = colMat;
		else
			hconcat(totalMat, colMat, totalMat);
	}

	imshow("gabor bank", totalMat);
	//imwrite("gabor_bank.jpg",totalMat);
	waitKey(0);
}

Mat gabor_filter(Mat& img)
{
	// variables for gabor filter
	double Kmax = PI/2;
	double f = sqrt(2.0);
	double sigma = 2*PI;
	int U = 7;
	int V = 4;
	int GaborH = 129;
	int GaborW = 129;

	// 
	Mat kernel_re, kernel_im;
	Mat dst_re, dst_im, dst_mag;

	// variables for filter2D
	Point archor(-1,-1);
	int ddepth = -1;
	double delta = 0;

	// filter image with gabor bank
	Mat totalMat;
	for(U = 0; U < 8; U++){
		Mat colMat;
		for(V = 0; V < 5; V++){
			kernel_re = getMyGabor(GaborW, GaborH, U, V,
				Kmax, f, sigma, CV_64F, "real");
			kernel_im = getMyGabor(GaborW, GaborH, U, V,
				Kmax, f, sigma, CV_64F, "imag");

			filter2D(img, dst_re, ddepth, kernel_re);
			filter2D(img, dst_im, ddepth, kernel_im);

			dst_mag.create(img.rows, img.cols, CV_32FC1);
			magnitude(Mat_<float>(dst_re),Mat_<float>(dst_im), 
				dst_mag);

			//show gabor kernel
			normalize(dst_mag, dst_mag, 0, 1, CV_MINMAX);
			printf("U%dV%d\n", U, V);
			//imshow("dst_mag", dst_mag);
			//waitKey(0);

			if(V == 0)
				colMat = dst_mag;
			else
				vconcat(colMat, dst_mag, colMat);
		}
		if(U == 0)
			totalMat = colMat;
		else
			hconcat(totalMat, colMat, totalMat);
	}

	return totalMat;
}

int main( int argc, char** argv )
{
    //construct_gabor_bank();

	Mat image;
    image = imread(argv[1], 0); // Read the file

    if(! image.data ) // Check for invalid input
    {
        cout << "Could not open or find the image" << std::endl ;
        return -1;
    }

	Mat filterd_image = gabor_filter(image);
	imshow("filtered image", filterd_image);
	//imwrite("filterd_image.jpg",filterd_image);
	waitKey(0);

    return 0;
}

其中,construct_gabor_bank函式構建了5個尺度8個方向上的Gabor小波,如下圖所示:


gabor_filter函式利用構建好的Gabor小波對影象進行濾波,原圖和濾波後在影象如下圖所示:



文件及程式碼地址:http://download.csdn.net/detail/lichengyu/7008011

注:這一版本的程式碼有問題,filter2D函式的ddepth引數值應改為CV_64而非採用預設值,見

相關推薦

OpenCV實現Gabor濾波

圖1 不同中心震盪頻率下在Gabor函式 程式碼:根據http://blog.csdn.net/watkinsong/article/details/7876361實現 #include <opencv2/core/core.hpp> #include &

opencv實現導向濾波(GuidedFilter)

何凱明去霧演算法中的導向濾波實現,原文地址導向濾波。 導向影象I,濾波輸入影象p以及輸出影象q。畫素點 i 處的濾波結果是被表達成一個加權平均: 假設導向濾波器在導向影象I和濾波輸出q之間是一個區域性線性模型: 最小化下面的視窗Wk的代價函式: 用來確定a,b的值 其中

Gabor濾波簡介和實現(Matlab,OpenCV)

   簡介             Gabor變換屬於加窗傅立葉變換,Gabor函式可以在頻域不同尺度、不同方向上提取相關的特徵。Gabor 濾波

Gabor濾波簡介與Opencv中的實現及引數變化實驗

Gabor濾波是一種非常常見的特徵提取演算法,在人臉識別等領域有著很廣泛的應用,在這裡我主要介紹一下Gabor濾波器的公式及Opencv下的程式碼實現,以及我做的一些引數變化的實驗。 一、Gabor濾波簡介 注意,這裡我介紹的Gabor演算法與在人臉識別

Log-Gabor濾波器構造,opencv實現

參照連結:https://github.com/carandraug/PeterKovesiImage/blob/master/PhaseCongruency/gaborconvolve.m點選開啟連結 畢設要用Log-Gabor濾波器來實現視網膜血管增強,這東西真是折騰了

opencv實現影象鄰域均值濾波、中值濾波、高斯濾波

void CCVMFCView::OnBlurSmooth()//鄰域均值濾波 { IplImage* in; in = workImg; IplImage* out = cvCreateImage(cvGetSize(in),IPL_DEPTH_8U,workImg-&g

引導濾波OpenCV實現

上一篇文章已經說了引導濾波的基本理論,而且我們也知道引導濾波可以寫出時間複雜度與視窗大小無關的演算法,現在就來使用C++並藉助OpenCV實現這一演算法。 實現這種演算法的關鍵思想是盒式濾波(box filter),而且必須是通過積分圖來實現的盒式濾波,否則不可能與視窗大小

眼底影象血管增強與分割--(2)Gabor濾波演算法原理及實現

Gabor濾波演算法 維基裡給出的解釋,“In image processing, aGabor filter is a linear filter used fortextureanalysis,

雙邊濾波原理及Opencv實現

演算法原理 雙邊濾波是一種非線性濾波方法,是結合了影象的鄰近度和畫素值相似度的一種折中,在濾除噪聲的同時可以保留原圖的邊緣資訊。整個雙邊濾波是由兩個函式構成:一個函式是由空間距離決定的濾波器係數,另外一個詩由畫素差值決定的濾波器係數。整個雙邊濾波的公式如下:

gabor濾波器 opencv 實現

{144145        IplImage *pDestImage = cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);146        // IplImage * pGaborImage = get_Imge();

CUDA實現影象的高斯濾波opencv實現

高斯濾波簡介:       高斯濾波是通過對輸入陣列的每個點與輸入的高斯濾波模板執行卷積計算然後將這些結果一塊組成了濾波後的輸出陣列,通俗的講就是高斯濾波是對整幅影象進行加權平均的過程,每一個畫素點的值都由其本身和鄰域內的其他畫素值經過加權平均後得到。        高斯

引導圖濾波(Guided Image Filtering)原理以及OpenCV實現

引導圖濾波器是一種自適應權重濾波器,能夠在平滑影象的同時起到保持邊界的作用,具體公式推導請查閱原文獻《Guided Image Filtering》以及matlab原始碼:http://kaiminghe.com/eccv10/index.html。這裡只說一下自適應權重原理、C++實現灰度影象以及彩色影象的

openCV之中值濾波&均值濾波(及程式碼實現

 在開始我們今天的部落格之前,我們需要先了解一下什麼是濾波: 首先我們看一下影象濾波的概念。影象濾波,即在儘量保留影象細節特徵的條件下對目標影象的噪聲進行抑制,是影象預處理中不可缺少的操作,其處理效果的好壞將直接影響到後續影象處理和分析的有效性和可靠性。 下圖左邊是原圖右邊

python+opencv實現高斯平滑濾波

功能: 建立兩個滑動條來分別控制高斯核的size和σ的大小,這個程式是在閾值分割的那個程式上改動的。閾值分割程式在這 注意:由於σ=0時,opencv會根據視窗大小計算出σ,所以,從0滑動σ的滑動條

opencv實現影象的灰度轉換,均值濾波實現影象的顯示和儲存

#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <opencv2/core/core.hpp> #include <iostrea

導向濾波小結:從導向濾波(guided filter)到快速導向濾波(fast guide filter)的原理,應用及opencv實現程式碼

1. 導向濾波簡介導向濾波是何凱明在學生時代提出的一個保邊濾波(edge-preserving smoothing)演算法。何凱明在cv圈應該算是名人了,學生時代關於影象去霧的研究就以第一作者的身份獲得Best Paper Award(CVPR 2009),而且今年剛剛又斬獲

OpenCV實現圖象翻轉、濾波、銳化

flip 叠代器 names 直方圖 read space eat tiger input OpenCV實現圖象翻轉、濾波、銳化 註:以下代碼,使用opencv庫函數實現了對圖片的翻轉、灰度圖轉換、各種濾波、各種銳化。 庫函數相關參數及說明參閱:OpenCV中文站=》o

使用OpenCL+OpenCV實現圖像旋轉(一)

posit 段落 大致 pro 什麽 string cpp base wechat [題外話]近期申請了一個微信公眾號:平凡程式人生。有興趣的朋友可以關註,那裏將會涉及更多更新OpenCL+OpenCV以及圖像處理方面的文章。 最近在學習《OPENCL異構計算》,其中有

opencl+opencv實現sobel算法

編譯 globals ifstream sel perf edi query oba from 這幾天在看opencl編程指南。照著書中的樣例實現了sobel算法: 1.結合opencv讀取圖像,保存到緩沖區中。 2.編寫和編譯內核。並保存顯示處理後的結果。 內核: c

opencv實現一種改進的Fast特征檢測算法

sheng 特征檢測 local 溫習 現在 ble map 閾值 lag 引言   之前了解了Fast算法之後使用opencv自己實現了下,具體見http://www.cnblogs.com/Wiley-hiking/p/6898049.html。不過算法也有缺點,主要就