【问题标题】:Finding shapes in an image using opencv使用opencv在图像中查找形状
【发布时间】:2012-02-05 19:48:14
【问题描述】:

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

我目前的做法:

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

这种方法失败的地方是形状接触的地方。轮廓检测将两个相邻的形状作为单个轮廓(单个边界框)。匹配步骤显然会失败。

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

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

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

源代码:

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)

e.png:

y.png:

好:

不好:

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

【问题讨论】:

  • 您是否考虑过为比率高度/宽度定义一个有效区间。如果形状相互接触的所有情况都导致边界框太宽或太高,那么这可能是一个线索。
  • 是的,我已经想到了。不过,谢谢你提到它。

标签: python opencv


【解决方案1】:

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

在您的测试模板上处理这些描述符,然后使用某种简单的分类来提取它们。正如您所展示的那样,它应该会以简单的形状给出相当不错的结果。

我过去使用过 Zernike 和 Hu 的时刻,后者是最著名的。您可以在此处找到实现示例:http://www.lengrand.fr/2011/11/classification-hu-and-zernike-moments-matlab/

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

希望这会有所帮助。

朱利安

【讨论】:

  • 感谢您的评论。你会计算每个轮廓的矩吗?如果是,那么它将如何解决合并形状的问题?提取的时刻不会真正匹配训练形状的时刻,不是吗?此外,OCR per se 在这里并不真正相关:我的真实项目中的实际形状不是字符——我只是懒惰,字符是最容易绘制的东西(并且仍然得到用简单的方法检测)。由于您可能不是第一个或最后一个在查看问题时考虑 OCR 的人,所以我在其中添加了一些内容。
  • 是的。相关方法的问题是我不知道图像的确切大小。我可以尝试不同的模板大小,但这对我来说真的不够好——我需要知道形状的确切大小。
  • 有什么消息吗?形状合并是计算机视觉中众所周知的问题之一 :)
  • 根据我对现有形状和其他图像特征的了解,我最终寻找了分割 CC 的最佳位置。这是一个非常具体的算法,我对它一点也不满意,但它现在似乎可以工作。
【解决方案2】:

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

倒角匹配是使用目标图像和模板轮廓的距离变换。不完全是尺度不变的,但速度很快。

后者相当慢,因为对于二分匹配问题,复杂度至少是二次方的。另一方面,这种方法对于缩放、旋转和可能的局部失真是不变的(对于近似匹配,恕我直言,这对于上面的坏例子来说是好的)。

【讨论】:

    猜你喜欢
    • 2015-07-17
    • 1970-01-01
    • 2011-01-05
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 2018-12-01
    • 2020-11-22
    相关资源
    最近更新 更多