如何使用OpenCV检测大量白色像素的区域?

20

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

2个回答

48
我有一个方法可以实现这个。我不知道这个方法是否适用于所有情况,但在这里它表现很好。
以下是代码(使用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)

以下是检测到的轮廓图像:

在输入图像上绘制出的检测到的轮廓

接下来是掩模图像:

新的掩模图像

现在你可以使用cv2.bitwise_not函数对图像进行反转。 在这个函数中,你可以选择给定一个掩模,在其中我们将提供我们的掩模图像,以便函数仅在输入图像中存在白色掩模区域时操作。

cv2.bitwise_not(gray2,gray2,mask)

最后展示图片:

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

以下是结果:

在此输入图片描述


注意:

上述方法的目的是保留白色正方形中的“橙色”。这就是为什么会出现一些伪影的原因。如果你不想要那个橙色,可以更加精确。

只需找到面积过滤轮廓的边界矩形,并绘制填充有黑色的矩形即可。

代码:

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()

结果:

检测到的边界矩形:

enter image description here

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

enter image description here

这比之前更好,当然如果你不想要橙色就好了。


你为什么调整了图片的大小? - chostDevil
因为你的图片太大了,我的屏幕无法完整显示它。(这里不是很重要,如果你不喜欢可以忽略。另外,较小的图像意味着操作更快。)顺便问一下,你实际想使用哪种方法?使用ORANGE还是不使用ORANGE? - Abid Rahman K
如果你懂C ++,请更新你的回答,因为我不能在Python和C ++之间进行映射。 - chostDevil
4
抱歉,我不了解C++,但是所有的函数都是类似的。请访问www.opencv.itseez.com,将Python函数输入到搜索框中,您将获得相应的带有完整文档的C++函数。他们还提供教程。顺便说一下,我正在使用OpenCV 2.4beta。它也兼容2.3或2.2版本。 - Abid Rahman K

1
您可以使用形态滤波器(如交替顺序滤波)简化多颜色图像,然后使用分割算法(如分水岭算法或一些粒度测量方法)并选择最大的物体。您可以在网上找到几个实现。但是这仅适用于标志是离散的情况(例如不在背景上)。

@PatrickJones 我的意思是,如果这是一个图像文件,而不是那些商务卡片,其中徽标位于文本下方并占据整张卡片。或者如果该卡片分为多个颜色区域。有很多种情况。 - sivann
什么是形态学滤波器或交替顺序过滤,请讨论。 - chostDevil
@PatrickJones 形态学滤波器是连接滤波器,如膨胀、腐蚀、开运算和闭运算。ASF使用交替的开运算和闭运算操作符,每次使用不同(更大)的结构元素。图像分析是一个广泛而复杂的主题,您可以尝试从Mathwork的Matlab演示中学习一些东西:链接 - sivann
该项目没有可下载的文件! - chostDevil
@sivann如果徽标在文本内部或卡片分成不同的颜色区域,会出现什么情况? - chostDevil
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接