我有一堆像这样的图像:
没有相应的数据。我需要在蓝色曲线上自动检索大约 100 个点(通常为 x 间距)。所有曲线都非常相似,所以我需要至少 1 个像素精度,但最好使用子像素。好消息是所有曲线都从 0,0 开始到 1,1 结束,所以我们可能会忘记网格。
关于 Python 库的任何提示可以提供帮助或任何其他方法?谢谢 !
我有一堆像这样的图像:
没有相应的数据。我需要在蓝色曲线上自动检索大约 100 个点(通常为 x 间距)。所有曲线都非常相似,所以我需要至少 1 个像素精度,但最好使用子像素。好消息是所有曲线都从 0,0 开始到 1,1 结束,所以我们可能会忘记网格。
关于 Python 库的任何提示可以提供帮助或任何其他方法?谢谢 !
我将您的图像保存到文件14154233_input.png
中。那么这个程序
import pylab as plt
import numpy as np
# Read image from disk and filter all grayscale
im = plt.imread("14154233_input.png")[:,:,:3]
im -= im.mean(axis=2).reshape(im.shape[0], im.shape[1], 1).repeat(3,axis=2)
im_maxnorm = im.max(axis=2)
# Find y-position of remaining line
ypos = np.ones((im.shape[1])) * np.nan
for i in range(im_maxnorm.shape[1]):
if im_maxnorm[:,i].max()<0.01:
continue
ypos[i] = np.argmax(im_maxnorm[:,i])
# Pick only values that are set
ys = 1-ypos[np.isfinite(ypos)]
# Normalize to 0,1
ys -= ys.min()
ys /= ys.max()
# Create x values
xs = np.linspace(0,1,ys.shape[0])
# Create plot of both
# read and filtered image and
# data extracted
plt.figure(figsize=(4,8))
plt.subplot(211)
plt.imshow(im_maxnorm)
plt.subplot(212, aspect="equal")
plt.plot(xs,ys)
plt.show()
产生这个情节:
然后,您可以xs
随心所欲ys
地做任何事情。也许你应该把这段代码放在一个返回 xs 和 ys 左右的函数中。
可以通过在每列左右拟合高斯来提高精度。如果你真的需要它,请告诉我。
首先,通过阅读图像
from scipy.misc import imread
im = imread("thefile.png")
这给出了一个 3D numpy 数组,第三维是颜色通道 (RGB+alpha)。曲线在蓝色通道中,但网格也在那里。但在红色通道中,您有网格而不是曲线。所以我们使用
a = im[:,:,2] - im[:,:,0]
现在,我们想要沿着每一列的最大值的位置。具有一个像素精度,它由下式给出
y0 = np.argmax(a, axis=0)
当列中没有蓝色曲线时,即在框架之外,结果为零。On 可以通过
xmin, xmax = np.where(y0>0)[0][[0,-1]
有了这个,您可以重新调整 x 轴。
然后,您需要亚像素分辨率。让我们专注于单个列
f=a[:,x]
我们使用牛顿法的单次迭代来细化极值的位置
y1 = y0 - f'[y]/f''[y]
请注意,由于离散采样,我们无法进一步迭代。尽管如此,我们想要一个很好的导数近似值,因此我们将对两者都使用 5 点方案。
coefprime = np.array([1,-8, 0, 8, -1], float)
coefsec = np.array([-1, 16, -30, 16, -1], float)
y1 = y0 - np.dot(f[y0-2:y0+3], coefprime)/np.dot(f[y0-2:y0+3], coefsec)
PS:Thorsten Kranz 比我快(至少在这里),但我的答案具有亚像素精度,而且我提取蓝色曲线的方式可能更容易理解。