6

我有一堆像这样的图像:

在此处输入图像描述

没有相应的数据。我需要在蓝色曲线上自动检索大约 100 个点(通常为 x 间距)。所有曲线都非常相似,所以我需要至少 1 个像素精度,但最好使用子像素。好消息是所有曲线都从 0,0 开始到 1,1 结束,所以我们可能会忘记网格。

关于 Python 库的任何提示可以提供帮助或任何其他方法?谢谢 !

4

2 回答 2

6

我将您的图像保存到文件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 左右的函数中。

可以通过在每列左右拟合高斯来提高精度。如果你真的需要它,请告诉我。

于 2013-01-04T10:17:27.113 回答
1

首先,通过阅读图像

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 比我快(至少在这里),但我的答案具有亚像素精度,而且我提取蓝色曲线的方式可能更容易理解。

于 2013-01-04T13:23:28.220 回答