开发者

need help in contrast stretching

i have found this formula and its description on a site

l(x,y)=(l(x,y)-min)(no of intensity levels/(max-min)) + initial intensity level

where, I( x,y ) represents the images, on the left side it represents the output image, while on the right side it represents the xth pixel in the yth column in the input image. In this equation the "min" and "max" are the minimum intensity value and the minimum intensity value in the current image. Here "no. of intensity levels" shows the total number of intensity values that can be assigned to a pixel. 开发者_运维问答For example, normally in the gray-level images, the lowest possible intensity is 0, and the highest intensity value is 255. Thus "no. of intensity levels" is equal to 255.

i have converted it into code, have i correctly converted it?

for(int y = 0; y < bmp.bmHeight; y++)   
  {      
      for(int x = 0; x < bmp.bmWidth; x++)     
      {         
          COLORREF rgb = dc.GetPixel(x, y);     
          BYTE r = GetRValue(rgb);       
          BYTE g = GetGValue(rgb);     
          BYTE b = GetBValue(rgb);     
          BYTE p,p1;
          if(r<g)
          {
              p=r;
              p1=g;
          }
          else
          {
              p=g;
              p1=r;
          }
          if(b<p)
              p=b;
          if(b>p1)
              p1=b;
          BYTE bw = (RGB(r, g, b)-p);
          bw=bw*(255/(p1-p));
          bw+=p1;
          dc.SetPixel(x, y, RGB(bw, bw, bw));      
      }   


This is my attempt to code the formula. Based on the formula from Fisher et al. Note that you will still run into artificial looking images unless you use the cutoff fraction described in Fisher's article, but that is your own homework ;-)

I didn't test this with real images, debugging it is also your homework.

Reference: For calculation of the intensity, see HSL and HSV on wikipedia.

typedef unsigned char byte;

const byte OUT_MIN  = 0;   // The desired min output luminosity 0   to stretch to entire spectrum
const byte OUT_MAX  = 255; // The desired max output luminosity 255 to stretch to entire spectrum

byte min = 255, max = 0;

// get the minimum and maximum values.
for( int y = 0; y < bmp.bmHeight; y++ )
{      
   for( int x = 0; x < bmp.bmWidth; x++ )     
   {  
       COLORREF rgb       = dc.GetPixel(x, y);   
       byte     intensity = ( rValue(rgb) + gValue(rgb) + bValue(rgb) ) / 3;

       min = min < intensity ? min : intensity;
       max = max > intensity ? max : intensity;
   }
}     

// set the new pixel values
for(int y = 0; y < bmp.bmHeight; y++)   
{      
   for(int x = 0; x < bmp.bmWidth; x++)     
   {  
      COLORREF rgb = dc.GetPixel(x, y);

     // Creates color image
     // Calculate new color using the formula. Has to be int, not byte, because you might go out of range.
     // We correct the range manually on the next two lines. 

     int r = ( rValue( rgb ) - min ) * ( OUT_MAX / (max - min) ) + OUT_MIN;  
     r = r < 0   ? 0   : r;  
     r = r > 255 ? 255 : r;

     int g = ( gValue( rgb ) - min ) * ( OUT_MAX / (max - min) ) + OUT_MIN;  
     g = g < 0   ? 0   : g;  
     g = g > 255 ? 255 : g;

     int b = ( bValue( rgb ) - min ) * ( OUT_MAX / (max - min) ) + OUT_MIN;  
     b = b < 0   ? 0   : b;  
     b = b > 255 ? 255 : b;

     dc.SetPixel( x, y, RGB( r, g, b ) );    
   }   
}


You need a separate loop to compute p and p1 (horrible variable names by the way) on a whole image basis before you have the loop for the main contrast stretching algorithm.

Also, in the example you give there are 256 intensity levels, not 255. 0 is an intensity level too.

Lastly, you should probably either convert the image to HSV before running the algorithm and only run it on the V values, or run it separately for R, G and B. Picking the minimum and maximum intensity the way you are is not likely to yield useful results for a color picture.


You need to make two passes through the image. First pass: find the max and min level of the image. Second pass: use the max and min values to do the contrast stretching.


I have edited @nus's code. actually I don't know if my code is correct or @nus's code, but my code has better result.

typedef unsigned char byte;

const byte OUT_MIN  = 0;   
const byte OUT_MAX  = 255; 

byte min = 255, max = 0;

for( int y = 0; y < bmp.bmHeight; y++ )
{      
for( int x = 0; x < bmp.bmWidth; x++ )     
{  
   COLORREF rgb       = dc.GetPixel(x, y);   

  byte     r = rValue(rgb);
  byte     g = gValue(rgb);
  byte     b = bValue(rgb);
  if (min > r) min = r;
  if (min > g) min = g;
  if (min > b) min = b;

  if (max < r) max = r;
  if (max < g) max = g;
  if (max < b) max = b;
 }
}     

for(int y = 0; y < bmp.bmHeight; y++)   
{      
for(int x = 0; x < bmp.bmWidth; x++)     
{  
  COLORREF rgb = dc.GetPixel(x, y);

    int r = ( rValue( rgb ) - min ) * ( OUT_MAX / (max - min) ) + OUT_MIN;  
 r = r < 0   ? 0   : r;  
 r = r > 255 ? 255 : r;

 int g = ( gValue( rgb ) - min ) * ( OUT_MAX / (max - min) ) + OUT_MIN;  
 g = g < 0   ? 0   : g;  
 g = g > 255 ? 255 : g;

 int b = ( bValue( rgb ) - min ) * ( OUT_MAX / (max - min) ) + OUT_MIN;  
 b = b < 0   ? 0   : b;  
 b = b > 255 ? 255 : b;

 dc.SetPixel( x, y, RGB( r, g, b ) );    
}   
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜