правильно повернуть или перевернуть изображения [счета, формы] в правильную ориентацию в python - PullRequest
0 голосов
/ 19 февраля 2020

Я пытаюсь повернуть изображения, которые содержат накладную и формирует ее правильную ориентацию. Я пытаюсь найти угол и затем поворачивать изображение. Немногие изображения вращаются только правильно. Ниже приведен код и изображения, которые я пытался повернуть в правильной ориентации: первое изображение вращается правильно, а другое вращается неправильно


import numpy as np
import cv2
import math
from scipy import ndimage

img_before = cv2.imread('rotate_me.png')

cv2.imshow("Before", img_before)    
key = cv2.waitKey(0)

img_gray = cv2.cvtColor(img_before, cv2.COLOR_BGR2GRAY)
img_edges = cv2.Canny(img_gray, 100, 100, apertureSize=3)
lines = cv2.HoughLinesP(img_edges, 1, math.pi / 180.0, 100, minLineLength=100, maxLineGap=5)

angles = []

for x1, y1, x2, y2 in lines[0]:
    cv2.line(img_before, (x1, y1), (x2, y2), (255, 0, 0), 3)
    angle = math.degrees(math.atan2(y2 - y1, x2 - x1))
    angles.append(angle)

median_angle = np.median(angles)
img_rotated = ndimage.rotate(img_before, median_angle)

print "Angle is {}".format(median_angle)
cv2.imwrite('rotated.jpg', img_rotated) 

первое изображение - [левая сторона перевернута] --- после вращения правильно вращается второе изображение - правая сторона перевернута - неправильное вращение Оба изображения имеют угол -90 градусов. Окончательный результат должен быть похож на изображение3

https://i.stack.imgur.com/XpFVy.png

https://i.stack.imgur.com/bGI3k.png

https://i.stack.imgur.com/jHNgD.png

1 Ответ

0 голосов
/ 19 февраля 2020

Вместо того, чтобы находить линии, я предлагаю найти цветную область.

Если область находится на правой стороне изображения, изображение необходимо повернуть.

Нахождение цветной области можно выполнить следующим образом:

  • Вычислить абсолютную разницу между каждыми двумя цветными каналами и суммировать результат.
    Результат имеет высокие значения, где есть цвет (не черный / белый).
  • Применить порог - значения ниже порога будут равны нулю (считается черно-белым), а порог выше 255 (цветные пиксели).
  • Найдите самый большой кластер в пороговом изображении, используя connectedComponentsWithStats .
  • Если центр наибольшего белого кластера находится справа, поверните изображение.

Вот пример кода:

import numpy as np
import cv2

im = cv2.imread("rotate_me1.png", cv2.IMREAD_UNCHANGED);

# Compute difference between each two color channels for finding colored pixels.
cdiff = cv2.absdiff(im[:,:,0], im[:,:,1])//3 + cv2.absdiff(im[:,:,0], im[:,:,2])//3 + cv2.absdiff(im[:,:,1], im[:,:,2])//3;
ret, cmask = cv2.threshold(cdiff, 10, 255, cv2.THRESH_BINARY)

# Find clusters.
# https://answers.opencv.org/question/194566/removing-noise-using-connected-components/
nlabel,labels,stats,centroids = cv2.connectedComponentsWithStats(cmask, connectivity=8)

# Find second largest cluster (the largest is the background?):
stats[np.argmax(stats[:, cv2.CC_STAT_AREA])] = 0
idx_max_size = np.argmax(stats[:, cv2.CC_STAT_AREA])
center = centroids[idx_max_size]

# True if the center of the centroid is at the right side of the image
is_center_at_right_side = center[0] > im.shape[1]//2

if is_center_at_right_side:
    rotated_im = im[::-1, ::-1, :].copy()  # Reverse left/right and up/down
    cv2.imshow('rotated_im', rotated_im)

# Draw green circle at the center (for testing)
cv2.circle(im, (int(center[0]), int(center[1])), 10, (0, 255, 0), thickness=10)

cv2.imshow('cmask', cmask)
cv2.imshow('im', im)
cv2.waitKey(0)
cv2.destroyAllWindows()

Пример для cmask:
enter image description here

Маркировочный центр самого большого скопления с зеленым кружком:
enter image description here

Повернутое изображение:
enter image description here


Обновление:

Поворот на 90 градусов:

Результат:

enter image description here
...