我正在尝试使用python改编Hough变换;在这种情况下,我需要寻找一个霍夫变换来检测正弦波。物镜曲线的形状为:y = amp * sin(ω+ɸ)+ y0。其中:amp =幅度,ω=频率(常数= 1(一个周期)),(ɸ)theta =相位,y0 =偏移量。
目标图片的长度为360像素,高度为300像素(附加示例) 目的是生成最佳[amp,theta,y0]的np阵列作为输出,然后将其绘制在原始图像上。 任何帮助都非常感谢 enter image description here
我不知道到目前为止我的代码出了什么问题,但是结果很糟糕。 这些是我的逐步代码:
# 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()