在openCV中创建2D LoG内核,如Matlab中的fspecial [英] create 2D LoG kernel in openCV like fspecial in Matlab
问题描述
我的问题不是如何使用高斯的拉普拉斯函数过滤图像(基本上是使用带有相关内核的filter2D等).
My question is not how to filter an image using the laplacian of gaussian (basically using filter2D with the relevant kernel etc.).
我想知道的是我如何生成 NxN内核.
What I want to know is how I generate the NxN kernel.
我将举一个示例,说明如何在openCV中生成[Winsize x WinSize]高斯内核.
I'll give an example showing how I generated a [Winsize x WinSize] Gaussian kernel in openCV.
在Matlab中:
gaussianKernel = fspecial('gaussian', WinSize, sigma);
在openCV中:
cv::Mat gaussianKernel = cv::getGaussianKernel(WinSize, sigma, CV_64F);
cv::mulTransposed(gaussianKernel,gaussianKernel,false);
其中预定义了sigma和WinSize.
Where sigma and WinSize are predefined.
我想对高斯的拉普拉斯算子做同样的事情.
I want to do the same for a Laplacian of Gaussian.
在Matlab中:
LoGKernel = fspecial('log', WinSize, sigma);
如何在openCV中获得确切的内核(精确到可忽略的数值差异)?
How do I get the exact kernel in openCV (exact up to negligible numerical differences)?
我正在一个需要实际内核值的特定应用程序上工作,而我只是想找到一种通过近似高斯差来实现LoG过滤的另一种方法.
I'm working on a specific application where I need the actual kernel values and simply finding another way of implementing LoG filtering by approximating Difference of gaussians is not what I'm after.
谢谢!
推荐答案
我要感谢old-ufo朝着正确的方向推进我. 我希望我不必通过快速进行matlab-> openCV转换来重新发明轮子,但是我猜这是我为快速解决方案所拥有的最佳解决方案.
I want to thank old-ufo for nudging me in the correct direction. I was hoping I won't have to reinvent the wheel by doing a quick matlab-->openCV conversion but guess this is the best solution I have for a quick solution.
注意-我仅对方形内核执行此操作(否则易于修改,但是我不需要这样做...). 也许可以用更优雅的形式写出来,但这是我做的一项快速工作,所以我可以继续处理更紧迫的事情.
NOTE - I did this for square kernels only (easy to modify otherwise, but I have no need for that so...). Maybe this can be written in a more elegant form but is a quick job I did so I can carry on with more pressing matters.
通过主要功能:
int WinSize(7); int sigma(1); // can be changed to other odd-sized WinSize and different sigma values
cv::Mat h = fspecialLoG(WinSize,sigma);
实际功能是:
// return NxN (square kernel) of Laplacian of Gaussian as is returned by Matlab's: fspecial(Winsize,sigma)
cv::Mat fspecialLoG(int WinSize, double sigma){
// I wrote this only for square kernels as I have no need for kernels that aren't square
cv::Mat xx (WinSize,WinSize,CV_64F);
for (int i=0;i<WinSize;i++){
for (int j=0;j<WinSize;j++){
xx.at<double>(j,i) = (i-(WinSize-1)/2)*(i-(WinSize-1)/2);
}
}
cv::Mat yy;
cv::transpose(xx,yy);
cv::Mat arg = -(xx+yy)/(2*pow(sigma,2));
cv::Mat h (WinSize,WinSize,CV_64F);
for (int i=0;i<WinSize;i++){
for (int j=0;j<WinSize;j++){
h.at<double>(j,i) = pow(exp(1),(arg.at<double>(j,i)));
}
}
double minimalVal, maximalVal;
minMaxLoc(h, &minimalVal, &maximalVal);
cv::Mat tempMask = (h>DBL_EPSILON*maximalVal)/255;
tempMask.convertTo(tempMask,h.type());
cv::multiply(tempMask,h,h);
if (cv::sum(h)[0]!=0){h=h/cv::sum(h)[0];}
cv::Mat h1 = (xx+yy-2*(pow(sigma,2))/(pow(sigma,4));
cv::multiply(h,h1,h1);
h = h1 - cv::sum(h1)[0]/(WinSize*WinSize);
return h;
}
这篇关于在openCV中创建2D LoG内核,如Matlab中的fspecial的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!