Это решение смотрит на пару изображений. Алгоритм оценивает, будут ли фигуры на изображении сцепляться как ключ и замок. Мой ответ не пытается выровнять изображения.
Первый шаг - найти контуры на изображениях:
left= cv2.imread('/home/stephen/Desktop/left.png')
right = cv2.imread('/home/stephen/Desktop/right.png')
# Resize
left = cv2.resize(left, (320,320))
gray = cv2.cvtColor(left, cv2.COLOR_BGR2GRAY)
_, left_contours, _ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# Approximate
left_contour = left_contours[0]
epsilon = 0.005*cv2.arcLength(left_contour,True)
left_contour = cv2.approxPolyDP(left_contour,epsilon,True)
Что такое контур? Контур - это просто список точек, которые лежат по периметру фигуры. Контур для треугольника будет иметь 3 точки и длину 3. Расстояние между точками будет длиной каждой ноги в треугольнике.
Аналогично, расстояния между вершинами и долинами будут совпадать на ваших изображениях. Чтобы вычислить это расстояние, я нашел расстояние между точками контура. Из-за способа выравнивания изображений я использовал только горизонтальное расстояние.
left_dx = []
for point in range(len(left_contour)-1):
a = left_contour[point][0]
b = left_contour[point+1][0]
dist = a[0]-b[0]
left_dx.append(dist)
right_dx = []
for point in range(len(right_contour)-1):
a = right_contour[point][0]
b = right_contour[point+1][0]
# Use the - of the distance becuase this is the key hole, not the key
dist = -distance(a,b)
right_dx.append(dist)
# Reverse so they will fit
right_dx.reverse()
В этой точке вы можете видеть, что контуры совпадают. Если у вас есть лучшие изображения, контуры выстроятся в ряд на этом шаге. Я использовал Scipy для интерполяции и проверки соответствия функций. Если две функции выстраиваются в линию, то объекты на изображениях будут сцепляться.
left_x_values = []
for i in range(len(left_dx)): left_x_values.append(i)
x = np.array(left_x_values)
y = np.array(left_dx)
left_x_new = np.linspace(x.min(), x.max(),500)
f = interp1d(x, y, kind='quadratic')
left_y_smooth=f(left_x_new)
plt.plot (left_x_new, left_y_smooth,c = 'g')
* * 1030
Я попробовал это снова на паре изображений, которые я создал сам:
Контуры:
Расстояния между точками контура:
Подгонка контуров: