使用opencv在图像中查找形状

时间:2012-01-09 08:36:43

标签: python opencv

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

我目前的做法:

  1. 检测轮廓
  2. 对于每个轮廓,计算最大边界框
  3. 将每个边界框分别与其中一个已知形状匹配。在我的实际项目中,我将区域缩放到模板大小并计算Sobel梯度的差异,但对于此演示,我只是使用宽高比。
  4. 这种方法即将解体的地方是形状触摸的地方。轮廓检测将两个相邻的形状作为单个轮廓(单个边界框)拾取。匹配步骤显然会失败。

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

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

    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)
    

    e.png:

    enter image description here

    y.png:

    enter image description here

    好:

    enter image description here

    坏:

    enter image description here

    在任何人问之前,不,我试图打破验证码:) OCR本身并不真正相关:我真实项目中的实际形状不是字符 - 我只是懒惰,角色是最简单的绘制(并且仍然可以通过简单的方法检测到)。

2 个答案:

答案 0 :(得分:3)

由于您的形状的大小和比例各不相同,您应该查看缩放不变描述符。一堆这样的描述符对你的应用来说是完美的。

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

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

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

希望这会有所帮助。

于连

答案 1 :(得分:0)

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

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

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