2009-08-18 10 views
5

Tengo una matriz de Marcos de mapa de bits y necesito hacer un estiramiento de histograma. Sé que esto es diferente de una ecualización de histograma, y ​​cuál es el resultado final ... sorta. el problema es que no tengo idea de qué hacer después de obtener el histograma.Necesito hacer un estiramiento de histograma

Hasta ahora, mi código crea una matriz para el histograma, así que sé cuántos píxeles de cada valor tengo. Pero después de eso, no sé qué hacer.

este es el código que tengo hasta ahora ... ahora que hace que el histograma y luego histograma iguala ... que no es lo que quiero ... Yo sólo estaba tratando de aprender más sobre histogramas

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

esto es lo que los histogramas debe ser similar según mi profesor:

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

me encontré con el código anterior ... y consiguió un ima negro recta ge. aquí es mi código de:

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

Respuesta

9

histograma estiramiento es el mapeo de valores de pixel de tal manera que:

  • el valor más bajo (por ejemplo, 84 en la ilustración) se convierte en 0
  • el más alto el valor (por ejemplo, 153 en la ilustración) se convierte en 255 (en imágenes de 8 bits)
  • y todos los valores intermedios se interpolan entre ese rango (consulte i). Ilustracion).

En otras palabras, el estiramiento del histograma significa extender la dinámica de los datos de imagen (84: 153) a la mayor dinámica posible (0: 255).

Esto no debería afectar la altura de los picos del histograma, sino solo su extensión (la ilustración es un poco engañosa en este punto).

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

Image source

En la práctica Esto es la asociación que se aplicaría a los píxeles de la imagen (pseudocódigo):

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

me trató de implementar que ver ... mi "respuesta" a continuación ... que es el nuevo código que tengo para ella, pero no funciona – dabonz413

0

Si usted tiene control sobre la iluminación y o ganancia/desplazamiento de la cámara, puede optimizarlos y estirar el histograma como lo desee.

+0

no tengo control de la cámara en absoluto. esto es todo tratar con cualquier imagen que estoy dado al azar – dabonz413

0

No olvides considerar el flotador. Por lo que una ligera modificación a la respuesta de dabonz413:

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