编辑:我找到了解决方案:D感谢您的帮助。
我创建了一个图像处理算法,从数据中提取该图像。它很复杂,所以我不会详细说明,但这个图像本质上是一个巨大的numpy数组(它可视化对象像素强度的角度依赖性)。
我想写一个自动确定曲线何时切换方向的程序。我有数据,我也有这个图像,但事实证明做一些有意义的事情要么很棘手。阈值处理失败,因为存在不同背景颜色的条带。由于同样的原因,Sobel算子和Hough变换也不能很好地工作。
人们很容易看到这种切换何时发生,但不容易告诉计算机。有小费吗?谢谢!
编辑:谢谢大家,我现在在使用结果的一般高斯和骨架化进行卷积后,将线条拟合到此图像。关于这样做的任何指示将不胜感激:)
答案 0 :(得分:3)
您可以采用连续列的加权点积来获得更容易使用的一维信号。您可以使用此信号提取模式:
import numpy as np
A = np.loadtxt("img.txt")
N = A.shape[0]
L = np.logspace(1,2,N)
X = []
for c0,c1 in zip(A.T, A.T[1:]):
x = c0.dot(c1*L) / (np.linalg.norm(c0)*np.linalg.norm(c1))
X.append(x)
X = np.array(X)
import pylab as plt
plt.matshow(A,alpha=.5)
plt.plot(X*3-X.mean(),'k',lw=2)
plt.axis('tight')
plt.show()
这绝对不是这个问题的完整答案,而是一个有用的观察,对评论来说太长了。如果有更好的答案,我会删除。
答案 1 :(得分:2)
在Mark McCurry的帮助下,我取得了不错的成绩。
步骤1:加载原始图像。通过从自身中减去每个垂直列的中位数来删除背景。
no_background=[]
for i in range(num_frames):
no_background.append(orig[:,i]-np.median(orig,1))
no_background=np.array(no_background).T
步骤2:将负值更改为0。
clipped_background = no_background.clip(min=0)
步骤3:提取1D信号。取垂直列的加权和,它将列中的最大强度与其位置相关联。
def exp_func(x):
return np.dot(np.arange(len(x)), np.power(x, 10))/(np.sum(np.power(x, 10)))
weighted_sum = np.apply_along_axis(exp_func,0, clipped_background)
步骤4:获取1D信号的导数。
conv = np.convolve([-1.,1],weighted_sum, mode='same')
pl.plot(conv)
步骤5:确定衍生物何时改变符号。
signs=np.sign(conv)
pl.plot(signs)
pl.ylim(-1.2,1.2)
步骤6:将中值滤波器应用于上述信号。
filtered_signs=median_filter(signs, 5) #pick window size based on result. second arg and odd number.
pl.plot(filtered_signs)
pl.ylim(-1.2,1.2)
步骤7:找到符号切换时的索引(帧位置)。绘制结果。
def sign_switch(oneDarray):
inds=[]
for ind in range(len(oneDarray)-1):
if (oneDarray[ind]<0 and oneDarray[ind+1]>0) or (oneDarray[ind]>0 and oneDarray[ind+1]<0):
inds.append(ind)
return np.array(inds)
switched_frames = sign_switch(filtered_signs)
答案 2 :(得分:0)
对于探测尖端位置或转折点,您可以尝试在原始图像上使用角点检测器(而不是骨架图像)。作为角点检测器,结构张量可以适用。结构张量对于计算图像中的局部方向也很有用。