Согласно диаграмме, это не похоже на билинейную интерполяцию, это выглядит как среднее между двумя углами.
Я не уверен, что мое решение - то, что вы ищете, но я предполагаю, что оно дает вам преимущество ...
Я попытался решить его, найдя круг автоматически, используя cv2.HoughCircles
и отметьте x
, y
позиции с помощью тригонометрии.
Решение использует следующие этапы:
- Преобразование изображения в серый и двоичный.
- Найдите круги, используя
cv2.HoughCircles
. - . Итерируйте круги и найдите круг с центром, ближайшим к центру изображения.
- Вычислять углы с шагом 45 градусов
[0, 45, 90, 135...]
, назвать их alpha
.
Вычислить углы между вышеуказанными углами [22.5, 67.5, 112.5...]
, назвать их beta
.
Мы на самом деле не нужно alpha
для вычислений beta
.
Это просто для демонстрации того типа интерполяции, который вы предполагаете сделать. - Вычисление
x
, y
каждой точки с использованием тригонометрии.
Пометка "альфа" точек голубыми кружками.
Пометка "бета" точек желтыми кружками.
Вы можете хранить x
, y
«бета» баллов - это те баллы, которые вы ищете.
Вот код:
import cv2
import numpy as np
# Read input imgae
img = cv2.imread('image.png')
# Convert to Grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Convert to binary image, and invert polarity
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
rows, cols = thresh.shape
circles = cv2.HoughCircles(thresh, cv2.HOUGH_GRADIENT, 1, minDist=rows//8, param1=50, param2=60, minRadius=rows//8, maxRadius=rows//2)
# Find the circle with center closest to the center of the image
min_dist_from_center = 1e9
min_c = []
for c in circles[0,:]:
# Euclidean distance from the center of circle to center of image
dist_from_center = np.linalg.norm([c[0] - cols/2, c[1] - rows/2])
if dist_from_center < min_dist_from_center:
min_dist_from_center = dist_from_center
min_c = c
c = min_c
# Draw circle for testing
cv2.circle(img, (c[0], c[1]), c[2], (0, 255, 0), 2)
# Array of angles in 45 degrees difference
alpha_arr = np.arange(0, 360+45, 45) # [ 0, 45, 90, 135, 180, 225, 270, 315, 360]
betta_arr = (alpha_arr[1:] + alpha_arr[0:-1])/2 # [ 22.5, 67.5, 112.5, 157.5, 202.5, 247.5, 292.5, 337.5] Points between alpha
# Compute x, y coordinates by angle and radius
r = c[2]
for alpha, beta in zip(alpha_arr[:-1], betta_arr):
x = r*np.cos(np.deg2rad(alpha)) + c[0] # x = r*cos(alpha) + center_x
y = r*np.sin(np.deg2rad(alpha)) + c[1] # y = r*sin(alpha) + center_y
# Draw small cyan circle to mark alpha points
cv2.circle(img, (int(x), int(y)), 12, (255, 255, 0), 3)
x = r*np.cos(np.deg2rad(beta)) + c[0] # x = r*cos(alpha) + center_x
y = r*np.sin(np.deg2rad(beta)) + c[1] # y = r*sin(alpha) + center_y
# Draw small yellow circle to mark beta points
cv2.circle(img, (int(x), int(y)), 10, (0, 255, 255), 3)
# Show images for testing
cv2.imshow('thresh', thresh)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Результат: