在openCV中创建2D LoG内核,如Matlab中的fspecial [英] create 2D LoG kernel in openCV like fspecial in Matlab

查看:235
本文介绍了在openCV中创建2D LoG内核,如Matlab中的fspecial的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题不是如何使用高斯的拉普拉斯函数过滤图像(基本上是使用带有相关内核的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆