Я пытаюсь адаптировать преобразование Хафа, используя python;в этом случае я ищу преобразование Хафа для обнаружения синусоидальных волн.Кривые объектива имеют вид: y = amp * sin (ω + ɸ) + y0.где: amp = амплитуда, ω = частота (постоянная = 1 (один цикл)), (ɸ) тета = фаза, y0 = смещение.
Длина целевых изображений составляет 360 пикселей, а высота - 300 пикселей (Прикрепленный пример) Цель состоит в том, чтобы генерировать np-массивы наилучших [amp, theta, y0] в качестве выходных данных, а затем вывести их на исходное изображение.Любая помощь очень ценится введите описание изображения здесь
Я не знаю, что не так с кодами, которые у меня есть, но результаты довольно плохие.Вот пошаговые коды, которые у меня есть:
# Import libraries to work
import cv2
import numpy as np
from matplotlib import pyplot as plt
# Reading image & canny for edges
img = cv2.imread('s3.png',0) # "0" For gray scale
edges = cv2.Canny(img, threshold1 = 0, threshold2 = 50, apertureSize = 3)
# Hough Transform for sine detection
# y(x) = amp*sin(wx + theta) + y0 # Target equation
# amp = (y - y0)/sin(wx + theta) # Search equation
# following code is an adaption from:
# http://nabinsharma.wordpress.com/2012/12/26/linear-hough-transform-using-python/
#https://gist.github.com/ilyakava/c2ef8aed4ad510ee3987/6b69a16dba2d97eaa585f35c025dac57ffb58651
def hough_transform(img_bin, theta_res=1, amp_res=1, y0_res=1):
nR,nC = img_bin.shape
theta = np.linspace(0, 360, np.ceil(360/theta_res) + (1.0))
y0 = np.linspace(0, 300, np.ceil(300/y0_res) + (1.0))
amp = np.linspace(0, 300, np.ceil(300/amp_res) + (1.0))
H = np.zeros((len(amp), len(theta), len(y0)))
for rowIdx in range(nR):
for colIdx in range(nC):
if img_bin[rowIdx, colIdx]:
for thIdx in range(len(theta)):
for y0Idx in range(len(y0)):
ampVal = (rowIdx - y0[y0Idx]) / np.sin((colIdx + theta[thIdx]))#*np.pi/180)
ampIdx = np.nonzero(np.abs(amp-ampVal) == np.min(np.abs(amp-ampVal)))
H[ampIdx, thIdx, y0Idx] += 1
return amp, theta, y0, H
amps, thetas, y0s, H = hough_transform(edges)
# Best Amps, Thetas and y0s Selection – From:
#https://gist.github.com/ilyakava/c2ef8aed4ad510ee3987/6b69a16dba2d97eaa585f35c025dac57ffb58651
def top_n_amp_theta_y0(ht_acc_matrix, n, amps, thetas, y0s):
'''
@param hough transform accumulator matrix H (amp by theta by y0s)
@param n of amps, thetas ans y0s desired
@param ordered array of amps represented by rows in H
@param ordered array of thetas represented by columns in H
@param ordered array of y0s represented by deep in H
@return top n amp, theta and y0 in H by accumulator value
@return x,y,z indexes in H of top n amp, theta and y0
'''
flat1 = np.hstack(ht_acc_matrix)
flat2 = np.hstack(flat1)
flat = list(set(flat2))
flat_sorted = sorted(flat, key = lambda n: -n)
coords_sorted = [(np.argwhere(ht_acc_matrix == acc_value)) for acc_value in flat_sorted[0:n]]
amp_theta_y0 = []
x_y_z = []
for coords_for_val_idx in range(0, len(coords_sorted), 1):
coords_for_val = coords_sorted[coords_for_val_idx]
for i in range(0, len(coords_for_val), 1):
n,m,l = coords_for_val[i] # n by m by l matrix
amp = amps[n]
theta = thetas[m]
y0 = y0s[l]
amp_theta_y0.append([amp, theta, y0])
x_y_z.append([m, n, l]) # just to unnest and reorder coords_sorted
return [amp_theta_y0[0:n], x_y_z]
amp_theta_y0, x_y_z = top_n_amp_theta_y0(H, 1000, amps, thetas, y0s)
# From [amp_theta_y0] plot the best values on the original image
x = np.linspace(0, 360, 360)
y = amp1*np.sin((x + theta1*np.pi/180) ) + (y0_1)
q = amp2*np.sin((x + theta2*np.pi/180) ) + (y0_2)
x1, x2 = (0, 360)
y1, y2 = (300, 0)
fig, ax = plt.subplots()
ax.imshow(edges, extent=[x1, x2, y1, y2], aspect='auto', cmap='gray')
ax.plot(x, y, q)
plt.show()