使用OpenCV来验证所画的线与计算机生成的线的相似性。

问题描述 投票:0回答:1

在Python和OpenCV中,我希望验证我所画的线和计算机所画的线是一样的(或者说线的相似度达到了一定的比例)。这可能吗?我已经附上了图片,谢谢你Andrew印线图,线形图

opencv line similarity
1个回答
2
投票

这里是在PythonOpenCV中使用形状匹配的一种方法。

  • 读取两个输入图像并计算它们的中心点。
  • 将两张图片裁剪到它们的中心位置的一些共同大小。
  • 将它们转换为灰色
  • 做大津阈值
  • 将形态学侵蚀应用到手绘图上,使线条与电脑生成的图像差不多粗。
  • 做形状匹配,得到3个不同的度量距离。

电脑生成图。

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.comshape-matching-using-hu-moments-c-python

© www.soinside.com 2019 - 2024. All rights reserved.