Как развернуть рисунок спирали? - PullRequest
1 голос
/ 14 марта 2020

Спираль - это плоская кривая, которая вращается вокруг центральной оси.

spiral

У меня есть рисунок пациента с болезнью Паркинсона, основанный на спирали.

drawing

Как видите, это изображение рисунка пациента колеблется вокруг базовой спирали. Я хотел бы сделать следующее: «развернуть» спираль так, чтобы колебание рисунка и самой спирали основывалось на прямой линии, то есть линеаризовать спираль. Как я могу это сделать?

1 Ответ

1 голос
/ 15 марта 2020

Возможный подход состоит из двух частей.

Первая часть пытается выровнять спираль по изображению. Самая простая спираль - это архимедова спираль, в которой радиус и угол линейно связаны. При построении графика и просмотре координат определяются пределы приблизительного масштаба для направлений x и y. Результат не идеален. Возможно, данное изображение не очень хорошо отсканировано, но просто фотография, вызывающая деформации, или оригинальная спираль не была идеальной архимедианской спиралью. (Кроме того, файл PNG будет предпочтительнее, чем данный JPG) В любом случае, масштаб достаточно хорош, чтобы дать представление о том, как будет работать алгоритм, предпочтительно начиная с точного сканирования.

Следующая часть проходит через каждый пиксель изображения и находит его соответствующий угол и расстояние до центра. (используя масштабирование, найденное в первой части). Следующий шаг - найти, сколько раз угол сместился (кратно 2 пи), выбрав наиболее близкое совпадение. Вычитание радиуса из угла выровняет спираль.

Некоторый код для иллюстрации идеи.

import numpy as np
from matplotlib import pyplot as plt
import imageio

fig, ax = plt.subplots()

img = imageio.imread('spiral_follow.jpg')
# the image extent is set using trial and error to align with the spiral equation;
# the center of the spiral should end up with coordinates 0,0
x0, x1, y0, y1 = extent = [-17.8, 16, 13, -16.8]
ax.imshow(img, extent=extent)

# t=17.4 is about where the spiral ends; the exact value is not important
t = np.linspace(0, 17.4, 1000) 
r = t
theta = t
sx = r * np.sin(theta)
sy = r * np.cos(theta)

ax.plot(sx, sy, c='lime', lw=6, alpha=0.4) # plot the spiral over the image

# r_p and theta_p are the polar coordinates of the white pixels
r_p = []
theta_p = []
for i in range(img.shape[0]):
    for j in range(img.shape[1]):
        if img[i,j] > 127: # the black pixels are 0, the white are 255; 127 is the middle
            # transform from pixel coordinates (i,j) to the coordinatets of the spiral (x,y)
            x = x0 + j * (x1 - x0) / (img.shape[1] - 1)
            y = y1 + i * (y0 - y1) / (img.shape[0] - 1)
            # transform from carthesian (x,y) to polar coordinates (theta,r)
            theta = np.arctan2(x, y)
            r = np.sqrt(x*x+y*y)
            # the following code tries to find out how many times 2pi should be added to theta
            #   in order to correspond best to r
            k = np.round((r - theta) / (2 * np.pi))
            nearest_theta = theta + 2 * k * np.pi
            theta_p.append(nearest_theta)
            r_p.append(nearest_theta - r)
plt.show()

fig, ax = plt.subplots()
ax.set_facecolor('black')
ax.scatter(theta_p, r_p, s=1, lw=0, color='white')
plt.show()

Выровненная спираль:

aligned spiral

Выпрямленная спираль:

straightened spiral

...