如何在python中使用opencv复制图像区域?

Posted

技术标签:

【中文标题】如何在python中使用opencv复制图像区域?【英文标题】:How to copy a image region using opencv in python? 【发布时间】:2012-02-23 11:18:34 【问题描述】:

我正在尝试使用http://iamabhik.wordpress.com/category/opencv/ 的想法来实现一个车牌识别软件。

我在 python 中使用 opencv 实现了板定位,使用“import cv2”。它工作正常,现在我需要将车牌区域复制到另一张图像以进行字符分割,然后是 OCR 部分(可能使用神经网络)。

我发现 GetSubRect() 函数可以复制或隔离图像的一部分,但它似乎在 python 中不可用。有替代方案吗? ROI功能似乎也没有实现。

是否有关于 opencv 的 python 接口的最新文档?

我在 Debian wheezy/sid 环境中从 svn 存储库(修订版 7239)编译了 opencv。

随意提出解决此问题的替代方法/想法。

提前致谢。

【问题讨论】:

【参考方案1】:

这是从图像中裁剪 ROI 的可视化效果

-------------------------------------------
|                                         | 
|    (x1, y1)                             |
|      ------------------------           |
|      |                      |           |
|      |                      |           | 
|      |         ROI          |           |  
|      |                      |           |   
|      |                      |           |   
|      |                      |           |       
|      ------------------------           |   
|                           (x2, y2)      |    
|                                         |             
|                                         |             
|                                         |             
-------------------------------------------

(0,0) 视为图像的左上角,从左到右为x 方向,从上到下为y 方向。如果我们将(x1,y1) 作为左上角,(x2,y2) 作为 ROI 的右下角顶点,我们可以使用 Numpy 切片来裁剪图像:

ROI = image[y1:y2, x1:x2]

但通常我们不会有右下角的顶点。在典型情况下,我们将遍历可以使用cv2.boundingRect() 找到矩形 ROI 坐标的轮廓。此外,如果我们想保存多个 ROI,我们可以保留一个计数器

cnts = cv2.findContours(grayscale_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

ROI_number = 0
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    ROI = image[y:y+h, x:x+w]
    cv2.imwrite('ROI_.png'.format(ROI_number), ROI)
    ROI_number += 1

从 OpenCV v2.2 开始,Numpy 数组被天真地用于显示图像。这种提取 ROI 的 Numpy 切片方法可能不适用于旧版本

【讨论】:

【参考方案2】:

例子:如果你有几个点,并且想复制包含它的区域

r = cv2.boundingRect(pts)
cv2.imwrite('roi.png', im[r[0]:r[0]+r[2], r[1]:r[1]+r[3]])

【讨论】:

我认为它实际上是r[1]:r[1]+r[3], r[0]:r[0]+r[2]。因为 boundingRect 返回 r = [x, y, w, h] 并且 numpy 语法需要 [y:y+h, x:x+w] 上面的评论是对的,应该是[y: y+h, x: x+w]。【参考方案3】:

cv.GetSubRect 和 ROI 函数都在 Python 中可用,但在旧的 import cv 模式或 import cv2.cv 中可用。即使用cv2.cv.GetSubRect()cv2.cv.SetImageROI,如果您更熟悉它们。

另一方面,由于新 cv2 中的 numpy 集成,在没有这些功能的情况下设置 ROI 很简单。

如果 (x1,y1) 和 (x2,y2) 是你得到的板的两个相反顶点,那么只需使用函数:

roi = gray[y1:y2, x1:x2]

这就是您的图像投资回报率。

所以选择适合你的。

【讨论】:

我尝试使用 SetImageROI,但在我的版本 OpenCV (2.4.1) 中它不起作用 - 始终从 (0,0) 点复制。 Slice ndarray 它是非常清晰和好的解决方案。谢谢。 我总是从点 (0,0) 复制时遇到同样的问题,这让我发疯了。带有 numpy 的 cv2 似乎是一个更好的解决方案。 很好奇为什么它在 y,x 而不是 x,y 坐标中? cv2.rectangle 取 x,y ...直观地取一个 roi 就像取一个矩形 @user391339:这是一个 numpy 数组操作。所以它是行,列的顺序。 array[r][c] 给出元素,array[r1:r2, c1:c2] 给出矩形。如果您使用的是 OpenCV Rectangle,是的,它是 x,y 坐标。 其中 gray 是读取为 numpy 数组的图像,如 gray = imread('plate.png"),而不是属性

以上是关于如何在python中使用opencv复制图像区域?的主要内容,如果未能解决你的问题,请参考以下文章

Python:如何从图像中切出具有特定颜色的区域(OpenCV,Numpy)

OpenCV_复制一个或多个ROI图像区域

如何在opencv python中调整PNG图像的大小? [复制]

在 Python、OpenCV 中使用切片从图像中提取区域

基于python语言的opencv如何把图片中指定区域截取出来?

opencv如何读取多边形区域内的像素值?