matlab中imfilter()、fspecial()以及meshgrid()的C++实现(LoG算子)

近期为实现图像处理,需要实现LoG算子(高斯拉普拉斯算子------Laplace of Gaussian)。
关于LoG的理论算法说明请自行参见参考文章:
1、http://blog.csdn.net/songzitea/article/details/12842825
2、http://blog.csdn.net/pi9nc/article/details/18619893


期望实现的效果是matlab上 
"imfilter(img,fspecial('log', floor(6*sigma+1), sigma),'replicate') ";
这个效果。并且使用C/C++实现


最开始使用openCV3.1版本的开源库,使用其中的cv::GaussianBlur()和cv::Laplacian()这两个函数。虽然通过改变高斯函数的卷积核sigma值的大小,可以有类似matlab上面函数的效果,但是这个类似与我的需求差很多。总的来说就是不能单纯的使用这两个函数实现matlab上面'log'的效果。


之后经过长时间的研究的探索在 
http://answers.opencv.org/question/8783/implement-imfiltermatlab-with-opencv/
这个网址上发现matlab上面的imfilter()函数可以由openCV中的cv::filter2D()函数近似实现但会有一些问题。问题的根源在于上面网址中提到的

"The problem is you can pass BORDER_CONSTANT to filter2D, but it doesnt take the value the constant should be, So instead you have to create a FilterEngine object. Additionally, Matlab anchors its kernel in the top-left corner, unlike the OpenCV's default, in the center"。


并且同时在上面的网址的学习到了openCV中所有的滤波算法基本的都是调用 FilterEngine 类实现的。这个类在我使用的openCV3.1版本中不可以直接调用。具体方法就是需要包含:filterengine.hpp, opencl_kernels_imgproc.hpp, precomp.hpp, filter.cpp, opencl_kernels_imgproc.cpp. 这5个hpp和cpp文件,同时需要自己添加位于opencv\sources\modules\core\include\opencv2\core\opencl把ocl_defs.hpp拷贝至build目录,官方的为opencv\build\include\opencv2\core,自己编译则为编译项目下的\install\include\opencv2\core,记得先创建opencl文件夹。
说白了就是包含上面5个文件之后,程序说需要找不到一些头文件,在你openCV中查询那些找不到的头文件之后把那些相应的头文件放到正确的路径上就OK了!)


研究了一小会儿之后发现FilterEngine类确实神奇,神奇到想研究明白了靠一时半会的时间是不行的..所以暂时选择放弃。但是本人坚信想要玩儿转openCV的图像处理,把这个类搞懂是必须的!


之后继续探索其他方式实现matlab中的'log'的方法中看到了
https://stackoverflow.com/questions/23471083/create-2d-log-kernel-in-opencv-like-fspecial-in-matlab
这篇“create 2D LoG kernel in openCV like fspecial in Matlab”的讨论。
其中发现了实现所谓LoG卷积核的matlab源码(也可能是python的..)如下:


 case 'log' % Laplacian of Gaussian
 % first calculate Gaussian
 siz   = (p2-1)/2;
 std2   = p3^2;


 [x,y] = meshgrid(-siz(2):siz(2),-siz(1):siz(1));
 arg   = -(x.*x + y.*y)/(2*std2);


 h     = exp(arg);
 h(h


 sumh = sum(h(:));
 if sumh ~= 0,
   h  = h/sumh;
 end;
 % now calculate Laplacian     
 h1 = h.*(x.*x + y.*y - 2*std2)/(std2^2);
 h     = h1 - sum(h1(:))/prod(p2); % make the filter sum to zero


看到这个之后本人把它移植成功!
(这个代码中需要实现matlab中meshgrid()函数,之前正好把它也实现了)


最终通过把matlab中fspecial() 和 imfilter()两个函数的实现,完成了对'log'的C/C++移植!(因为毕竟是两种语言,所以其中调节的sigma值和ksize值需要调节后,找到对应的。)

心里多如牛毛的锁的其中一个就此解开了~


下面是代码实现

代码传送门




你可能感兴趣的:(C/C++,matlab,CC++,meshgird,imfilter,LoG)