Использование OpenCV для проверки сходства нарисованной линии с созданной компьютером - PullRequest
0 голосов
/ 04 мая 2020

У меня есть случайно сделанная извилистая линия, которую я провел на другом листе бумаги. в Python и OpenCV I sh, чтобы подтвердить, что нарисованная мной линия совпадает с нарисованной компьютером (или сказать, что линия достаточно похожа на определенный процент). Это возможно? Я приложил изображения. Спасибо Андрей изображение печатной линии , изображение нарисованной линии

1 Ответ

1 голос
/ 04 мая 2020

Вот один из способов использования сопоставления форм в Python / OpenCV.

  • Считывание двух входных изображений и вычисление их центров
  • Обрезка обоих изображений до некоторого общего размера относительно их центров
  • Преобразовать их в серый
  • Do Otsu thresholding
  • Применить морфологическое разрушение к рисованной фигуре, чтобы сделать линии примерно такими же толстыми, как и в изображении, созданном компьютером
  • Выполните сопоставление формы и получите 3 различных метрических c расстояния.

Компьютерная фигура:

enter image description here

Нарисовано от руки рисунок:

enter image description here

import cv2
import numpy as np

# read computer generated figure and find center
img1 = cv2.imread('computer_figure.jpg')
hh1, ww1 = img1.shape[:2]
cx1 = ww1 // 2
cy1 = hh1 // 2

# read hand drawn figure and find center
img2 = cv2.imread('drawn_figure.jpg')
hh2, ww2 = img2.shape[:2]
cx2 = ww2 // 2
cy2 = hh2 // 2

# specify crop size and crop both images
wd = 1450
ht = 1450
xoff = wd // 2
yoff = ht // 2
img1_crop = img1[cy1-yoff:cy1+yoff, cx1-xoff:cx1+xoff]
img2_crop = img2[cy2-yoff:cy2+yoff, cx2-xoff:cx2+xoff]

# convert to grayscale
gray1 = cv2.cvtColor(img1_crop,cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2_crop,cv2.COLOR_BGR2GRAY)

# threshold
thresh1 = cv2.threshold(gray1, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
thresh2 = cv2.threshold(gray2, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]

# erode thresh2 to get black lines approx as thick as thresh1
# apply close and open morphology to fill tiny black and white holes and save as mask
kernel = np.ones((13,13), np.uint8)
thresh2 = cv2.morphologyEx(thresh2, cv2.MORPH_ERODE, kernel)

# do shape matching (the smaller the distance the better the match)
distance1 = cv2.matchShapes(thresh1, thresh2, cv2.CONTOURS_MATCH_I1, 0)
distance2 = cv2.matchShapes(thresh1, thresh2, cv2.CONTOURS_MATCH_I2, 0)
distance3 = cv2.matchShapes(thresh1, thresh2, cv2.CONTOURS_MATCH_I3, 0)
print("distance 1:",distance1)
print("distance 2:",distance2)
print("distance 3:",distance3)
print("")

#distance 1: 0.00019690372821457025
#distance 2: 0.001971857215556483
#distance 3: 0.0006233041352955213

# compare to mis-match with pure white image
thresh3 = np.full_like(thresh1, 255)
distance1 = cv2.matchShapes(thresh3, thresh2, cv2.CONTOURS_MATCH_I1, 0)
distance2 = cv2.matchShapes(thresh3, thresh2, cv2.CONTOURS_MATCH_I2, 0)
distance3 = cv2.matchShapes(thresh3, thresh2, cv2.CONTOURS_MATCH_I3, 0)
print("distance 1:",distance1)
print("distance 2:",distance2)
print("distance 3:",distance3)
print("")

#distance 1: 0.0019009881608588741
#distance 2: 0.019164295934527953
#distance 3: 0.006017629998960382

# compare to total mis-match of pure white image with pure black image
thresh4 = np.zeros_like(thresh1)
distance1 = cv2.matchShapes(thresh3, thresh4, cv2.CONTOURS_MATCH_I1, 0)
distance2 = cv2.matchShapes(thresh3, thresh4, cv2.CONTOURS_MATCH_I2, 0)
distance3 = cv2.matchShapes(thresh3, thresh4, cv2.CONTOURS_MATCH_I3, 0)
print("distance 1:",distance1)
print("distance 2:",distance2)
print("distance 3:",distance3)
print("")

#distance 1: 1.7976931348623157e+308
#distance 2: 1.7976931348623157e+308
#distance 3: 1.7976931348623157e+308

# save cropped image
cv2.imwrite('drawn_figure_thresh.jpg',thresh1)
cv2.imwrite('computer_figure_thresh.jpg',thresh2)

# show the images
cv2.imshow("crop1", img1_crop)
cv2.imshow("crop2", img2_crop)
cv2.imshow("thresh1", thresh1)
cv2.imshow("thresh2", thresh2)
cv2.waitKey(0)
cv2.destroyAllWindows()


Рисунок с пороговым значением на компьютере:

enter image description here

Рисованные с пороговым и эродированным рисунком:

enter image description here

Полученные результаты перечислены в коде выше

Метрики расстояний см. https://www.learnopencv.com/shape-matching-using-hu-moments-c-python/

...