How to find the orientation of an object (shape)? - Python Opencv

后端 未结 2 1542
庸人自扰
庸人自扰 2021-01-03 09:05

My images are always like this:

But I need to rotate them to be like this:

But to do that, I need to find the orientation of the object, knowing

相关标签:
2条回答
  • 2021-01-03 09:23

    Here is one way in Python/OpenCV.

    • Read the image

    • Convert to grayscale

    • Threshold

    • Get outer contour

    • Get minAreaRect points and angle from outer contour

    • Get vertices of rotated rectangle

    • Draw the rotated rectangle

    • Correct the angle as needed

    • Print the angle

    • Save the image with the rotated rectangle drawn on it


    Input:

    import cv2
    import numpy as np
    
    # load image as HSV and select saturation
    img = cv2.imread("wing2.png")
    hh, ww, cc = img.shape
    
    # convert to gray
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # threshold the grayscale image
    ret, thresh = cv2.threshold(gray,0,255,0)
    
    # find outer contour
    cntrs = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]
    
    # get rotated rectangle from outer contour
    rotrect = cv2.minAreaRect(cntrs[0])
    box = cv2.boxPoints(rotrect)
    box = np.int0(box)
    
    # draw rotated rectangle on copy of img as result
    result = img.copy()
    cv2.drawContours(result,[box],0,(0,0,255),2)
    
    # get angle from rotated rectangle
    angle = rotrect[-1]
    
    # from https://www.pyimagesearch.com/2017/02/20/text-skew-correction-opencv-python/
    # the `cv2.minAreaRect` function returns values in the
    # range [-90, 0); as the rectangle rotates clockwise the
    # returned angle trends to 0 -- in this special case we
    # need to add 90 degrees to the angle
    if angle < -45:
        angle = -(90 + angle)
     
    # otherwise, just take the inverse of the angle to make
    # it positive
    else:
        angle = -angle
    
    print(angle,"deg")
    
    # write result to disk
    cv2.imwrite("wing2_rotrect.png", result)
    
    cv2.imshow("THRESH", thresh)
    cv2.imshow("RESULT", result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    Angle Returned: 0.8814040422439575 deg

    Image with Rotated Rectangle:

    0 讨论(0)
  • 2021-01-03 09:25

    You have to compute the main axis (it is based on PCA). It will give you a good idea of the main orientation, then you can rotate your image accordingly.

    As it was pointed as a comment, you now have to test that the thin part is on the right side of the image, and for that you use the centroid/barycenter: if the centroid is on the left of the bounding box, then the wing is well oriented.

    Here is the complete algorithm:

    • Compute the main orientation (main axis, computed with PCA)
    • Rotate your image according to the main axis orientation.
    • Compute the bounding box and centroid/barycenter
    • If the centroid is on the left, then your image is well oriented, else rotate it about 180°.

    Here are the results...

    0 讨论(0)
提交回复
热议问题