37

I am trying to implement a license plate recognition software using the ideas from http://iamabhik.wordpress.com/category/opencv/.

I implemented the plate location using opencv in python, using "import cv2". It works okay and now I need to copy the plate region to another image to do the segmentation of the characters and then the OCR part (maybe using a neural network).

I found the GetSubRect() function to copy or isolate part of the image but it does not appear to be available in python. Is there an alternative? The ROI functions do not seem to be implemented either.

Is there an up-to-date documentation of the python interface to opencv?

I compiled opencv from svn repository (revision 7239) on a Debian wheezy/sid environment.

Fell free to suggest alternative methods/ideas to solve this problem.

Thanks in advance.

nathancy
  • 26,679
  • 11
  • 67
  • 86
curumim
  • 471
  • 1
  • 4
  • 4

3 Answers3

63

Both cv.GetSubRect and ROI functions are available in Python, but in old import cv mode or import cv2.cv. ie use cv2.cv.GetSubRect() or cv2.cv.SetImageROI if you are familier with them.

On the other hand, it is simple to set ROI without these functions due to numpy integration in new cv2.

If (x1,y1) and (x2,y2) are the two opposite vertices of plate you obtained, then simply use function:

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

that is your image ROI.

So choose whatever suit you.

Abid Rahman K
  • 48,289
  • 27
  • 140
  • 153
  • 1
    I was try to use SetImageROI, but in my version OpenCV (2.4.1) it doesn't work - copy from (0,0) point always. Slice ndarray it's very clear and good solution. Thanks. – Xeningem Jun 12 '12 at 14:38
  • I had the same problem with it always copying from point (0,0), it drove me crazy. The cv2 with numpy seems a much better solution. – hjweide Jul 04 '12 at 07:33
  • 2
    curious why is it in y,x and not x,y coordinates? cv2.rectangle takes x,y ... intuitively taking an roi is like taking a rectangle – user391339 Jun 20 '15 at 02:26
  • 3
    @user391339: This is a numpy array operation. So it is in row, column order. array[r][c] gives the element, array[r1:r2, c1:c2] gives the rectangle. If you are using OpenCV Rectangle, yes, it is x,y coordinate. – Abid Rahman K Jun 20 '15 at 17:50
  • where gray is the image read as numpy array, as in gray = imread('plate.png"), and not an attribute – Gathide Jun 01 '16 at 12:54
  • Beware that if part of the region falls outside the image itself, opencv will still proceed with the extraction - but it will return a region with a smaller size that the one specified – Eduardo Pignatelli Apr 11 '18 at 14:27
16

Here's a visualization for cropping a ROI from an image

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

Consider (0,0) as the top-left corner of the image with left-to-right as the x-direction and top-to-bottom as the y-direction. If we have (x1,y1) as the top-left and (x2,y2) as the bottom-right vertex of a ROI, we can use Numpy slicing to crop the image with:

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

But normally we will not have the bottom-right vertex. In typical cases, we will be iterating through contours where the rectangular ROI coordinates can be found with cv2.boundingRect(). Additionally, if we wanted to save multiple ROIs, we could keep a counter

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

Since OpenCV v2.2, Numpy arrays are naively used to display images. This Numpy slicing method to extract the ROI may not work with older versions

nathancy
  • 26,679
  • 11
  • 67
  • 86
7

Example: If you have few points, and want to copy region contains its

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