使用“打开”在图像中查找形状

2024-09-28 05:25:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用OpenCV在图像中寻找形状。我知道我想匹配的形状(有些形状我不知道,但我不需要找到它们)和它们的方向。我不知道它们的大小(比例)和位置。

我目前的做法:

  1. 检测等高线
  2. 对于每个轮廓,计算最大边界框
  3. 将每个边界框分别与已知形状之一匹配。在我的实际项目中,我将区域缩放到模板大小并计算Sobel梯度的差异,但是对于这个演示,我只是使用纵横比。

这种方法的失败之处在于形状的接触。轮廓检测将两个相邻的形状提取为单个轮廓(单个边界框)。匹配步骤显然会失败。

有没有办法修改我的方法来分别处理相邻的形状?还有,有没有更好的方法来执行步骤3?

例如:(Es为绿色,Ys为蓝色)

enter image description here

失败案例:(红色未知形状)

enter image description here

源代码:

import cv
import sys
E = cv.LoadImage('e.png')
E_ratio = float(E.width)/E.height
Y = cv.LoadImage('y.png')
Y_ratio = float(Y.width)/Y.height
EPSILON = 0.1

im = cv.LoadImage(sys.argv[1], cv.CV_LOAD_IMAGE_GRAYSCALE)
storage = cv.CreateMemStorage(0)
seq = cv.FindContours(im, storage, cv.CV_RETR_EXTERNAL, 
        cv.CV_CHAIN_APPROX_SIMPLE)
regions = []
while seq:
    pts = [ pt for pt in seq ]
    x, y = zip(*pts)    
    min_x, min_y = min(x), min(y)
    width, height = max(x) - min_x + 1, max(y) - min_y + 1
    regions.append((min_x, min_y, width, height))
    seq = seq.h_next()

rgb = cv.LoadImage(sys.argv[1], cv.CV_LOAD_IMAGE_COLOR)
for x,y,width,height in regions:
    pt1 = x,y
    pt2 = x+width,y+height
    if abs(float(width)/height - E_ratio) < EPSILON:
        color = (0,255,0,0)
    elif abs(float(width)/height - Y_ratio) < EPSILON:
        color = (255,0,0,0)
    else:
        color = (0,0,255,0)
    cv.Rectangle(rgb, pt1, pt2, color, 2)

cv.ShowImage('rgb', rgb)
cv.WaitKey(0)

巴布亚新几内亚:

enter image description here

巴布亚新几内亚:

enter image description here

好的:

enter image description here

坏的:

enter image description here

在有人问我之前,不,我没有试图破解一个验证码:)OCR本身在这里并不真正相关:我真正的项目中的实际形状不是字符——我只是懒惰,字符是最容易画的东西(仍然被琐碎的方法检测到)。


Tags: 方法rgbfloatminwidthcvseqcolor
2条回答

你是否尝试过用CCH作为描述符的切角匹配或轮廓匹配(对应)。

切角匹配是利用目标图像和模板轮廓的距离变换。不完全是比例不变量,但速度快。

后者是相当缓慢的,因为复杂度至少是二次的二分匹配问题。另一方面,该方法对尺度、旋转和可能的局部失真(对于近似匹配,IMHO对上面的坏例子是好的)具有不变性。

由于形状在大小和比例上可能有所不同,因此应该查看缩放不变的描述符。一堆这样的描述符将非常适合您的应用程序。

在测试模板上处理这些描述符,然后使用某种简单的分类来提取它们。它应该会给相当好的结果,与简单的形状,如你所示。

我过去用过泽尼克和胡的时刻,后者是最有名的。您可以在这里找到一个实现示例:http://www.lengrand.fr/2011/11/classification-hu-and-zernike-moments-matlab/

另一件事:考虑到你的问题,你应该看看OCR技术(代表光学字符识别:http://en.wikipedia.org/wiki/Optical_character_recognition;)。

希望这有帮助。

朱利安

相关问题 更多 >

    热门问题