Detect if a text image is upside down

后端 未结 4 1610
孤城傲影
孤城傲影 2021-01-31 03:06

I have some hundreds of images (scanned documents), most of them are skewed. I wanted to de-skew them using Python.
Here is the code I used:

import numpy a         


        
4条回答
  •  孤街浪徒
    2021-01-31 03:28

    Python3/OpenCV4 script to align scanned documents.

    Rotate the document and sum the rows. When the document has 0 and 180 degrees of rotation, there will be a lot of black pixels in the image:

    Use a score keeping method. Score each image for it's likeness to a zebra pattern. The image with the best score has the correct rotation. The image you linked to was off by 0.5 degrees. I omitted some functions for readability, the full code can be found here.

    # Rotate the image around in a circle
    angle = 0
    while angle <= 360:
        # Rotate the source image
        img = rotate(src, angle)    
        # Crop the center 1/3rd of the image (roi is filled with text)
        h,w = img.shape
        buffer = min(h, w) - int(min(h,w)/1.15)
        roi = img[int(h/2-buffer):int(h/2+buffer), int(w/2-buffer):int(w/2+buffer)]
        # Create background to draw transform on
        bg = np.zeros((buffer*2, buffer*2), np.uint8)
        # Compute the sums of the rows
        row_sums = sum_rows(roi)
        # High score --> Zebra stripes
        score = np.count_nonzero(row_sums)
        scores.append(score)
        # Image has best rotation
        if score <= min(scores):
            # Save the rotatied image
            print('found optimal rotation')
            best_rotation = img.copy()
        k = display_data(roi, row_sums, buffer)
        if k == 27: break
        # Increment angle and try again
        angle += .75
    cv2.destroyAllWindows()
    

    How to tell if the document is upside down? Fill in the area from the top of the document to the first non-black pixel in the image. Measure the area in yellow. The image that has the smallest area will be the one that is right-side-up:

    # Find the area from the top of page to top of image
    _, bg = area_to_top_of_text(best_rotation.copy())
    right_side_up = sum(sum(bg))
    # Flip image and try again
    best_rotation_flipped = rotate(best_rotation, 180)
    _, bg = area_to_top_of_text(best_rotation_flipped.copy())
    upside_down = sum(sum(bg))
    # Check which area is larger
    if right_side_up < upside_down: aligned_image = best_rotation
    else: aligned_image = best_rotation_flipped
    # Save aligned image
    cv2.imwrite('/home/stephen/Desktop/best_rotation.png', 255-aligned_image)
    cv2.destroyAllWindows()
    

提交回复
热议问题