16bit灰度图像映射到8bit显示

来源:互联网 发布:红蜘蛛调色软件 编辑:程序博客网 时间:2024/05/01 16:42

 图像显示和打印面临的一个问题是:图像的亮度和对比度能否充分突出关键部分。这里所指的“关键部分”在   CT   里的例子有软组织、骨头、脑组织、肺、腹部等等。  
   
  技术问题:    
  o     显示器往往只有   8-bit,   而数据有   12-   至   16-bits。  
  o     如果将数据的   min   和   max   间   (dynamic   range)   的之间转换到   8-bit   0-255   去,过程是个有损转换,   而且出来的图像往往突出的是些噪音。  
   
  针对这些问题,研究人员先提出一些要求   (requirements),然后根据这些要求提出了一些算法。这些算法现在都很成熟。  
   
  要求一:充分利用   0-255   间的显示有效值域  
  要求二:尽量减少值域压缩带来的损失  
  要求三:不能损失应该突出的组织部分  
   
  算法分析:  
  A.     16-bit   到   8-bit   直接转换:    
   
        computeMinMax(pixel_val,   min,   max);   //   先算图像的最大和最小值  
        for   (i   =   0;   i   <   nNumPixels;   i++)  
            disp_pixel_val[i]   =   (pixel_val[i]   -   min)*255.0/(double)(max   -   min);  
   
  这个算法必须有,对不少种类的图像是很有效的:如   8-bit   图像,MRI,   ECT,   CR   等等。  
   
  B.   Window-leveling   算法:   W/L   是专门为   CT   设计的。原理很简单:CT   图像里不同组织的密度   (用   Hounsfield   单位)   是在固定的值域,   与具体设备和成像软件没有关系。因此,要看头颅时,   我们只需将头颅的值域转换到   0-255   就行了。  
   
  CT   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[i]   =   (pixel_val[i]   -   min)*255.0/(double)(max   -   min);  
   
  请注意,CT   图像必须先转换成   Hounsfield   值再做   window-level。   这个转换包括将多余高位   bits   变成   0   (clipping),   和用   recale   slope   和   rescale   intercept   来做单位转换。  
   
  HU[i]   =   pixel_val[i]*rescale_slope   +   rescale_intercept  
   
  C.非线性转换  
   
  我刚刚说的是将   min   和   max   间的数值线性转换到   0-255   之间。   如果   max   -   min   出来是个很大的数值,比如说   25500,   那就说每   100   原始密度会压缩成一个显示灰度。   这样的损失可能会很大。  
   
  因为人眼对灰度地反应式是非线性的,非线性转换可以解决一些问题。   常用算法有   log   和   gamma   两种。gamma   比较好调   gamma   值,因此用得比较多。  
   
  for   (i   =   0;   i   <   nNumPixels;   i++)  
          disp_pixel_val[i]   =   255.0   *   pow(pixel_value[i]/(max-min),   1.0/gamma);  
   
  D.   有效值域:CT   的   Window-level   有标准的定义,请参看   “Practical   CT   Techniques",   by   Wladyslaw   Gedroyc   and   Sheila   Rankin,   Springer-Verlag。最常用到的有   WW   =   400,   WL   =   40   (实用许多部位);   WW   =   100,   WL   =   36   (头);WW   =   3200,   WL   =   200   (骨头),等等。  
   
  补充几点:  
   
  o       在做任何转换时要注意有效灰度域外的数值的处理。    
        最好先用   int   而非   unsigned   char   来算,再转入矩阵,以避免   overflow   和   underflow。  
   
        double   dFactor   =   255.0/(double)(max   -   min);  
        int   nPixelVal;  
   
        for   (i   =   0;   i   <   nNumPixels;   i++)  
        {  
   
            nPixelVal   =   (int)   ((pixel_val[i]   -   min)*dFactor);  
   
            if   (nPixelVal   <   0)            
                disp_pixel_val[i]   =   0;  
            else   if   (nPixelVal   >   255)  
              disp_pixel_val[i]   =   255;  
            else  
              disp_pixel_val[i]   =   nPixelVal;  
   
        }    
         
   
  o       做   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[i]   <   min)  
            {  
                disp_pixel_val[i]   =   0;  
                continue;  
            }  
   
            if   (pixel_val[i]   >   max)  
            {  
                disp_pixel_val[i]   =   255;  
                continue;  
            }  
   
            nPixelVal   =   (int)((pixel_val[i]   -   min)*dFactor);  
   
            if   (nPixelVal   <   0)            
                disp_pixel_val[i]   =   0;  
            else   if   (nPixelVal   >   255)  
              disp_pixel_val[i]   =   255;  
            else  
              disp_pixel_val[i]   =   nPixelVal;  
   
      }  

原创粉丝点击