openCV滤镜图像 - 用本地最大值替换内核 [英] openCV filter image - replace kernel with local maximum

查看:189
本文介绍了openCV滤镜图像 - 用本地最大值替换内核的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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



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

我有一个问题,在一个点附近有几个角落检测到(但只有一)。



确切的问题:



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

是否有构建-in openCV function to do this?

解决方案

这是我该怎么做的:


  1. 创建一个内核,它定义一个像素邻域。
  2. 通过使用这个内核扩展图像来创建一个新的图像。这个扩大的图像包含每个点的最大邻域值。
  3. 在这两个数组之间做一个相等的比较。无论哪里相等都是有效的邻域最大值,并在比较数组中设置为 255
  4. 乘以比较数组,
  5. 这是您的最终数组,只包含邻域最大值。


    这是通过放大图像来说明的:

    9像素×9像素原始图像



    5×5像素内核,只剩下局部邻域最大值(即最大值与具有较大值的像素相距超过2个像素):


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



    这是一些Python代码,它应该很容易转换到c ++:

    pre code $ import $

    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)
    #创建一个锚定在2,2
    处的5 * 5内核kernel = cv.CreateStructuringElementEx(5,5,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乘5内核处理之后:$ b $ stack.imgur.com/yCrFd.jpgalt =在这里输入图像描述 b



    固体区域是由于共享的局部最大值。


    Some details about my problem:

    I'm trying to realize corner detector in openCV (another algorithm, that are built-in: Canny, Harris, etc).

    I've got a matrix filled with the response values. The biggest response value is - the biggest probability of corner detected is.

    I have a problem, that in neighborhood of a point there are few corners detected (but there is only one). I need to reduce number of false-detected corners.

    Exact problem:

    I need to walk through the matrix with a kernel, calculate maximum value of every kernel, leave max value, but others values in kernel make equal zero.

    Are there build-in openCV functions to do this?

    解决方案

    This is how I would do it:

    1. Create a kernel, it defines a pixels neighbourhood.
    2. Create a new image by dilating your image using this kernel. This dilated image contains the maximum neighbourhood value for every point.
    3. Do an equality comparison between these two arrays. Wherever they are equal is a valid neighbourhood maximum, and is set to 255 in the comparison array.
    4. Multiply the comparison array, and the original array together (scaling appropriately).
    5. This is your final array, containing only neighbourhood maxima.

    This is illustrated by these zoomed in images:

    9 pixel by 9 pixel original image:

    After processing with a 5 by 5 pixel kernel, only the local neighbourhood maxima remain (ie. maxima seperated by more than 2 pixels from a pixel with a greater value):

    There is one caveat. If two nearby maxima have the same value then they will both be present in the final image.

    Here is some Python code that does it, it should be very easy to convert to 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)
    

    I didn't realise until now, but this is what @sansuiso suggested in his/her answer.

    This is possibly better illustrated with this image, before:

    after processing with a 5 by 5 kernel:

    solid regions are due to the shared local maxima values.

    这篇关于openCV滤镜图像 - 用本地最大值替换内核的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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