【问题标题】:How to copy a image region using opencv in python?如何在python中使用opencv复制图像区域?
【发布时间】: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。

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

提前致谢。

【问题讨论】:

    标签: python image opencv image-processing roi


    【解决方案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"),而不是属性
      猜你喜欢
      • 2021-04-11
      • 2015-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-01
      • 2012-02-21
      • 2021-07-31
      相关资源
      最近更新 更多