opencv python 稳定的图标识别

问题描述 投票:0回答:2

我有以下问题:我需要可靠地检测图像中的图标。该图像还包含文本,并且图标有各种尺寸。

目前,我使用 Python 和 cv2 库来完成此任务。然而,不幸的是,当前使用

cv2.findContours
的轮廓检测算法不太可靠。这是我目前正在做的事情:

gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
binary = cv2.adaptiveThreshold(self.gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 17, 1)
contours, _ = cv2.findContours(self.binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

然后进行轮廓过滤,合并过滤后的轮廓,再次过滤。

然而,事实证明这种方法并不可靠。

我也尝试过使用

getStructuringElement
,但它为白色背景上的图标提供了不可靠的结果。

我无法透露真实的输入数据,但我使用了亚马逊徽标并创建了一个示例来演示该问题。

enter image description here

对于彩色图标,当使用轮廓时,我经常会得到两个或三个尺寸不正确的图标,并且合并它们会失去精确的尺寸。对于白色背景上的图标,使用

getStructuringElement
的方法不能很好地检测边界。

我的问题: 你有什么建议? 我的想法:

  1. 训练 Haar 级联。会有很大帮助吗?
  2. 微调当前方法之一的参数。
  3. 任何其他方法/库。

我愿意接受任何建议,或者让我知道是否有人有解决此类问题的经验。

图片:https://i.sstatic.net/bZYrnCTU.jpg

python opencv image-processing image-recognition haar-classifier
2个回答
0
投票

为了提高可靠性,请使用轮廓数据来检查轮廓面积。图标的面积似乎比文本更大,因此您可以为该区域设置阈值以将其过滤掉。


0
投票

我认为边缘检测在这里可以很好地工作,我做了一个现在有效的小例子:

im = cv2.imread("logos.jpg")
imGray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(imGray,5, 20)

这给出了以下结果:

edges

在此之后,检测轮廓并按区域过滤将非常有效,因为徽标的方块似乎都是相同大小的:

contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
sortedContours = sorted(contours, key = cv2.contourArea, reverse = True)
for c in sortedContours:
    print(cv2.contourArea(c))

我们看到,面积最大的三个轮廓确实都有 10500 像素左右:

10787.0
10715.0
10128.0
7391.5
4555.5
3539.0
3420.0
.
.
.

填充前三个轮廓:

im1 = cv2.drawContours(im.copy(), sortedContours, 2, (255,0,0), -1)
im2 = cv2.drawContours(im.copy(), sortedContours, 1, (0,255,0), -1)
im3 = cv2.drawContours(im.copy(), sortedContours, 0, (0,0,255), -1)

这就是您将得到的:

filled logos

我假设你想要的是一个布尔掩码来获取这些像素。所以类似

mask = np.zeros_like(imGray)
mask = cv2.drawContours(mask, sortedContours, 2, 1, -1)
firstLogo = cv2.bitwise_and(im, im, mask = mask)

可以胜任这项工作。您可以通过过滤轮廓轻松地实现自动化,我只是向您推送一个 POC。

© www.soinside.com 2019 - 2024. All rights reserved.