1. 程式人生 > >關於dicom引數資訊和資料讀寫的理解

關於dicom引數資訊和資料讀寫的理解

1. 資料位儲存(DCM_BitsStored)、資料位分配(DCM_BitsAllocated)、資料符號型別(DCM_PixelRepresentation)、灰度偏移(DCM_RescaleIntercept) 和資料值(DCM_PixelData)本身的關係:

    (1) DCM_BitsAllocated是給每個畫素分配的位元組數對應的位數,如單位元組就是8,兩位元組就是16.......,把dicom資料讀出來存到計算機記憶體最好就用相應的DCM_BitsAllocated資料型別,如DCM_BitsAllocated=16的時候,用short或者unsigned short型別;

    (2) DCM_PixelRepresentation是資料的儲存型別,0代表無符號儲存,1代表有符號儲存;

    (3) 在dicom檔案裡,DCM_BitsStored是DCM_BitsAllocated中的有效儲存位。如果DCM_PixelRepresentation=1(有符號儲存),那麼DCM_BitsStored的DCM_HighBit位為符號位,比如DCM_BitsStored=12並且DCM_HighBit=11的時候,表示有效儲存位(DCM_BitsStored)中的最高位為符號位,此時資料表示範圍為-2048(即2^11) ~ 2043(即2^11-1);

    (4) DCM_RescaleIntercept用於得到輸出灰度值,也就是每個畫素的DCM_PixelData值加上DCM_RescaleIntercept得到的結果。如一張影象上一個畫素點灰度為1024,偏移DCM_RescaleIntercept=-1024,那麼該畫素對應輸出1024+(-1024)=0;

    (5) 由(3)和(4)可知,影象儲存的有符號或者無符號不能決定影象的輸出灰度的正負,而是由DCM_RescaleIntercept與DCM_PixelData的相加的結果決定。比如無符號儲存的影象,某一畫素灰度為255,但是偏移DCM_RescaleIntercept=-1024,那麼輸出灰度=255-1024=-769.

    (6) 由(3)和(4)可知影象的輸出灰度的資料型別與分配的位寬不一定一致,比如DCM_BitsAllocated=8,最大表示灰度255, 如果偏移為-2048,那麼輸出灰度為1793,必須要用short型別才能儲存。

2. 對於使用dcmtk對dicom的標籤讀寫有效性問題

    (1) 如果是能夠明確用某一資料型別,使用特定資料型別來讀寫,比如影象的行列都是無符號整型的,他們的讀寫都可用putAndInsertUint16

//寬
delete dataset->remove(DCM_Rows);
dataset->putAndInsertUint16(DCM_Rows,row);  
//高
delete dataset->remove(DCM_Columns);
dataset->putAndInsertUint16(DCM_Columns,col); 

     (2)如果是不能明確資料型別的,但不是影象畫素資料,如DCM_RescaleIntercept對應的資料不確定是float,double還是int,可用putAndInsertString:

//灰度偏移
delete dataset->remove(DCM_RescaleIntercept);
sprintf_s(buf,"%f",rescaleIntercept);
dataset->putAndInsertString(DCM_RescaleIntercept,buf);

      (3)對於影象畫素資料的讀寫,建議一律使用putAndInsertUint8Array,比如:

case BIT_STORED8S:
delete dataset->remove(DCM_PixelData);
dataset->putAndInsertUint8Array(DCM_PixelData,(unsigned char*)pData,isize);
break;
case BIT_STORED8U:
delete dataset->remove(DCM_PixelData);
dataset->putAndInsertUint8Array(DCM_PixelData,(unsigned char*)pData,isize); 
break;
case BIT_STORED16S:
delete dataset->remove(DCM_PixelData);
dataset->putAndInsertUint8Array(DCM_PixelData,(unsigned char*)pData,isize*2);
break;
case BIT_STORED16U:
delete dataset->remove(DCM_PixelData);
dataset->putAndInsertUint8Array(DCM_PixelData,(unsigned char*)pData,isize*2);
break;
case BIT_STORED32S:
delete dataset->remove(DCM_PixelData);
dataset->putAndInsertUint8Array(DCM_PixelData,(unsigned char*)pData,isize*4);  //todo_20150721
break;
case BIT_STORED32U:
delete dataset->remove(DCM_PixelData);
dataset->putAndInsertUint8Array(DCM_PixelData,(unsigned char*)pData,isize*4);   //todo_20150721
break;