Перекошенное изображение - невозможно определить горизонтальные линии с помощью CV2 - PullRequest
0 голосов
/ 26 апреля 2020

На этом изображении я пытаюсь обнаружить горизонтальные линии. Код работает хорошо, когда изображение не перекошено. Тем не менее, он не работает с такими искаженными изображениями. Я пробовал этот метод для определения правильного угла по гистограмме, но много раз на самом деле делает его более искаженным - python -opencv-skew-исправить-for-ocr

Skewed image

Ниже приведен код для обнаружения горизонтальных линий:

    gray=cv2.cvtColor(img_final_bin,cv2.COLOR_BGR2GRAY)
    horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (100,1))
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
    detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
    cnts, hierarchy = cv2.findContours(detected_lines, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)


    boundingBoxes = [list(cv2.boundingRect(c)) for c in cnts]

Ниже приведен код для коррекции перекоса, который дает неверные результаты для меня:

def correct_skew(image, delta=0.001, limit=3):
    def determine_score(arr, angle):
        data = inter.rotate(arr, angle, reshape=False, order=0)
        histogram = np.sum(data, axis=1)
        score = np.sum((histogram[1:] - histogram[:-1]) ** 2)
        return histogram, score

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] 

    print("thresh", thresh.shape)
    thresh1 = thresh[0:500, 0:500]
    print("thresh1", thresh1.shape)

    scores = []
    angles = np.arange(-limit, limit + delta, delta)
    for i, angle in enumerate(angles):
        histogram, score = determine_score(thresh1, angle)
        scores.append(score)
        # if i%100 == 0:   
        #     print(score, angle, len(angles), i)

    best_angle = angles[scores.index(max(scores))]

    (h, w) = image.shape[:2]
    center = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D(center, best_angle, 1.0)
    rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, \
              borderMode=cv2.BORDER_REPLICATE)

    return best_angle, rotated

1 Ответ

3 голосов
/ 26 апреля 2020

Python Жезл, основанный на ImageMagick, имеет настольную функцию.

Ввод:

enter image description here


from wand.image import Image
from wand.display import display

with Image(filename='table.png') as img:
    img.deskew(0.4*img.quantum_range)
    img.save(filename='table_deskew.png')
    display(img)


Результат:

enter image description here

...