scheme - Simple display of DICOM format file image -


i trying read simple dicom file named "cr-mono1-10-chest" http://www.barre.nom.fr/medical/samples/ 440x440 sized image.

as expained on http://www.dclunie.com/medical-image-faq/html/part1.html , image data @ end of file:

in other words, if image 256 256, uncompressed, , 12-16 bits deep (and hence usually, though not always, stored 2 bytes per pixel), know file going contain 256*256*2=131072 bytes of pixel data @ end of file. if file 145408 bytes long, ge signa 3x/4x files example, need skip 14336 bytes of header before data. presume row row starting top left hand corner raster order, try both alternatives byte order, deal 16 8 bit windowing problem, , have image on screen of workstation.

a figure on http://people.cas.sc.edu/rorden/dicom/index.html shows image data located @ end of file.

i using following code read , display image in file:

(define in (open-input-file "cr-mono1-10-chest" #:mode 'binary)) (define size (* 2 440 440))                        ; width , ht 440 (define ignore (read-bytes (- 387976 size) in))    ; size of file 387976 (define imgdata (read-bytes size in)) (close-input-port in)  (define img (make-object bitmap% imgdata 440 440)) img 

however, shows random mix of black , white pixels:

enter image description here

using 440*440 instead of 2*440*440 not work.

following code not read image:

(define img (make-object bitmap% in 'unknown)) 

this not display image @ all.

where problem , how can solve it?

you calculating image data offset correctly , data appears raw , uncompressed. problem appears racket not support kind of image data. 16-bit, single channel, intensity data. each 2 bytes represents pixel in grayscale (and image 10 bits used, other 6 bits should ignored).

the make-object make-bitmap functions appear support color (24 or 32) or monochrome (1) bit depth. jumps out @ in example: when create bitmap state pixels 16-bit. absent byte order. , in racket documentation appear allows specify either of these.

lack of support 16-bit grayscale data seems evident in get-depth function documentation:

(send a-bitmap get-depth) → exact-nonnegative-integer? gets color depth of bitmap, which 1 monochrome bitmap , 32 color bitmap. see is-color?.

here's 1 solution, looping through , converting each 16-bit pixel argb pixel.

#lang racket/gui (define in (open-input-file "cr-mono1-10-chest" #:mode 'binary)) (define size (* 2 440 440))                        ; width , ht 440 (define ignore (read-bytes (- 387976 size) in))    ; size of file 387976 (define imgdata (read-bytes size in)) (close-input-port in)  (define rgbdata (make-bytes (* 4 440 440))) (define img (make-object bitmap% 440 440))  (define max 1024.0) ; 10 bits valid  (for ([y 440])   (for ([x 440])       (define index (+ (* y 440) x))       (define b1 (bytes-ref imgdata (+ (* index 2) 0))) ; first byte       (define b2 (arithmetic-shift (bytes-ref imgdata (+ (* index 2) 1)) 8)) ; second byte       (define val (bitwise-xor b1 b2)) ; combine bytes       (define screenval (exact-floor (* 255 (/ val max)))) ; convert 8-bit screen value        ; create argb pixel       (define b (bytes (bytes-ref (make-bytes 1 255) 0) (bytes-ref (make-bytes 1 screenval) 0) (bytes-ref (make-bytes 1 screenval) 0) (bytes-ref (make-bytes 1 screenval) 0)))           (send img set-argb-pixels x y 1 1 b)   ))  img 

producing:

enter image description here

a note of caution though: aware there many, many ways image data can stored in dicom files (some examples on page linked). , there many parts of dicom header need pay attention decode image data correctly.


Comments