GC または HPLC のクロマトグラムから情報を抽出する方法を探しています。クロマトグラムは次のようになります。
私は画像処理/分析にあまり興味がないので、これらのクロマトグラムからピークの長さ (および可能であればピークの下の表面) を抽出するツール/アルゴリズムを探しています。ソリューションは、Python または C# で作成できます。
前もって感謝します。
画像ファイルからクロマトグラム (または任意の単一値) データを抽出する簡単な Python コードを作成しました。
次の要件があります。
これは非常に単純で、画像の各列を繰り返し処理し、最初の黒の値をデータ ポイントとして取得するだけです。PILを使用します。これらのデータ ポイントは最初はimage
座標系にあるため、データ座標系に再スケーリングする必要があります。すべての画像が同じ軸を共有している場合、これは簡単です。それ以外の場合は、画像ごとに手動で行う必要があります。基礎(自動化はより複雑になります)。
以下の画像は、処理のために画像を抽出した場所 (テキストを削除した場所)を示しています (ピンク以外のx_range = 4.4 - 0.55
領域x_offset = 0.55
) 。y_range = 23000 - 2500
y_offset = 2500
pyplot で再プロットされた抽出データは次のとおりです。
コードは次のとおりです。
import Image
import numpy as np
def get_data(im, x_range, x_offset, y_range, y_offset):
x_data = np.array([])
y_data = np.array([])
width, height = im.size
im = im.convert('1')
for x in xrange(width):
for y in xrange(height):
if im.getpixel((x, y)) == 0:
x_data = np.append(x_data, x)
y_data = np.append(y_data, height - y)
break
x_data = (x_data / width) * x_range + x_offset
y_data = (y_data / height) * y_range + y_offset
return x_data, y_data
im = Image.open('clean_data_2.png')
x_data, y_data = get_data(im,4.4-0.55,0.55,23000-2500,2500)
from pylab import *
plot(x_data, y_data)
grid(True)
savefig('new_data.png')
show()
データを numpy 配列として取得したら、ピークとその下の対応する領域を見つけるために使用できる多くのオプションがあります (いくつかのアプローチについては、このディスカッションを参照してください)。ノイズは大きな懸念事項であるため、一般的なアプローチは、データを畳み込んでノイズを滑らかにし (または、ピークが鋭い場合はしきい値を設定できます)、微分してピークを見つけることです。ピークの下の領域を見つけるには、ピーク領域全体で数値積分を行うことができます。
考えられるアプローチを説明するために、いくつかの仮定を立て、いくつかの簡単なコード (以下) を書きました。5000 を超えるピークのみが生き残るようにデータのしきい値を設定しました。次に、データを繰り返し処理してピークを見つけ、トラピーズ ルールを使用して、np.trapz
各ピークの下の領域を見つけます。ピークがオーバーラップする場所では、領域がオーバーラップ ポイントで分割されます (これが標準であるとは思えません..)。また、このコードは局所的な最大値であるピークのみを認識します (ショルダーは検出されません)。結果をグラフ化し、対応するピーク位置で各ピークの面積値を書きました。
def find_peak(start, grad):
for index, gr in enumerate(grad[start:]):
if gr < 0:
return index + start
def find_end(peak, grad):
for index, gr in enumerate(grad[peak:]):
if gr >= 0:
return index + peak + 1
def find_peaks(grad):
peaks=[]
i = 0
while i < len(grad[:-1]):
if grad[i] > 0:
start = i
peak_index = find_peak(start, grad)
end = find_end(peak_index, grad)
area = np.trapz(y_data[start:end], x_data[start:end])
peaks.append((x_data[peak_index], y_data[peak_index], area))
i = end - 1
else:
i+=1
return peaks
y_data = np.where(y_data > 5000, y_data, 0)
grad = np.diff(y_data)
peaks = find_peaks(grad)
from pylab import *
plot(x_data, y_data)
for peak in peaks:
text(peak[0], 1.01*peak[1], '%d'%int(peak[2]))
grid(True)
show()
この時点でどのようなアプローチを取るにしても、データに関する仮定が必要になります (これを行う立場にあるわけではありません! 上でいくつか作成しましたが!)。など..クロマトグラフィーには標準的なアプローチがあると確信しているので、最初にそれを確認する必要があります. お役に立てれば!
このコードを使用すると、次の画像が表示されます
コードは上記と同じです(わずかな変更があります)
from PIL import Image
import numpy as np
def get_data(im, x_range, x_offset, y_range, y_offset):
x_data = np.array([])
y_data = np.array([])
width, height = im.size
im = im.convert('1')
for x in range(width):
for y in range(height):
if im.getpixel((x, y)) == 0:
x_data = np.append(x_data, x)
y_data = np.append(y_data, height - y)
break
x_data = (x_data / width) * x_range + x_offset
y_data = (y_data / height) * y_range + y_offset
return x_data, y_data
im = Image.open('C:\Python\HPLC.png')
x_data, y_data = get_data(im,4.4-0.55,0.55,23000-2500,2500)
from pylab import *
plot(x_data, y_data)
grid(True)
savefig('new_data.png')
show()
I am not quite sure what the problem might be.