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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10262600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:48:59  来源:igfitidea点击:

How to detect region of large # of white pixels using OpenCV?

c++image-processingopencvobject-detection

提问by chostDevil

I want to detect a logo inside an image in order to remove it. I have an idea which is to look for objects which have the big number of pixels then remove. Another idea is to loop through all the white pixels (I have inverted my image) and look for pixels which forms a large region and then remove this region. Is there any algorithm better that this one. Also which methods in OpenCV will help me to detect object of large pixels number.

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

回答by Abid Rahman K

I have a method to do this. I don't know whether this method applicable to all, but it works good here.

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

Below is code ( in Python ):

下面是代码(在 Python 中):

First convert image to grayscale, resize image, apply threshold, and make a mask image of same size and type of that of resized grayscale image. (Mask image is just a black image)

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

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)

Now find contours in the threshold image. Filter the contour for area between 500 to 5000. It will be most probably a large white blob, obviously not letters. (Remember, this area is particular for this image. I dont know about your other images. You will have to find it yourself). Now draw this contour on the mask image filled with white color.

现在在阈值图像中找到轮廓。过滤 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:

Below is the detected contour image:

detected contour drawn on the input image

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

Next is the mask image:

Next is the mask image:

New mask image

新蒙版图片

Now you invert image using cv2.bitwise_notfunction. There you have option for giving mask where we give our mask image so that function operates only on the area in input image where there is white in mask image.

现在您使用cv2.bitwise_not函数反转图像。在那里您可以选择在我们提供蒙版图像的地方提供蒙版,以便该功能仅对输入图像中蒙版图像中存在白色的区域进行操作。

cv2.bitwise_not(gray2,gray2,mask)

And finally show the image :

最后显示图像:

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

And here is the result:

结果如下:

enter image description here

在此处输入图片说明



NOTE:

笔记:

Above method is done to preserve "ORANGE" in white square. That is why some artifacts are there. If you don't want that orange also, it can be more accurate.

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

Just find the bounding rectangle for area-filtered contours and draw rectangle filled with black color.

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

Code :

代码 :

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

Result :

结果 :

detected bounding rects:

检测到的边界矩形:

enter image description here

在此处输入图片说明

Then fillout those rectangles with black:

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

enter image description here

在此处输入图片说明

It is better than previous , of course if you don't want "ORANGE")

它比以前更好,当然如果你不想要“橙色”)

回答by sivann

You may use morphological filters (perhaps alternating sequential filtering) to simplify your multi-color image and then use a segmentation algorithm like watershed or some granulometry method and choose the largest object. You may find several implementations online. But this will work only if the logo is discrete (e.g. not on the background)

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