2009-08-18 46 views
5

我有一個BitmapFrames數組,需要做一個直方圖拉伸。我知道這與直方圖均衡有所不同,最終的結果是......不一樣。問題是我完全不知道在得到直方圖後該怎麼做。我需要做一個直方圖拉伸

到目前爲止,我的代碼爲直方圖創建了一個數組,因此我知道每個值有多少個像素。但之後我不知道該怎麼做。

這是我迄今...現在它使直方圖,然後直方圖均衡......這是不是我想要的代碼...我只是想更多地瞭解直方圖

[Cmdlet(VerbsData.ConvertTo, "HistoStretch")] 
public class HistoStretchCmdlet : PSCmdlet 
{ 
    private BitmapFrame[] bFrame, outFrame; 
    private BitmapSource src; 
    private double pixelsize; 
    private byte[] pixels, outPixels; 
    private byte MAX_VAL; 
    private int[] histogram; 
    private int cf, start; 

    [Parameter(ValueFromPipeline = true, 
     ValueFromPipelineByPropertyName = true), ValidateNotNullOrEmpty] 
    public BitmapFrame[] Bitmap 
    { 
     get 
     { 
      return bFrame; 
     } 
     set 
     { 
      bFrame = value; 
     } 
    } 

    protected override void ProcessRecord() 
    { 
     base.ProcessRecord(); 
     Console.Write("Applying a histogram stretch to the image...\n\n"); 
     outFrame = new BitmapFrame[bFrame.Length]; 
     for (int c = 0; c < bFrame.Length; c++) 
     { 
      MAX_VAL = (byte)((1 << bFrame[c].Format.BitsPerPixel) - 1); 
      histogram = new int[MAX_VAL + 1]; 
      for (int i = 0; i <= MAX_VAL; i++) 
      { 
       histogram[i] = 0; 
      } 

      pixelsize = bFrame[c].PixelWidth * bFrame[c].PixelHeight; 
      pixels = new byte[(int)pixelsize]; 
      outPixels = new byte[(int)pixelsize]; 
      bFrame[c].CopyPixels(pixels,(int)bFrame[c].Width * (bFrame[c].Format.BitsPerPixel/8),0); 

      for (int i = 0; i < pixelsize; i++) 
      { 
       histogram[(int)pixels[i]] = histogram[(int)pixels[i]] + 1; 
      } 
      for (int i = 0; i <= MAX_VAL; i++) 
      { 
       Console.Write("{0}: {1}\n", i, histogram[i]); 
      } 
      for (int i = 0; i <= MAX_VAL; i++) 
      { 
       if (histogram[i] >= 1) 
       { 
        start = i; 
        break; 
       } 
      } 

      for (int i = 0; i < pixelsize; i++) 
      { 
       cf = 0; 
       for (int g = 0; g <= MAX_VAL; g++) 
       { 
        cf += histogram[g]; 
        if (g == pixels[i]) 
        { 
         break; 
        } 
       } 
       outPixels[i] = (byte)(cf * (MAX_VAL/pixelsize)); 
      } 

      src = BitmapSource.Create(bFrame[c].PixelWidth, bFrame[c].PixelHeight, bFrame[c].DpiX, bFrame[c].DpiY, 
       bFrame[c].Format, bFrame[c].Palette, outPixels, (int)(bFrame[c].Width * (bFrame[c].Format.BitsPerPixel/8))); 
      outFrame[c] = BitmapFrame.Create(src); 
     } 
     WriteObject(outFrame); 
    } 
} 

這是直方圖看起來應該按照我的老師,如:

http://www.fileden.com/files/2009/8/18/2547657/histostretch.PNG

我跑上面的代碼...並得到了黑色直IMA GE。 這裏是我的代碼:

outFrame = new BitmapFrame[bFrame.Length]; 
     for (int c = 0; c < bFrame.Length; c++) 
     { 
      MAX_VAL = (byte)((1 << bFrame[c].Format.BitsPerPixel) - 1); 
      histogram = new int[MAX_VAL + 1]; 
      for (int i = 0; i <= MAX_VAL; i++) 
      { 
       histogram[i] = 0; 
      } 

      pixelsize = bFrame[c].PixelWidth * bFrame[c].PixelHeight; 
      pixels = new byte[(int)pixelsize]; 
      outPixels = new byte[(int)pixelsize]; 
      bFrame[c].CopyPixels(pixels,(int)bFrame[c].Width * (bFrame[c].Format.BitsPerPixel/8),0); 
      max = pixels[0]; 
      min = pixels[0]; 

      for (int i = 0; i < pixelsize; i++) 
      { 
       histogram[(int)pixels[i]] = histogram[(int)pixels[i]] + 1; 
       if((int)pixels[i] > max) 
        max = pixels[i]; 
       if((int)pixels[i] < min) 
        min = pixels[i]; 
      } 

      dynamic = max - min; 

      for (int i = 0; i < pixelsize; i++) 
      { 
       outPixels[i] = (byte)(((pixels[i] - min)/dynamic) * MAX_VAL); 
      } 

回答

9

直方圖拉伸是像素值的映射使得:

  • 最低值(例如84圖中)變爲0
  • 最高值(例如圖中的153)變爲255(在8位圖像中)
  • 並且所有中間值都在該範圍之間插值(參見i llustration)。

換句話說,直方圖拉伸意味着將圖像數據(84:153)的動態擴展到最大可能的動態(0:255)。

這應該不會影響直方圖峯的身高,但只有其蔓延(插圖是有點誤導這一點)。

histogram stretch http://cct.rncan.gc.ca/resource/tutor/fundam/images/linstre.gif

Image source

在實踐這是你將適用於圖像的像素映射(僞):

maxVal = image.maximumValue() # 153 
minVal = image.minumumValue() # 84 
dynamic = maxVal-minVal 
for pixel in image.Pixels(): 
    newPixel = ((pixel-minVal)/dynamic)*255 
+0

我試圖實現一個......看到我的「答案」的......這是新的代碼我有,但它不工作 – dabonz413 2009-08-19 15:36:53

0

如果你有在照明控制和或相機的增益/偏移,您可以優化這些並根據需要展開直方圖。

+0

我管不着無論如何。這是所有處理任何我隨機給出的圖像 – dabonz413 2009-08-19 15:36:17

0

不要忘記考慮浮動。所以,一個輕微修改dabonz413的回答是:

maxVal = image.maximumValue() # 153 
minVal = image.minumumValue() # 84 
dynamic = maxVal-minVal 
for pixel in image.Pixels(): 
    newPixel = ((float) (pixel-minVal)/dynamic)*255