使用OpenCV查找图像中矩形的位置

时间:2010-01-14 22:26:36

标签: image-processing opencv computer-vision

我正在尝试使用OpenCV从iPhone游戏Blocked“解析”屏幕截图。屏幕截图裁剪得如下:

Blocked screenshot

我想现在我只想找到构成每个矩形的4个点中每个点的坐标。我确实看到OpenCV附带的示例文件squares.c,但是当我在这张图片上运行该算法时,它会出现72个矩形,包括空格的矩形区域,我显然不想算作我的一个矩形。有什么更好的方法来解决这个问题?我尝试过一些谷歌研究,但对于所有的搜索结果,几乎没有相关的可用信息。

6 个答案:

答案 0 :(得分:14)

已经讨论过类似的问题: How to recognize rectangles in this image?

对于您的数据,您要查找的矩形是唯一的黑色对象。因此,您可以尝试进行阈值二值化:黑色像素是那些具有小于40的所有三个RGB值的像素(我已经凭经验找到它)。这个简单的操作使您的图片看起来像这样:

binarized picture http://img691.imageshack.us/img691/975/rectk.png

之后你可以应用Hough变换来查找行(在我所提到的主题中讨论过),或者你可以更容易地做到。计算黑色像素到X和Y轴的积分投影。 (对X的投影是x_i的向量 - 黑色像素的数量,使得它具有等于x_i的第一个坐标)。因此,您可以获得x和y值作为投影的峰值。然后查看由找到的x和y限制的所有可能的段(如果在(x_i,y_j)和(x_i,y_k)之间存在大量黑色像素,则可能存在一条线)。最后,将线段组成矩形!

答案 1 :(得分:6)

我结束了我的原始方法,正如罗伯特在他对我的问题的评论中所说的那样。在我得到矩形列表之后,然后我运行并计算每个矩形的平均颜色。我检查一下平均颜色的红色,绿色和蓝色成分是否都在灰色和蓝色矩形颜色的10%范围内,如果它们是我保存矩形,如果它们不是我丢弃它。这个过程给我这样的东西:

screenshot

从这一点来看,获取我需要的信息(每个矩形的方向,起点和长度,将游戏窗口视为6x6网格)是微不足道的。

答案 2 :(得分:3)

块看起来像位图 - 为什么不为每个块大小/颜色/方向使用不同模板的简单模板匹配?

答案 3 :(得分:2)

由于您的问题是小矩形,我首先要删除它们。 由于这些线条比矩形边框薄得多,我首先要在图像上应用morphological operations

使用如下所示的结构元素:

 element = [ 1 1
             1 1 ]

应删除宽度小于两个像素的行。删除小行后,OpenCV的矩形查找算法很可能会为您完成剩余的工作。 可以通过函数cvErode

在OpenCV中完成侵蚀

答案 4 :(得分:1)

这是一个完整的Python解决方案。主要思想是:

  • 应用pyramid mean shift filtering有助于提高阈值准确性
  • 大津获取二进制图像的阈值
  • 找到轮廓并使用轮廓逼近进行滤波

这是每个检测到的矩形轮廓的可视化

enter image description here

结果

enter image description here

import cv2

image = cv2.imread('1.png')
blur = cv2.pyrMeanShiftFiltering(image, 11, 21)
gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.015 * peri, True)
    if len(approx) == 4:
        x,y,w,h = cv2.boundingRect(approx)
        cv2.rectangle(image,(x,y),(x+w,y+h),(36,255,12),2)

cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()

答案 5 :(得分:0)

尝试使用哈里斯角探测器等众多角落探测器中的一个。一般来说,在多种分辨率下尝试它也是一个好主意:所以做一些不同放大倍数的预处理。 看起来你想要某种颜色支配的方形,然后你可以抑制其他颜色,首先使用像cvsplit .....然后阈值颜色...所以只有那个区域仍然....跟随它种植作业......我认为这也可以起作用....