使用OpenCV查找图像中的形状 [英] Finding shapes in an image using opencv

查看:582
本文介绍了使用OpenCV查找图像中的形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to look for shapes in an image using OpenCV. I know the shapes I want to match (there are some shapes I don't know about, but I don't need to find them) and their orientations. I don't know their sizes (scale) and locations.

我目前的做法:

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

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

Where this approach comes undone is where shapes touch. The contour detection picks up the two adjacent shapes as a single contour (single bounding box). The matching step will then obviously fail.

有没有一种方法可以修改我的方法以分别处理相邻的形状?另外,是否有更好的方法执行第3步?

Is there a way to modify my approach to handle adjacent shapes separately? Also, is there a better way to perform step 3?

例如:(ES颜色为绿色,Ys颜色为蓝色)

For example: (Es colored green, Ys colored blue)

失败的情况:(红色未知形状)

Failed case: (unknown shape in red)

源代码:

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本身在这里并不重要:我实际项目中的实际形状不是字符-我只是懒惰,而且字符是最容易绘制的东西(并且仍然会被一些琐碎的方法检测到).

Before anybody asks, no, I'm not trying to break a captcha :) OCR per se isn't really relevant here: the actual shapes in my real project aren't characters -- I'm just lazy, and characters are the easiest thing to draw (and still get detected by trivial methods).

推荐答案

由于形状的大小和比例会有所不同,因此您应该查看缩放不变描述符.一堆这样的描述符对于您的应用程序来说是完美的.

As your shapes can vary in size and ratio, you should look at scaling invariant descriptors. A bunch of such descriptors would be perfect for your application.

在测试模板上处理这些描述符,然后使用某种简单的分类来提取它们.如您所展示的,它应该以简单的形状给出非常好的结果.

Process those descriptors on your test template and then use some kind of simple classification to extract them. It should give pretty good results with simple shapes as you show.

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

I used Zernike and Hu moments in the past, the latter being the most famous. You can find an example of implementation here : http://www.lengrand.fr/2011/11/classification-hu-and-zernike-moments-matlab/.

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

Another thing : Given your problem, you should look at OCR technologies (stands for optical character recognition : http://en.wikipedia.org/wiki/Optical_character_recognition ;)).

希望这会有所帮助.

朱利安

这篇关于使用OpenCV查找图像中的形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆