【问题标题】:openCV filter image - replace kernel with local maximumopenCV过滤器图像 - 用局部最大值替换内核
【发布时间】:2012-05-24 04:18:19
【问题描述】:

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

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

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

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

确切的问题:

我需要用内核遍历矩阵,计算每个内核的最大值,留下最大值,但内核中的其他值为零。

是否有内置的 openCV 函数可以做到这一点?

【问题讨论】:

  • 你不是在寻找局部最大值吗?喜欢这里:stackoverflow.com/questions/5550290/…
  • 我不仅需要每个内核中的局部最大值,但我需要这样一个过滤器,当每一步只保留局部最大值时,其他值为零
  • 不确定我理解你的意思,但无论如何,使用 MinMaxLoc 将其限制为内核(或 ROI,并在图像中移动此 ROI)应该有效吗?就像他们的评论一样。
  • 嗯..但是是的,你是对的。我可以用内核循环图像,并计算 MinMaxLoc。它不仅返回值,还返回最大值的位置。比我让内核中的所有元素都为零,除了最大值......我第一次有这个想法,但我认为可能是 openCV 有更容易做到这一点的内置能力。

标签: c++ opencv image-processing filter max


【解决方案1】:

如果您正在寻找一些内置功能,FilterEngine 将帮助您制作自定义过滤器(内核)。

http://docs.opencv.org/modules/imgproc/doc/filtering.html#filterengine

另外,我建议在所有处理之前进行某种降噪,通常是模糊处理。除非你真的想要原始图像。

【讨论】:

    【解决方案2】:

    我会这样做:

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

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

    9 x 9 像素原始图像:

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

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

    这是一些 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 在他/她的回答中建议的。

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

    使用 5 x 5 内核处理后:

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

    【讨论】:

    • 谢谢。是的,我明白了,这是扩展@sansuiso 的想法。
    • @Innuendo - 是的,这很有趣,直到我发帖才看到他们的答案,它让我微笑;)
    • @fraxel,我在回答相关问题后才注意到您的回答 :) 在我的回答中,我建议如何处理具有相等值(高原)的像素。 stackoverflow.com/a/21023493
    【解决方案3】:

    我建议使用 opencv 内置函数的原始两步程序(可能存在更有效的方法):

    1. 第 1 步:使用方形核(对应于您的邻域)进行形态膨胀。在将每个像素值替换为内核内部的最大值之后,此步骤会为您提供另一张图像。

    2. 步骤2:测试原始响应图像的每个像素的角点值是否等于膨胀步骤给出的最大值。如果没有,那么显然附近有更好的角落。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-28
      • 2011-07-29
      • 2019-03-28
      • 2018-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多