【转】DELPHI 对DICOM中的窗宽、窗位调整
在寫這篇文章前72小時,我的多窗顯示組件對于個別大W/C值的16位影像顯示還是個問題,也發(fā)了帖子到PACS站詢問過,更是在Google上貓刨了很久,終歸一無所獲,今天靜下心來,用了2小時反復查看程序處理過程,對比數(shù)據(jù),居然就這么搞定了,原來如此簡單,哎,困惑了3天,把答案公布了,也算是助人為樂(中國地大物博,人心應寬廣無量)
 對16位的影像,要判斷DICOM中最大像素值(0028,0107)大于65534,是則將16位影像數(shù)據(jù)的像素值大于等于0的全部減去65535,小于0的全部加上65535,然后在window-level的方法中將pixel_val按word取值(word是無符號類型,相當于取絕對值)進行判斷,然后賦值即可(CT影像不能用word類型取值和賦值),就這么簡單,以下是關(guān)鍵代碼,祝你愉快!!!
?
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值的數(shù)據(jù)進行處理
 ??? 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; //轉(zhuǎn)換為8位
 end;
 ?
總結(jié)
以上是生活随笔為你收集整理的【转】DELPHI 对DICOM中的窗宽、窗位调整的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 兴业PASS信用卡:网上支付笔笔有积分
 - 下一篇: 中信大众点评信用卡额度一般多少