DICOM ファイルを TIFF に変換(改訂版)

2017-11-10 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
先日(2017-10-16)の記事「DICOM ファイルを TIFF に変換」では、
.nii ファイルを経由せずに、
.dcm ファイルから 直接 TIFF ファイルに変換する
プログラム“DICOM_to_TIFF.gsl”を作った。

しかし、
新たな .dcm ファイルを入手したが、
対応できないモノだった。

更なる DICOM ファイルの仕様を解読し、
何とか読み込めるメドついた。

ポイントは、前回コードの
変数 g で表しているコード値が 2 以外の時でも
変数 vr で表しているタイプが指定されているモノでした。

これに対応した処理方式と、以前のデータに対する処理方式を
併せて、キモチ汎用版を作った。

プログラム名を“DICOM_to_TIFF_Rev.gsl”とした:
----- DICOM_to_TIFF_Rev.gsl -----
require'pl'; require'cv2_a'; SF = string.format
uint16 = |x| ffi.cast( 'uint16_t*', x )
uint32 = |x| ffi.cast( 'uint32_t*', x )

ReadUInt16 = || uint16( IN:read(2) )[0]
ReadUInt32 = || uint32( IN:read(4) )[0]
ReadChars = |n| IN:read(n)

Fname = 'x.dcm'; IN = io.open( Fname, 'rb' ) -- サンプルデータ --

-- 先頭 128 バイトは Preamble ( all ゼロ )
-- 次の4バイトは:'DICM'

zzz = IN:read(128); fid = IN:read(4)
if fid ~= 'DICM' then
print( 'Not a DICM' ); _=io.read(1); os.exit()
end

g = ReadUInt16()
------- g の判定は、以下のループの中に纏めた。
while g==2 or g==8 or g==16 or g==24 or g==32 or
g==40 or g==64 or g==0x7005 or g==0x7FE0 do
e = ReadUInt16();
vr = ReadChars(2)
if vr == 'AE' or vr == 'AS' or vr == 'AT' or vr == 'CS' or
vr == 'DA' or vr == 'DS' or vr == 'DT' or vr == 'FL' or
vr == 'FD' or vr == 'IS' or vr == 'LO' or vr == 'PN' or
vr == 'SH' or vr == 'SL' or vr == 'SS' or vr == 'ST' or
vr == 'TM' or vr == 'UI' or vr == 'UL' or vr == 'US'
then
length = ReadUInt16()
else
_tmp = ReadUInt16() -- Read the reserved byte
if string.sub(vr,1,1) == 'O' then -- g==2 の'OB' と、0x7FE の'OW'
length = ReadUInt32()
else
length = ffi.cast('uint16_t*',vr)[0] + _tmp*256*256 -- *****
end
end
----- print( g, e, vr, length, SF('%X',IN:seek()) ) -- デバッグ用

if g==0x7FE0 then break end
val = ReadChars(length)
---------------------------
if g==40 then
if e==0x0010 then yy = uint16(val)[0] end
if e==0x0011 then xx = uint16(val)[0] end
if e==0x0100 then bpp= uint16(val)[0] end
end
---------------------------
g = ReadUInt16()
end

if bpp ~= 16 then print( 'Not 16bits' ); _=io.read(1); os.exit() end

AT = uint16( IN:read('*a') ) -- Read '*a' == length == xx*yy*2
IN:close()

------------------------------
tif = cv2.cvCreateMat( yy, xx, CV_16UC1 )
BT = ffi.cast( 'uint16_t*', tif.Byte )

for n=0,xx*yy-1 do
if AT[0]>32767 then
BT[n] = AT[n] + 0x8000 --========
else
BT[n] = AT[n]
end
end

if string.find( Fname, 'dcm' ) ~= nil then
FN = string.gsub( Fname, '.dcm', '.tif' )
else
FN = Fname..'.tif'
end
cv2.cvSaveImage( 'o-'..FN , tif, 0 )
これで、?????

これで、
.dcmファイルを 16 bit TIFFファイルに変換できた。
前回のものよりキモチ汎用で。


本日はここまで。


DICOM 学習は続く?


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


171018
関連記事
スポンサーサイト

コメントの投稿

管理者にだけ表示を許可する

おきてがみ/blogram
blogram投票ボタン



おきてがみ

最新記事
カレンダー
10 | 2017/11 | 12
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -
月別アーカイブ
カテゴリ
最新コメント
検索フォーム
リンク
プロフィール

<紙>

Author:<紙>
ようこそ。
「パソコンヲタクの雑記帳」
もろもろなことを綴っています。
パソコン ヲタクってねくら?
画像は kami でなく kani です。

カウンター(fc2、i2i) /Google Analytics


i2i(from 2010-08-24)
Total =
Today  =  
Yesterday=
アンチエイジング

Google Analytics
ブックマーク