我有這樣一個一堆圖像:圖像分析曲線擬合
相應的數據不可用。我需要在藍色曲線上自動檢索約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左右的函數中。
可以通過在每列左右擬合gaussians來提高精度。如果你真的需要它,告訴我。
我不實用pylab,我可以問你解釋如何'im - = im.mean(axis = 2).reshape(im.shape [0],im.shape [1],1).repeat(3,axis = 2)'line works? –
當然。 imread給了我們一個RGBA圖像,也就是說,我們的數組有形狀(x,y,4),我立即通過丟棄前一行中的alpha([:,:,3])來減少它。 然後我想用紅色=綠色=藍色(從黑色到白色的所有灰色)將所有顏色設置爲黑色,以便只保留藍色線條。 我通過從每個像素中減去R,G和B值的平均值來做到這一點。如果它們相等,則全部變爲零。 '.mean(axis = 2)'計算平均值,製作一個二維數組; '.reshape()'再次使它成爲3d,只需添加一個3. dim的len 1; '.repeat()'將數組的形狀重置爲'im'的形狀 –
首先,經由
from scipy.misc import imread
im = imread("thefile.png")
這給出了與所述第三尺寸的顏色通道(RGB +阿爾法)一個3D numpy的陣列讀出的圖像。曲線在藍色通道中,但網格也在那裏。但在紅色通道中,您擁有網格而不是曲線。所以我們使用
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)
P.S. :Thorsten Kranz比我快(至少在這裏),但我的答案具有亞像素精度,而我提取藍色曲線的方式可能更容易理解。
有趣的問題,我正在研究一個解決方案,但亞像素精度不太可能。 –
只有半自動但仍然相關的問題,這個網絡應用程序可以做的奇蹟:http://arohatgi.info/WebPlotDigitizer/ –