2009-08-18 6 views
5

Ho una matrice di BitmapFrames e devo eseguire un allungamento dell'istogramma. So che questo è diverso dall'equalizzazione di un istogramma e quale è il risultato finale .... il problema è che non ho assolutamente idea di cosa fare dopo aver ottenuto l'istogramma.Ho bisogno di eseguire un allungamento dell'istogramma

Finora il mio codice crea una matrice per l'istogramma, quindi so quanti pixel di ciascun valore ho. Ma dopo non so cosa fare.

Questo è il codice che ho finora ... in questo momento rende l'istogramma e poi istogramma equalizza ... che non è quello che voglio ... stavo solo cercando di imparare di più su istogrammi

[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); 
    } 
} 

questo è ciò che gli istogrammi dovrebbe essere simile secondo il mio insegnante:

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

ho eseguito il codice di cui sopra ... e ottenuto un dritto nero ima ge. ecco il mio codice:

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); 
      } 

risposta

9

Istogramma estende è la mappatura di valori di pixel tale che:

  • il valore più basso (ad esempio, 84 in figura) diventa 0
  • il più alto valore (ad esempio 153 nell'illustrazione) diventa 255 (in immagini a 8 bit)
  • e tutti i valori intermedi sono interpolati tra tale intervallo (vedere i llustration).

In altre parole l'allungamento dell'istogramma significa estendere la dinamica dei dati dell'immagine (84: 153) alla massima dinamica possibile (0: 255).

Questo non dovrebbe influenzare l'altezza dei picchi dell'istogramma, ma solo la loro diffusione (l'illustrazione è un po 'fuorviante su questo punto).

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

Image source

In pratica questa è la mappatura si applicano ai pixel dell'immagine (pseudocodice):

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

ho cercato di attuare tale ... Vai ai miei "risposta" al di sotto ... questo è il nuovo codice che ho per essa, ma non funziona – dabonz413

0

Se si ha il controllo dell'illuminazione e o guadagno/offset della fotocamera, puoi ottimizzarli e allungare l'istogramma come desideri.

+0

non ho alcun controllo della fotocamera qualunque. questo è tutto a che fare con qualsiasi immagine che mi viene data a caso – dabonz413

0

Non dimenticare di considerare il galleggiante. Quindi, una leggera modifica alla risposta di dabonz413:

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