📄 dicomviewerimage__define.pro
字号:
4: type = 13-10*self.pixelrep ; unsigned or signed long
else: type = 1 ; default to byte
endcase
; Convert datatype if needed, otherwise just reform
if (type ne size(data,/TYPE)) then begin
ok = dialog_message('Unexpected data type. Will try converting to integer.')
data = fix(temporary(data),0,dims,TYPE=type)
endif else begin
pdims = product(dims,/INTEGER)
if n_elements(data) gt pdims then data = data[0:pdims-1]
if n_elements(data) lt pdims then return
data=reform(data,dims,/OVERWRITE)
endelse
case strlowcase(strtrim(self.photo,2)) of
'monochrome1': begin
p = 255b - bindgen(256)
self -> setproperty, $
palette = obj_new('idlgrpalette', p,p,p)
end
'palette color': begin
redinfo = o->GetValueDefault('0028,1101',[0,0,0])
greinfo = o->GetValueDefault('0028,1102',[0,0,0])
bluinfo = o->GetValueDefault('0028,1103',[0,0,0])
red = o->GetValueDefault('0028,1201',-1)
gre = o->GetValueDefault('0028,1202',-1)
blu = o->GetValueDefault('0028,1203',-1)
IF (redinfo[1] EQ 0) THEN BEGIN
red = UINT(red)
gre = UINT(gre)
blu = UINT(blu)
ENDIF
self.bitsalloc = redinfo[2]
paloffset = fix(redinfo[1],TYPE=2+10*(~self.pixelrep))
if (self.bitsalloc eq 8) then begin ;; 8 bits per channel
if (redinfo[0] eq 0) then ncolors=65536 else ncolors=uint(redinfo[0])
if ncolors ne n_elements(red) then $
ok = dialog_message('Tag inconsitency: 0028,1101 vs. 0028,1201')
if ncolors le 256 then begin ;; if 256 or less colors and 8 bits per channel, then use palette
pal = obj_new('IDLgrPalette',red_values=red, green_values=gre, blue_values=blu)
self->SetProperty, PALETTE=pal
;; subtract offset and convert to byte
data = byte(((temporary(data)>paloffset)<(paloffset+255b))-paloffset)
endif else begin ;; more than 256 colors, use 24-bit TrueColor
data = ((temporary(data)>paloffset)<(paloffset+255b))-paloffset
dims[0] = 3
newdata = bytarr(dims)
newdata[0,0,0,0]=red[data]
newdata[1,0,0,0]=gre[data]
newdata[2,0,0,0]=blu[data]
data = temporary(newdata)
endelse
endif else begin ;; 16 bits per channel
;; convert to 48-bit TrueColor here
self.bitsAlloc = 16
dims[0] = 3
newdata = MAKE_ARRAY(dims, TYPE=SIZE(red, /TYPE))
newdata[0,0,0,0] = red[data]
newdata[1,0,0,0] = gre[data]
newdata[2,0,0,0] = blu[temporary(data)]
data = temporary(newdata)
endelse
end
else: $
self->setproperty, palette=obj_new()
endcase
; Adjust widow level
if (self.win_dcm[1] eq 0) then self.win_dcm = (max(data,min=mini)+[mini,-mini])/2 $
else self.win_dcm = self.win_dcm/self.rescale[1]-[self.rescale[0],0]
*self.orig = temporary(data)
if (self.bitsalloc eq 16) then self->DefaultWL
self->SetProperty, FRAME=0
end
;----------------------------------------------------------------------
; DicomViewerImage::DefaultWL
;+
; Set the image to the default window level.
;-
pro DicomViewerImage::DefaultWL
compile_opt idl2
if self.wl_type then self.win_level=self.win_dcm $
else if ptr_valid(self.orig) then begin
mini = min(*self.orig,max=maxi)
self.win_level = [DOUBLE(maxi)+mini,maxi-mini]/2
endif else self.win_level = [32768*(~self.pixelrep),32768]
end
;----------------------------------------------------------------------
; DicomViewerImage::GetProperty
;+
; Return the current value of an object property.
;
; @keyword COLS {out}{type=integer} Image columns.
; @keyword ROWS {out}{type=integer} Image rows.
; @keyword SAMPLES {out}{type=integer} Samples (planes) per pixel.
; @keyword NFRAMES {out}{type=integer} Frames in the image.
; @keyword BITSALLOC {out}{type=integer} Bits allocated per pixel.
; @keyword PIXELREP {out}{type=integer} Pixel representation.
; @keyword PHOTO {out}{type=string} Photometric interpretation.
; @keyword CURRENTFRAME {out}{type=integer} Currently displayed image frame.
; @keyword _REF_EXTRA {out}{type=any} Properties passed to the superclass.
;-
pro DicomViewerImage::GetProperty, $
cols=cols, $
rows=rows, $
samples=samples, $
nframes=nframes, $
bitsalloc=bitsalloc, $
pixelrep=pixelrep, $
photo=photo, $
currentframe=currentframe, $
_ref_extra=extra
; Properties of this class.
if arg_present(cols) then cols = self.cols
if arg_present(rows) then rows = self.rows
if arg_present(samples) then samples = self.samples
if arg_present(nframes) then nframes = self.nframes
if arg_present(currentframe) then currentframe = self.currentframe
if arg_present(bitsalloc) then bitsalloc = self.bitsalloc
if arg_present(pixelrep) then pixelrep = self.pixelrep
if arg_present(photo) then photo = self.photo
; Get any requested property of the superclass.
self->IDLgrImage::GetProperty, _EXTRA=extra
end
;----------------------------------------------------------------------
; DicomViewerImage::SetProperty
;+
; Set the current value of an object property.
;
; @keyword COLS {in}{type=integer} Image columns.
; @keyword ROWS {in}{type=integer} Image rows.
; @keyword SAMPLES {in}{type=integer} Samples (planes) per pixel.
; @keyword NFRAMES {in}{type=integer} Frames in the image.
; @keyword BITSALLOC {in}{type=integer} Bits allocated per pixel.
; @keyword PIXELREP {in}{type=integer} Pixel representation.
; @keyword PHOTO {in}{type=string} Photometric interpretation.
; @keyword DATA {in}{type=matrix} Image data.
; @keyword FRAME {in}{type=integer} Frame number.
; @keyword WL_TYPE {in}{type=integer} Window level type.
; @keyword _REF_EXTRA {in}{type=any} Properties passed from the superclass.
;-
pro DicomViewerImage::SetProperty, $
cols=cols, $
rows=rows, $
samples=samples, $
nframes=nframes, $
bitsalloc=bitsalloc, $
pixelrep=pixelrep, $
photo=photo, $
data=data, $
frame=frame, $
wl_type=wl_type, $
_ref_extra=extra
compile_opt logical_predicate
; Set superclass properties, if any.
self->IDLgrImage::SetProperty, _extra=extra
; This class properties.
if size(wl_type,/TYPE) then self.wl_type = wl_type
if size(cols,/TYPE) then self.cols = cols
if size(rows,/TYPE) then self.rows = rows
if size(samples,/TYPE) then self.samples = samples
if size(nframes,/TYPE) then self.nframes = nframes
if size(bitsalloc,/TYPE) then self.bitsalloc = bitsalloc
if size(pixelrep,/TYPE) then self.pixelrep = pixelrep
if size(photo,/TYPE) then self.photo = photo
if size(frame,/TYPE) && ptr_valid(self.orig) then begin
dims = size(*self.orig,/DIMENSIONS)
case n_elements(dims) of
2: data = *self.orig
3: data = *self.orig
4: data = reform((*self.orig)[*,*,*,frame])
else: print, dims
endcase
endif
dtype = size(data,/TYPE)
if dtype then begin
if (self.bitsalloc eq 16) then begin
;; determine the integer range
range = [0d0,65536d0]-self.pixelrep*32768d0
;; bytscl min and max, clip to range
minmax = fix(((self.win_level[0]+self.win_level[1]*[-1,1])>range[0])<range[1], TYPE=dtype)
if ~strcmp(self.photo,'monochrome1',11,/FOLD_CASE) then $
self->IDLgrImage::SetProperty, DATA=bytscl(data, MIN=minmax[0], MAX=minmax[1]) $
else $
self->IDLgrImage::SetProperty, DATA= not bytscl(data, MIN=minmax[0], MAX=minmax[1])
endif else self->IDLgrImage::SetProperty, DATA=data
endif
end
;----------------------------------------------------------------------
; DicomViewerImage__define
;+
; Define the class.
;-
pro DicomViewerImage__define
compile_opt idl2
s = {DicomViewerImage, $
inherits IDLgrImage, $
cols:0, $ ; number of columns
rows:0, $ ; number of rows
samples:0, $ ; number of samples (planes)
nframes:0, $ ; number of frames in the image
photo:'', $ ; photometric interpretation
bitsalloc:0, $ ; number of bits allocated per pixel
pixelrep:0, $ ; pixel representation (signed or unsigned data)
planar:0, $ ; boolean if data has multiple planes
win_dcm: dblarr(2), $ ; default DICOM window level and width
win_level: dblarr(2), $ ; current window level and width
rescale: dblarr(2), $ ; rescale slope and intercept (eg, to Hounsfield units for CT)
scale: dblarr(2), $ ; image scale
orig:ptr_new(), $ ; original DICOM image data
currentframe:0, $ ; currently displayed frame
wl_type:0} ; boolean, use DICOM if true or current window level
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -