在显示器往往只有 8位(0~255), 而数据有 12~16位。如果将数据的 min 和 max 间 (dynamic range) 的之间转换到 8位的0~255,在这个过程是有损转换,而且出来的图像往往突出的是些噪音。针对这些问题,研究人员先提出一些要求 (requirements),然后根据这些要求提出了一些算法。这些算法现在都很成熟。要求(1):充分利用 0-255 间的显示有效值域;要求(2):尽量减少值域压缩带来的损失;要求(3):不能损失应该突出的组织部分。
窗宽窗位概念
窗技术(Window Technique)是医生用 以观察不同密度正常组织或病变的一种显示技术,其包括窗宽(window width)和窗位(window level)。由于各种不同组织结构或病变具有不同的像素值,因些欲显示某一组织结构细节时,应选择适合观察组织结构的窗宽窗位,以获得显示最佳效果。
窗宽
窗宽是CT/ DR图像上显示的CT/DR值,在此CT/DR值范围内组织和病变均以不同的模拟灰度显示,而CT/DR值高于此范围的组织和病变,无论是高于多少,都均为白影显示,不再有灰度差异,反之,低于此范围的组织,不论是低于多少,均为黑影显示,也无灰度差异。增大窗宽,则图像所示CT/DR值范围加大,显示具有不同密度的组织结构增多,但各结构这间的灰度别减少;减少窗宽,则显示组织结构减少,而各结构这间的灰度别增加。
窗位
窗位是窗的中心位置。同样的窗宽, 由于窗位不同,其包括CT/DR范围的CT/DR值有差异。例如窗宽(w)同为w =60,当窗位为L =0时,其CT/DR值范围为-30~+30;如窗位是+10时,则CT/DR值范围为-20~+40。通常欲观察某一组织的结构及发生的病变,应以该组织的CT/DR值为窗位。
算法分析
1. 16-bit 到 8-bit 直接转换
- ComputeMinValMaxVal(pixel_val, min, max); // 先算图像的最大和最小值
- for (i = 0; i < nNumPixels; i++){
- disp_pixel_val = (pixel_val - min)*255.0/(double)(max - min);
- }
这个算法必须有,对不少种类的图像是很有效的:如 8-bit 图像,MRI, ECT, CR 等等。
2. Window-leveling 算法
W/L 是专门为 CT/DR 设计的。原理很简单:CT/DR 图像里不同组织的密度 (用 Hounsfield 单位) 是在固定的值域, 与具体设备和成像软件没有关系。因此,要看头颅时, 我们只需将头颅的值域转换到 0-255 就行了。CT/DR W/L 不讲头颅值域的 min 和 max, 而说 max - min (即 window_width) 和 (max+min)/2 (即 window_center)。我们还可以用原来的公式,只是 min 和 max 的算法不一样。
- min = (2*window_center - window_width)/2.0 + 0.5;
- max = (2*window_center + window_width)/2.0 + 0.5;
- for (i = 0; i != nNumPixels; i++){
- disp_pixel_val = (pixel_val - min)*255.0/(double)(max - min);
- }
刚刚说的是将 min 和 max 间的数值线性转换到 0-255 之间。 如果 max - min 出来是个很大的数值,比如说 25500, 那就说每 100 原始密度会压缩成一个显示灰度。 这样的损失可能会很大。因为人眼对灰度地反应式是非线性的,非线性转换可以解决一些问题。 常用算法有log和gamma 两种。gamma 比较好调 gamma 值,因此用得比较多。
- for (i = 0; i < nNumPixels; i++){
- disp_pixel_val = 255.0 * pow(pixel_value/(max-min), 1.0/gamma);
- }
1. 在做任何转换时要注意有效灰度域外的数值的处理。
最好先用 int 而非 unsigned char 来算,再转入矩阵,以避免 overflow 和 underflow。
- double dFactor = 255.0/(double)(max - min);
- int nPixelVal;
- for (i = 0; i < nNumPixels; i++){
- nPixelVal = (int) ((pixel_val - min)*dFactor);
- if (nPixelVal < 0) disp_pixel_val = 0;
- else if (nPixelVal > 255) disp_pixel_val = 255;
- else disp_pixel_val = nPixelVal;
- }
2. window-level 时要注意 min 和 max 之外原始数据的处理
- double dFactor, min, max;
- int nPixelVal;
- min = (2*window_center - window_width)/2.0 + 0.5;
- max = (2*window_center + window_width)/2.0 + 0.5;
- dFactor = 255.0/(double)(max - min);
- for (i = 0; i < nNumPixels; i++){
- if (pixel_val < min){
- disp_pixel_val = 0;
- continue;
- }
- if (pixel_val > max){
- disp_pixel_val = 255;
- continue;
- }
- nPixelVal = (int)((pixel_val - min)*dFactor);
- if (nPixelVal < 0) disp_pixel_val = 0;
- else if (nPixelVal > 255) disp_pixel_val = 255;
- else disp_pixel_val = nPixelVal;
- }
实验结果
不同窗宽窗位比较
===============================================================================================
转载请注明出处:http://blog.csdn.net/utimes/article/details/8505469
===============================================================================================