如何在Python中使用OpenCV复制图像区域?

48 投票
3 回答
133522 浏览
提问于 2025-04-17 12:03

我正在尝试开发一个车牌识别软件,灵感来自于这个网站

我用Python和opencv实现了车牌位置的检测,使用了“import cv2”。效果还不错,现在我需要把车牌区域复制到另一张图片上,以便进行字符的分割,然后再进行OCR(光学字符识别)部分,可能会用到神经网络。

我找到了GetSubRect()这个函数,可以用来复制或隔离图像的一部分,但在Python中似乎没有这个函数。有没有其他的替代方法?ROI(感兴趣区域)相关的函数好像也没有实现。

有没有更新的关于Python接口使用opencv的文档?

我是在Debian wheezy/sid环境下,从svn仓库(版本7239)编译了opencv。

欢迎随时提出其他方法或想法来解决这个问题。

3 个回答

8

举个例子:如果你有几个点,并且想要复制包含这些点的区域。

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

这里有一个关于如何从图片中裁剪感兴趣区域(ROI)的可视化示例。

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

我们把(0,0)看作是图片的左上角,x轴是从左到右,y轴是从上到下。如果我们有(x1,y1)作为左上角的坐标,(x2,y2)作为右下角的坐标,我们可以用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数组被简单地用来显示图片。不过,这种用Numpy切片提取ROI的方法在旧版本中可能不太适用。

73

在Python中,cv.GetSubRect和ROI这两个功能是可以用的,不过是在旧的import cv模式下,或者是import cv2.cv。也就是说,如果你对这些函数熟悉的话,可以用cv2.cv.GetSubRect()或者cv2.cv.SetImageROI

不过,使用新的cv2时,由于它和numpy结合得很好,所以其实不需要这些函数也能很简单地设置ROI。

假设你得到了板子的两个对角点坐标(x1,y1)和(x2,y2),那么你只需要使用这个函数:

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

这就是你的图像ROI。

所以你可以选择适合你的方法。

撰写回答