【问题标题】:How to detect region of large # of white pixels using OpenCV?如何使用 OpenCV 检测大量白色像素的区域?
【发布时间】:2012-05-03 00:07:48
【问题描述】:

我想检测图像中的徽标以将其删除。我有一个想法是寻找具有大量像素然后删除的对象。另一个想法是遍历所有白色像素(我已经反转了我的图像)并寻找形成大区域的像素,然后删除该区域。有没有比这个更好的算法。此外,OpenCV 中的哪些方法可以帮助我检测大像素数的对象。

【问题讨论】:

    标签: c++ image-processing opencv object-detection


    【解决方案1】:

    您可以使用形态过滤器(可能是交替顺序过滤器)来简化您的多色图像,然后使用分水岭或某些粒度方法等分割算法并选择最大的对象。您可能会在网上找到几个实现。但这仅在徽标是离散的(例如不在背景上)时才有效

    【讨论】:

    • 什么意思(不在后台)
    • @PatrickJones 我的意思是如果它是某处的图像,而不是徽标位于文本下方并占据整张卡片的名片之一。或者,如果卡片被分成几个颜色区域。有很多情况。
    • 什么是形态过滤或交替顺序过滤请讨论
    • @PatrickJones 形态过滤器是连接过滤器,如膨胀、腐蚀、打开、关闭。 ASF 使用具有不同(每次较大)结构元素的交替打开和关闭运算符。图像分析是一个大而难的话题,你可以尝试从 Mathwork 的 matlab 演示中学习一些东西:link
    • 我看到你发布了图片。应该在减少颜色深度之前进行过滤以避免产生噪音(如顶部白色方块内的黑色“头发”)。之后,您可以使用类似sourceforge.net/projects/opencvbwlabel
    【解决方案2】:

    我有办法做到这一点。我不知道这种方法是否适用于所有人,但在这里效果很好。

    下面是代码(Python):

    首先将图像转换为灰度,调整图像大小,应用阈值,并制作与调整大小的灰度图像相同大小和类型的蒙版图像。 (蒙版图像只是黑色图像)

    import cv2
    import numpy as np
    
    img = cv2.imread('bus.png')
    img = cv2.resize(img,(400,500))
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret,gray = cv2.threshold(gray,127,255,0)
    gray2 = gray.copy()
    mask = np.zeros(gray.shape,np.uint8)
    

    现在在阈值图像中找到轮廓。过滤 500 到 5000 之间区域的轮廓。它很可能是一个大的白色斑点,显然不是字母。 (记住,这个区域是这个图像的特殊区域。我不知道你的其他图像。你必须自己找到它)。现在在填充了白色的蒙版图像上绘制此轮廓。

    contours, hier = cv2.findContours(gray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    for cnt in contours:
        if 200<cv2.contourArea(cnt)<5000:
            cv2.drawContours(img,[cnt],0,(0,255,0),2)
            cv2.drawContours(mask,[cnt],0,255,-1)
    

    Below is the detected contour image:

    Next is the mask image:

    现在您使用cv2.bitwise_not 函数反转图像。您可以选择在我们提供遮罩图像的地方提供遮罩,以便该功能仅在输入图像中遮罩图像中有白色的区域上运行。

    cv2.bitwise_not(gray2,gray2,mask)
    

    最后显示图片:

    cv2.imshow('IMG',gray2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    结果如下:


    注意:

    上述方法用于将“ORANGE”保留在白色方块中。这就是为什么存在一些文物的原因。如果你也不想要那个橙色,它会更准确。

    只需找到区域过滤轮廓的边界矩形并绘制填充黑色的矩形。

    代码:

    import cv2
    import numpy as np
    
    img = cv2.imread('bus.png')
    img = cv2.resize(img,(400,500))
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret,gray = cv2.threshold(gray,127,255,0)
    gray2 = gray.copy()
    
    contours, hier = cv2.findContours(gray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    for cnt in contours:
        if 200<cv2.contourArea(cnt)<5000:
            (x,y,w,h) = cv2.boundingRect(cnt)
            cv2.rectangle(gray2,(x,y),(x+w,y+h),0,-1)
    
    cv2.imshow('IMG',gray2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    结果:

    检测到的边界矩形:

    然后用黑色填充这些矩形:

    比以前的要好,当然如果你不想要“ORANGE”)

    【讨论】:

    • 为什么要调整图片大小?
    • 是因为你的图片太大了,我的屏幕无法将它作为一个整体包含进来。 (这里不那么重要。如果你不喜欢它,请避免它。Also smaller images means more faster the operations。)顺便说一句,你真正想要哪种方法?有ORANGE还是没有ORANGE?
    • 如果您知道 c++,请更新您的答案,因为我无法在 python 和 c++ 之间进行映射
    • 对不起,我不懂 C++。但所有功能都是相似的。访问 www.opencv.itseez.com,在搜索框中输入 python 函数。您将获得带有完整文档的相应 C++ 函数。他们也有教程。顺便说一句,我使用的是opencv 2.4beta。它也与 2.3 或 2.2 兼容。
    猜你喜欢
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 2016-10-01
    相关资源
    最近更新 更多