c++ - openCV 滤波图像 - 用局部最大值替换内核

标签 c++ opencv image-processing filter max

关于我的问题的一些细节:

我正在尝试在 openCV(另一种内置算法:Canny、Harris 等)中实现角检测器。

我有一个充满响应值的矩阵。最大响应值是-检测到角点的最大概率是。

我有一个问题,在一个点附近检测到的角很少(但只有一个)。我需要减少误检测角点的数量。

确切问题:

我需要遍历带有内核的矩阵,计算每个内核的最大值,保留最大值,但内核中的其他值等于零。

是否有内置的 openCV 函数来执行此操作?

最佳答案

我会这样做:

  1. 创建一个内核,它定义了一个像素邻域。
  2. 使用这个核扩大你的图像来创建一个新图像。这个膨胀后的图像包含每个点的最大邻域值。
  3. 对这两个数组进行相等比较。它们相等的地方是有效的邻域最大值,并在比较数组中设置为 255
  4. 将比较数组与原始数组相乘(适当缩放)。
  5. 这是您的最终数组,仅包含邻域最大值。

这些放大的图像说明了这一点:

9 x 9 像素原始图像:

enter image description here

在使用 5 x 5 像素内核处理后,仅保留局部邻域最大值(即最大值与具有更大值的像素相隔超过 2 个像素):

enter image description here

有一个警告。如果两个附近的最大值具有相同的值,那么它们将同时出现在最终图像中。

下面是一些 Python 代码,它应该很容易转换为 C++:

import cv

im = cv.LoadImage('fish2.png',cv.CV_LOAD_IMAGE_GRAYSCALE)
maxed = cv.CreateImage((im.width, im.height), cv.IPL_DEPTH_8U, 1)
comp = cv.CreateImage((im.width, im.height), cv.IPL_DEPTH_8U, 1)
#Create a 5*5 kernel anchored at 2,2
kernel = cv.CreateStructuringElementEx(5, 5, 2, 2, cv.CV_SHAPE_RECT)

cv.Dilate(im, maxed, element=kernel, iterations=1)
cv.Cmp(im, maxed, comp, cv.CV_CMP_EQ)
cv.Mul(im, comp, im, 1/255.0)

cv.ShowImage("local max only", im)
cv.WaitKey(0)

直到现在我才意识到,但这是@sansuiso 在他/她的回答中建议的。

这张图片可能更好地说明了这一点,之前:

enter image description here

使用 5 x 5 内核处理后:

enter image description here

实心区域是由于共享局部最大值。

关于c++ - openCV 滤波图像 - 用局部最大值替换内核,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10621312/

相关文章:

python - 在 python opencv 中添加像素?

c++ - 如何将 JPG 图像读取为 CV_16UC1 并在屏幕上打印?

Java缓冲图像: Calculate Memory Size in Advance

java - 如何区分图像中的两条线

c++ - 尝试在VS中编写C代码,由于C++错误而无法生成

c++ - 在驱动器 c : 中按类 fstream 类打开文件

c++ - gcc 编译 C++ 代码 : undefined reference to `operator new[](unsigned long long)'

c++ - 重新定义(#define) 保留的 c++ 关键字

python - 在OpenCV中自动拍照

image-processing - 如何从 System.Drawing.Image 创建 Emgu 图像?