私は dicom 開発グループの初心者です。dicom image にローカライザー イメージ行を作成する必要があります。それで、何か良いアイデアはありますか?すべてのオタク。
1 に答える
David Brabant は、すでに正しい方向に導いてくれました (DICOM を使用したい場合は、必ずdclunie の医用画像に関する FAQを読んで大切にしてください)。詳しく説明して、実装を簡単にすることができるかどうか見てみましょう.
DICOM ファイル (Offis の DCMTK?) からタグを抽出するためのツール/ライブラリがあると思います。例示のために、ローカライザー ラインを表示する CT スキャン (多数のスライス、つまり多数の画像) とスカウト画像を参照します。CT スライスとスカウトを含む各 DICOM 画像には、空間内の位置に関する完全な情報が次の 2 つのタグに含まれています。
Group,Elem VR Value Name of the tag --------------------------------------------------------------------- (0020,0032) DS [-249.51172\-417.51172\-821] # ImagePositionPatient X0 Y0 Z0 (0020,0037) DS [1\0\0\0\1\0] # ImageOrientationPatient A B C D E F
ImagePositionPatient は、(x,y,z) として表される、送信された最初のピクセル (左上隅のピクセル) の mm 単位のグローバル座標を持ちます。私はそれらをX0、Y0、Z0とマークしました。ImageOrientationPatient には、イメージのピクセルの最初の行とピクセルの最初の列の方向余弦を指定する 2 つのベクトル (どちらも 3 つのコンポーネント) が含まれます。方向余弦を理解することは問題ありませんが (たとえばhttp://mathworld.wolfram.com/DirectionCosine.htmlを参照)、dclunie によって提案された方法はそれらと直接連携します。イメージ プレーン。数式を簡単にするために AF とマークしました。
さて、dclunie によって提供されたコード (C を意図していると思いますが、Java、C#、awk、Vala、Octave などと同様に機能するはずの非常に単純なものです) の規則は次のとおりです。
scr_* = ソース画像、つまり CT スライスを参照します。
dst_* = 宛先イメージ、つまりスカウトを参照します
*_pos_x、*_pos_y、*_pos_z = 上記の X0、Y0、Z0
*_row_dircos_x, *_row_dircos_y, *_row_dircos_z = 上記の A、B、C
*_col_dircos_x, *_col_dircos_y, *_col_dircos_z = 上記の D、E、F
適切な値を設定したら、これらを適用します。
dst_nrm_dircos_x = dst_row_dircos_y * dst_col_dircos_z
- dst_row_dircos_z * dst_col_dircos_y;
dst_nrm_dircos_y = dst_row_dircos_z * dst_col_dircos_x
- dst_row_dircos_x * dst_col_dircos_z;
dst_nrm_dircos_z = dst_row_dircos_x * dst_col_dircos_y
- dst_row_dircos_y * dst_col_dircos_x;
src_pos_x -= dst_pos_x;
src_pos_y -= dst_pos_y;
src_pos_z -= dst_pos_z;
dst_pos_x = dst_row_dircos_x * src_pos_x
+ dst_row_dircos_y * src_pos_y
+ dst_row_dircos_z * src_pos_z;
dst_pos_y = dst_col_dircos_x * src_pos_x
+ dst_col_dircos_y * src_pos_y
+ dst_col_dircos_z * src_pos_z;
dst_pos_z = dst_nrm_dircos_x * src_pos_x
+ dst_nrm_dircos_y * src_pos_y
+ dst_nrm_dircos_z * src_pos_z;
または、ファンシーな行列クラスがある場合は、この行列を作成して、点座標で乗算することができます。
[ dst_row_dircos_x dst_row_dircos_y dst_row_dircos_z -dst_pos_x ] M = [ dst_col_dircos_x dst_col_dircos_y dst_col_dircos_z -dst_pos_y ] [ dst_nrm_dircos_x dst_nrm_dircos_y dst_nrm_dircos_z -dst_pos_z ] [ 0 0 0 1 ]
それは次のようになります。
Scout_Point(x,y,z,1) = M * CT_Point(x,y,z,1)
とはいえ、スカウトに線を作成するには、CT のどのポイントを変換すればよいでしょうか? また、この dclunie については、すでに一般的な解決策を提案しています。
「私のアプローチは、ソース画像のバウンディング ボックスである正方形を投影することです (つまり、スライスの TLHC、TRHC、BRHC、および BLHC を結ぶ線)。」
CT スライスの 4 つの角の点を投影すると、スカウトに垂直な CT スライスの線と、垂直でないスライスの場合の台形ができます。ここで、CT スライスが座標軸に合わせられている場合 (つまり、ImageOrientationPatient = [1\0\0\0\1\0])、4 つの点は自明です。行/列の数と x/y 方向に沿ったピクセル距離を使用して、イメージの幅/高さを mm 単位で計算し、適切に合計します。一般的なケースを実装したい場合は、少し三角法が必要です...または必要ないかもしれません。方向余弦の定義をまだ読んでいない場合は、読むときが来たのかもしれません。
私はあなたを軌道に乗せようとします。たとえば、TRHC で作業すると、ボクセルがイメージ プレーンのどこにあるかがわかります。
# Pixel location of the TRHC x_pixel = number_of_columns-1 # Counting from 0 y_pixel = 0 z_pixel = 0 # We're on a plane!
DICOM のピクセル距離値はイメージ プレーンを参照するため、x と y にこれらの値を乗算するだけで、それらの位置を mm 単位で取得できますが、z は 0 (ピクセルと mm の両方) です。私はこれらの価値について話している:
(0028,0011) US 512 # 2, 1 Columns (0028,0010) US 512 # 2, 1 Rows (0028,0030) DS [0.9765625\0.9765625] # 20, 2 PixelSpacing
上記の行列 M は、グローバル座標から画像座標への一般的な変換であり、方向余弦が利用可能です。ここで必要なのは、逆の仕事 (イメージからグローバル) とソース イメージ (CT スライス) を行うものです。確かに幾何学の本を掘り下げてみましょうが、次のようにする必要があると思います (回転部分は転置され、変換には符号の変化はなく、もちろん src_* 値を使用します):
[src_row_dircos_x src_col_dircos_x src_nrm_dircos_x src_pos_x ] M2 = [src_row_dircos_y src_col_dircos_y src_nrm_dircos_y src_pos_y ] [src_row_dircos_z src_col_dircos_z src_nrm_dircos_z src_pos_z ] [0 0 0 1 ]
CT スライスの点 (例: 四隅) をミリメートルに変換し、M2 を適用してそれらをグローバル座標に配置します。次に、dclunie によって報告された手順にそれらを供給することができます。患者の診断などに使用する前に、数学をクロスチェックしてください。;-)
これがより良いdclunieの方法を理解するのに役立つことを願っています. 乾杯