4 point persective transform failure

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



4 point persective transform failure



I've been trying to do a 4 point perspective transform in order to start doing some OCR.



Starting with the following image I can detect the number plate



enter image description here



and crop it out with the green box being the bounding box and the red dots being the corners of the rectangle I want to square up.



enter image description here



This is the output of the transform.



enter image description here



At a first look it seams to have done the transform inside out (taking the parts either side rather than between the points).



I'm using the imutils package to do the transform and working from this and this as a guide. I'm sure it's something relatively simple I'm missing.


#!/usr/bin/python
import numpy as np
import cv2
import imutils
from imutils import contours
from imutils.perspective import four_point_transform

img = cv2.imread("sample7-smaller.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.bilateralFilter(gray,15,75,75)
v = np.median(blurred)
lower = int(max(0, (1.0 - 0.33) * v))
upper = int(min(255, (1.0 + 0.33) * v))
edged = cv2.Canny(blurred, lower, upper, 255)

conts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
conts = conts[0] if imutils.is_cv2() else conts[1]
conts = sorted(conts, key=cv2.contourArea, reverse=True)

for cnt in conts:
approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)
if len(approx) == 4:
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
for i in approx:
cv2.circle(img,(i[0][0], i[0][1]),2,(0,0,255), thickness=4)
warped = four_point_transform(img, approx.reshape(4,2))
cv2.imshow("crop",img[y:y+h,x:x+w])
cv2.imshow("warped", warped)
cv2.waitKey(0)




1 Answer
1



I would recommend you to use the OpenCV Perspective Transform method, to get the desired results, as per the given image:



enter image description here



First mark the position of src points:


src_pts = np.array([[8, 136], [415, 52], [420, 152], [14, 244]], dtype=np.float32)



And suppose you want to fit this number plate in a matrix of shape 50x200, so destination points would be:


dst_pts = np.array([[0, 0], [200, 0], [200, 50], [0, 50]], dtype=np.float32)



Find the perspective Transform Matrix as :


M = cv2.getPerspectiveTransform(src_pts, dst_pts)
warp = cv2.warpPerspective(img, M, (200, 50))



enter image description here



EDIT: As you didn't wanted to hard code the final width, height of plate, So in order to make the calculations more flexible you can calculate the width and height of the plate from the 4 marker points as:


def get_euler_distance(pt1, pt2):
return ((pt1[0] - pt2[0])**2 + (pt1[1] - pt2[1])**2)**0.5

src_pts = np.array([[8, 136], [415, 52], [420, 152], [14, 244]], dtype=np.float32)

width = get_euler_distance(src_pts[0][0], src_pts[0][1])
height = get_euler_distance(src_pts[0][0], src_pts[0][3])

dst_pts = np.array([[0, 0], [width, 0], [width, height], [0, height]], dtype=np.float32)

M = cv2.getPerspectiveTransform(src_pts, dst_pts)
warp = cv2.warpPerspective(img, M, (width, height))





That's what the imutils code is supposed to be doing (pyimagesearch.com/2014/08/25/…), it looks to be doing the same thing, just calculating the dimensions of the output on the fly
– hardillb
Feb 16 '17 at 10:09





So you want your output dimension to be be calculated on the fly @hardillb ?
– ZdaR
Feb 16 '17 at 10:19






I'd like to keep it at the same scale to start with, then I can rescale it later
– hardillb
Feb 16 '17 at 10:44





ok Edited @hardillb
– ZdaR
Feb 16 '17 at 15:48





unfortunately that's still giving the same output (and the values you're passing into the get_euler_distance need to be pairs not single values). I've zipped up all my code and the original image here if you want another look.
– hardillb
Feb 17 '17 at 20:06


get_euler_distance






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard