Как мы можем создать новые точки отбора проб с помощью билинейной интерполяции? - PullRequest
1 голос
/ 08 апреля 2020

У меня есть изображение в оттенках серого, и мне нужно сгенерировать новые точки отбора проб (обведены красным на рисунке) путем билинейной интерполяции. Есть ли формула или функция для вычисления значений этих точек в python?

enter image description here

1 Ответ

1 голос
/ 08 апреля 2020

Согласно диаграмме, это не похоже на билинейную интерполяцию, это выглядит как среднее между двумя углами.

Я не уверен, что мое решение - то, что вы ищете, но я предполагаю, что оно дает вам преимущество ...

Я попытался решить его, найдя круг автоматически, используя 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()

Результат:
enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...