高斯拉普拉斯 (LoG) 斑点检测器 c++

问题描述 投票:0回答:1

我正在编写一个基于 LoG 的斑点检测器。我正在使用 openCV 库。任务是检测黑暗背景上的光圈。图片类型CV_8UC1

原图(故意噪音) https://i.stack.imgur.com/eBglu.png

这一切都始于这样一个事实:由于某种原因,最小响应是由半径比所需圆本身更大的斑点给出的。我发现错误在于匹配

cv::GaussianBlur
cv::Laplacian
内核的大小。 例如,第一张图片包含所有找到的斑点(经过排序以消除误报),第二张图片是响应最小的废弃斑点。为了找到不同大小的斑点,我使用 cv::pyrDown 尺度金字塔和 LoG sigma^2 响应归一化。

https://i.stack.imgur.com/sjxDl.jpg

https://i.stack.imgur.com/drot2.jpg

从文档中我不明白应该在函数参数中指定什么尺寸 - 机翼的尺寸还是核心的实际尺寸。例如,如果我在参数中指定 ksize = 5。高斯核的大小会等于5吗?根据公式 2*n + 1,拉普拉斯核的大小将等于 11?

我试图通过获得原子核来寻找答案。也就是说,我使用了函数 cv::getGaussianKernel 和 cv::getDerivKernels。但由于某种原因,将 cv::Laplacian 应用于生成的高斯核的结果给出了略有不同的结果。也就是说,在使用 cv::GaussianBlur 和 cv::Laplacian 的情况下,我在点 [155, 710] 处收到了最小响应,其值为 -144004136960.000000,而在使用 cv::getGaussianKernel 的情况下和 cv:: 我收到的拉普拉斯最小响应位于点 [155, 710],值为 -9097119744.000000。我使用相同的核心尺寸。我将 cv::getGaussianKernel 获得的内核乘以转置内核,因为 cv::getGaussianKernel 函数给出一维内核。

我不明白这种行为的原因。

第一幅图像是使用经典方法获得的,而第二幅图像是通过对 cv::getGaussianKernel 获得的高斯核应用 cv::Laplacian 获得的。

https://i.stack.imgur.com/KZWGi.png

https://i.stack.imgur.com/oIJ95.png

这就是使用 cv::getGaussianKernel 查找高斯核时 LoG 的样子。

https://i.stack.imgur.com/SlIFb.png

接下来我尝试获取拉普拉斯核。为此我使用了

 cv::getDerivKernels(sobelKernelX, sobelKernelY, 2, 2, kernelsizes);
 cv::Mat sobelKernel = sobelKernelX * sobelKernelX.t() + sobelKernelY * sobelKernelY.t();

但是我得到了一个非常糟糕且不正确的结果。

https://i.stack.imgur.com/plXBP.png

这就是 LoG 的样子。 https://i.stack.imgur.com/EmL4x.png

 //values used
 double sigmakz = 3.2;
 int kernelsizes = static_cast<int>(6*sigmakz);
 
 //classic version
 image.convertTo(temprrrr_reverse, CV_32F);
 cv::GaussianBlur(temprrrr_reverse, tryinguff, cv::Size(kernelsizes, kernelsizes), sigmakz);
 cv::Laplacian(tryinguff, outtt, CV_32F, kernelsizes);

 //option to obtain a Gaussian kernel
 cv::Mat gausKernel = cv::getGaussianKernel(kernelsizes, sigmakz, CV_32F);
 cv::Mat temprrrr = gausKernel * gausKernel.t();
 cv::Mat smth;
 cv::Laplacian(temprrrr, smth, CV_32F, kernelsizes);
 cv::Mat hrrr;
 cv::filter2D(image, hrrr, CV_32F, smth);

 //option to obtain the kernel of the second derivative
 cv::Mat sobelKernelX;
 cv::Mat sobelKernelY;
 cv::getDerivKernels(sobelKernelX, sobelKernelY, 2, 2, kernelsizes);

 cv::Mat sobelKernel = sobelKernelX * sobelKernelX.t() + sobelKernelY * sobelKernelY.t();

 cv::Mat tryinguff;
 //temprr = gausKernel * gausKernel.t();
 cv::filter2D(temprrrr, tryinguff, CV_32F, sobelKernel);

 cv::Mat outtt;
 cv::filter2D(image, outtt, CV_32F, tryinguff);

主要问题是如何从技术角度正确协调核心尺寸?我应该在拉普拉斯和高斯的 ksize 参数中指定什么值?

c++ opencv blob laplacian
1个回答
0
投票

Переформулируйте свой вопрос!

Вопрос надо переформулировать!

Вопросы? Вопросы?

© www.soinside.com 2019 - 2024. All rights reserved.