Code
import cv2 from math import atan, pi, ceil img = cv2.imread('mask3.jpg', 0) h,w = img.shape[:2] cv2.imshow('original', img) m = cv2.moments(img) # You can read about Image Moments # Chapter 18 Shape analysis - Page 633 # Digital Image Processing 4th Edition By William K. Pratt # OR http://en.wikipedia.org/wiki/Image_moment x = m['m10']/m['m00'] y = m['m01']/m['m00'] mu02 = m['mu02'] mu20 = m['mu20'] mu11 = m['mu11'] lambda1 = 0.5*( mu20 + mu02 ) + 0.5*( mu20**2 + mu02**2 - 2*mu20*mu02 + 4*mu11**2 )**0.5 lambda2 = 0.5*( mu20 + mu02 ) - 0.5*( mu20**2 + mu02**2 - 2*mu20*mu02 + 4*mu11**2 )**0.5 lambda_m = max(lambda1, lambda2) # Convert from radians to degrees angle = atan((lambda_m - mu20)/mu11)*180/pi print angle # Create a rotation matrix and use it to de-skew the image. center = tuple(map(int, (x, y))) rotmat = cv2.getRotationMatrix2D(center, angle , 1) rotatedImg = cv2.warpAffine(img, rotmat, (w, h), flags = cv2.INTER_CUBIC) cv2.imshow('final', rotatedImg) cv2.waitKey()
Results
I would not be explaining the maths behind Image moments, if you care to know more check the reference in the code. Nothing explains code better than some tests! Here are a few test images and the de-skewed resulting images.Original Image | De-skewed Image | Orientation (degree) |
---|---|---|
-89.99 | ||
-0.0 | ||
-39.03 | ||
46.95 | ||
3.57 |
Conclusion
As you can see the algorithm works pretty well, an anticlockwise skew returns a negative angle and a clockwise skew returns a positive angle. Be aware the results you get will vary based on the quality of the segmented mask. Low quality (see last test image) segmentation would change the centre of the mask and this would after the calculated angle. So depending on your case you might need some pre-processing before de-skewing. Please feel free to post questions in the comments. Happy Coding!
angle = calculation from radians to degrees, does not give correct angle on image with text lines, I made some correction instead 18000 I set 1800, I checked for skews about 2%-3% it gave correct angle, have I made correctly ?
ReplyDeleteI have made some corrections to the code, please have a look at it
Deleteyes, now it correct,
DeleteI took examples for theta calculate also from houghLines with Atan2
thanks for correction.
your code for deskew, I found is the only one works accuratly with openCV.
for diversified images
images, on invoices with frames (vertical and horizontals) it gives not accurate angles the (the angle is about 30% skew) , on "smooth" images, like your rectangles examles, the angle is correct,
ReplyDeletecan you advice something about ?