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:
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:
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
Post a Comment