您的位置:首页 > 编程语言 > Delphi

DELPHI 对DICOM中的窗宽、窗位调整

2012-11-21 14:00 295 查看
对16位的影像,要判断DICOM中最大像素值(0028,0107)大于65534,是则将16位影像数据的像素值大于等于0的全部减去65535,小于0的全部加上65535,然后在window-level的方法中将pixel_val按word取值(word是无符号类型,相当于取绝对值)进行判断,然后赋值即可(CT影像不能用word类型取值和赋值),就这么简单,以下是关键代码,祝你愉快!!!

procedure DCM_GetWidAndCenBySmallint(var DICOMDATA: TDICOMDATA; var Buffer: SMallIntp0);

var

Value, Size, i: integer;

min16, max16: integer;

begin

Size := DICOMDATA.ImageColumns * DICOMDATA.ImageRows;

Value := Buffer[0];

max16 := Value;

min16 := Value;

i := 0;

while i < Size do begin

Value := Buffer;

if Value < min16 then min16 := Value;

if Value > max16 then max16 := Value;

i := i + 1;

end;

if DICOMDATA.MaxIntensity = 0 then DICOMDATA.MaxIntensity := max16;

if (DICOMDATA.MaxIntensity > 65534) then begin//这里对高CT值的数据进行处理

i := 0;

while i < (Size) do begin

if Buffer >= 0 then

Buffer := Buffer - 65535

else

Buffer := 65535 + Buffer;

i := i + 1;

end;

end;

DICOMDATA.WinCen := round(DICOMDATA.WindowCenter);

DICOMDATA.WinWid := round(DICOMDATA.WindowWidth);

DICOMDATA.ImgMin := min16;

DICOMDATA.ImgMax := max16;

DICOMDATA.ImgWid := DICOMDATA.ImgMax - DICOMDATA.ImgMin;

DICOMDATA.ImgCen := DICOMDATA.ImgMin + ((DICOMDATA.ImgWid) shr 1);

if DICOMDATA.WindowWidth <= 0 then begin

DICOMDATA.WinCen := DICOMDATA.ImgCen;

DICOMDATA.WinWid := DICOMDATA.ImgWid;

DICOMDATA.WindowCenter := DICOMDATA.ImgCen;

DICOMDATA.WindowWidth := DICOMDATA.ImgWid;

end;

end;

procedure DCM_Scale16to8bit(var DICOMDATA: TDICOMDATA; var Buffer: SMallIntp0; var lOutBuff: pByteArray; DataLen: integer);

var

Value, i, lScaleShl10, Size, lWid, lcen: integer;

min16, max16: integer;

PixelVal: integer;

Modality_CT: boolean;

begin

if Buffer = nil then exit;

//影像是否是CT

if (DICOMDATA.TransferSyntax = '1.2.840.10008.5.1.4.1.1.2') or (trim(DICOMDATA.Modality) = 'CT') then

Modality_CT := true

else

Modality_CT := false;

DICOMDATA.WinCen := round(DICOMDATA.WindowCenter);

DICOMDATA.WinWid := round(DICOMDATA.WindowWidth);

Size := DICOMDATA.ImageColumns * DICOMDATA.ImageRows;

lcen := round((round(DICOMDATA.WindowCenter) - DICOMDATA.IntenIntercept) / DICOMDATA.IntenScale); // 截距/斜率

lWid := (trunc((round(DICOMDATA.WindowWidth) / DICOMDATA.IntenScale) / 2));

min16 := lcen - lWid; //15za

max16 := lcen + lWid; //15za

getmem(lOutBuff, Size);

Size := Size - 1;

Value := (max16 - min16);

if (Value = 0) or (trunc((1024 / Value) * 255) = 0) then begin

if DICOMDATA.WinWid > 1024 then begin

for i := 0 to Size do

lOutBuff := 128;

end else begin

for i := 0 to Size do

if Buffer < DICOMDATA.WinCen then

lOutBuff := 0

else

lOutBuff := 255;

end;

end else begin

if Value = 0 then Value := 1;

lScaleShl10 := trunc((1024 / Value) * 255); //value = range,Scale = 255/range

for i := 0 to Size do begin

//除CT外,其余的全部取正值

if Modality_CT then begin

if (Buffer) < min16 then

lOutBuff := 0

else if (Buffer) > max16 then

lOutBuff := 255

else

lOutBuff := (((Buffer) - min16) * lScaleShl10) shr 10;

end else begin //非CT

if word(Buffer) < min16 then

lOutBuff := 0

else if word(Buffer) > max16 then

lOutBuff := 255

else

lOutBuff := ((word(Buffer) - min16) * lScaleShl10) shr 10;

end;

end;

end;

DICOMDATA.BitsStored := 8; //转换为8位

end;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: