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

2017-11-13 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-11-10)の記事「DICOM ファイルを TIFF に変換(改訂版)」を
書いたばかりだが、
その後に、
更なる新たな .dcm ファイルを入手した。

だが、このファイル形式には
対応できなかった。

データ部分のサイズを指定する、
変数 g で表しているコード値が 0x7FE0 のモノが2つあった。

これの識別は難しいので、

g が 40 で、
e が 0x0010 と 0x0011 の時の val 値から、
データサイズを取得したら、
後は、
ファイルの最後から
データ本体部分を取得すること
にした。

プログラム名を“DICOM_to_TIFF_Rev2.gsl”とした:
----- DICOM_to_TIFF_Rev2.gsl -----
require'pl'; _=path.currentdir()
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' ) -- サンプルデータ --
FSZ = lfs.attributes( Fname, 'size' ) -- ファイルサイズ

-- 先頭 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

----- 「g==0x7FE0」が2つあるので、全体から逆算する:
f_pos=IN:seek()
print( z, xx, yy, bpp, length + f_pos ) -- 進行確認用

nokori = FSZ - f_pos
if nokori > xx*yy*2 then _ = ReadChars( nokori- xx*yy*2 ) 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投票ボタン


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

コメントの投稿

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

おきてがみ/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
ブックマーク