二维gabor特征及其实现

二维Gabor小波核定义如下:



根据上述定义式,可以编写代码实现:

// *****************************************
// Copyright (c) 2016 Jingshuang Hu
   
// @filename:GaborFeature.cpp
// @datetime:2016.06.20
// @author:hjs
// @e-mail:jingshuang_hu@163.com
// @blog:http://blog.csdn.net/hujingshuang
// @GitHub:https://github.com/hujingshuang
// *****************************************

// φ_uv(z) = (|K_uv| ^ 2 / (sigma ^ 2)) * exp(-(|K_uv|^2 * |z|^2) / (2 * sigma^2)) * (exp(i * K_uv) - exp(-sigma^2 / 2))
// K_uv = K_v * exp(i * Phi_u)		//Phi_u ---> φ_u
// K_v = K_max / (f ^ v)
// Phi_u = u * pi / 8
// K_max = pi / 2
// f = sqrt(2)
// sigma = 2 * pi
void GaborFeature(const Mat img)
{
	assert(img.channels() == 1);				//single channel

	double sigma = 2 * CV_PI;
	double f = sqrt(2.0);
	double K_max = CV_PI / 2;

	for (int v = 0; v < 5; ++v)					// scale
	{
		for (int u = 0; u < 8; ++u)				// orientation
		{
			int mask_width = cvRound(6 * sigma * pow(f, v) / K_max) + 1;	//width of gabor filter
			double Phi_u = CV_PI * u / 8;
			double K_v = K_max / pow(f, v);	

			Mat imgMaskReal = Mat::zeros(mask_width, mask_width, CV_64FC1);
			Mat imgMaskIm = Mat::zeros(mask_width, mask_width, CV_64FC1);

			Mat imgReal, imgIm, imgMac;

			for (int i = 0; i < mask_width; ++i)
			{
				for (int j = 0; j < mask_width; ++j)
				{
					int x = i - (mask_width - 1) / 2;	// offset
					int y = j - (mask_width - 1) / 2;

					double K_uv = K_v * (cos(Phi_u) * x + sin(Phi_u) * y);
					double part1 = ((K_v * K_v) / (sigma * sigma)) * exp(-(K_v * K_v) * (x * x + y * y) / (2 * sigma * sigma));
					double part2 = cos(K_uv) - exp(-sigma * sigma / 2);
					double part3 = sin(K_uv);

					double realPart = part1 * part2;	// real part
					double imPart = part1 * part3;		// imaginary part

					imgMaskReal.at<double>(i, j) = realPart;
					imgMaskIm.at<double>(i, j) = imPart;
				}
			}

#define GABOR_MODE 0			// switch one of gabor mode

#if GABOR_MODE == 1
			filter2D(img, imgReal, CV_32F, imgMaskReal, Point((mask_width - 1) / 2, (mask_width - 1) / 2));		// real filter
			Mat imgDst(imgReal);
#elif GABOR_MODE == 2
			filter2D(img, imgIm, CV_32F, imgMaskIm, Point((mask_width - 1) / 2, (mask_width - 1) / 2));			// imaginary filter
			Mat imgDst(imgIm);
#else
			// magnitude filter
			filter2D(img, imgReal, CV_32F, imgMaskReal, Point((mask_width - 1) / 2, (mask_width - 1) / 2));
			filter2D(img, imgIm, CV_32F, imgMaskIm, Point((mask_width - 1) / 2, (mask_width - 1) / 2));

			cv::pow(imgReal, 2, imgReal);
			cv::pow(imgIm, 2, imgIm);
			cv::add(imgReal, imgIm, imgMac);
			cv::pow(imgMac, 0.5, imgMac);
			Mat imgDst(imgMac);
#endif
			Mat imgGabor;
			normalize(imgDst, imgDst, 255, 0, NORM_MINMAX);	// normalize value of pixel from 0 to 255
			convertScaleAbs(imgDst, imgGabor, 1, 0 );		// 8-bit unsigned integers

			imshow("gabor response", imgGabor); waitKey(0);	// show the image

		} // end of for
	} // end of for
} // end of function
好的,代码就是酱紫啦。下面来看看一些效果吧。

二维gabor响应的实部(也就是实部的5 x 8 = 40个滤波器):

上传图片真是太辛苦了,居然没有全部选中再传,而是要一个一个的点。发火

以上就是5个尺度,8个方向上的二维gabor滤波器响应的实部,我们用这40个滤波器来与图像进行卷积,下面我们以这位92 x 112尺寸且一本正经的帅小哥为例。







ok,到此为止我们已经提取到了一幅图像的gabor特征了。不过维数为92 x 112 x 40维,网上有好多降维的方法,也可以和LBP结合起来提取特征来达到降维的目的。


参考文献:

[1] 牟海军, 基于Gabor特征的人脸识别方法[D], 2013.

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值