2012-07-26 87 views
3

我正在对图像进行直方图均衡。我首先得到RGB图像并将其转换为YUV。我在YUV的Y'上运行直方图均衡算法,然后转换回RGB。是我吗,还是图像看起来很奇怪?我正确地做到了这一点?这个图像很亮,其他图像有点红。Android直方图均衡算法给了我真正的明亮或红色图像

这里是前/之后的图像:

before after

的算法(该评价值是我先前用于转换值都产生几乎相同的结果。):

public static void createContrast(Bitmap src) { 

    int width = src.getWidth(); 
    int height = src.getHeight(); 

    Bitmap processedImage = Bitmap.createBitmap(width, height, src.getConfig()); 

    int A = 0,R,G,B; 
    int pixel; 
    float[][] Y = new float[width][height]; 
    float[][] U = new float[width][height]; 
    float[][] V = new float [width][height]; 
    int [] histogram = new int[256]; 
    Arrays.fill(histogram, 0); 

    int [] cdf = new int[256]; 
    Arrays.fill(cdf, 0); 
    float min = 257; 
    float max = 0; 

    for(int x = 0; x < width; ++x) { 
     for(int y = 0; y < height; ++y) { 
      pixel = src.getPixel(x, y); 
      //Log.i("TEST","("+x+","+y+")"); 
      A = Color.alpha(pixel); 
      R = Color.red(pixel); 
      G = Color.green(pixel); 
      B = Color.blue(pixel); 

      /*Log.i("TESTEST","R: "+R); 
      Log.i("TESTEST","G: "+G); 
      Log.i("TESTEST","B: "+B);*/ 

      // convert to YUV 
      /*Y[x][y] = 0.299f * R + 0.587f * G + 0.114f * B; 
      U[x][y] = 0.492f * (B-Y[x][y]); 
      V[x][y] = 0.877f * (R-Y[x][y]);*/ 

      Y[x][y] = 0.299f * R + 0.587f * G + 0.114f * B; 
      U[x][y] = 0.565f * (B-Y[x][y]); 
      V[x][y] = 0.713f * (R-Y[x][y]); 
      // create a histogram 
      histogram[(int) Y[x][y]]+=1; 
      // get min and max values 
      if (Y[x][y] < min){ 
       min = Y[x][y]; 
      } 
      if (Y[x][y] > max){ 
       max = Y[x][y]; 
      } 
     } 
    } 

    cdf[0] = histogram[0]; 
    for (int i=1;i<=255;i++){ 
     cdf[i] = cdf[i-1] + histogram[i]; 
     //Log.i("TESTEST","cdf of: "+i+" = "+cdf[i]); 
    } 

    float minCDF = cdf[(int)min]; 
    float denominator = width*height - minCDF; 
    //Log.i("TEST","Histeq Histeq Histeq Histeq Histeq Histeq"); 
    for(int x = 0; x < width; ++x) { 
     for(int y = 0; y < height; ++y) { 
      //Log.i("TEST","("+x+","+y+")"); 
      pixel = src.getPixel(x, y); 
      A = Color.alpha(pixel); 
      Y[x][y] = ((cdf[ (int) Y[x][y]] - minCDF)/(denominator)) * 255; 
      /*R = minMaxCalc(Y[x][y] + 1.140f * V[x][y]); 
      G = minMaxCalc (Y[x][y] - 0.395f * U[x][y] - 0.581f * V[x][y]); 
      B = minMaxCalc (Y[x][y] + 2.032f * U[x][y]);*/ 

      R = minMaxCalc(Y[x][y] + 1.140f * V[x][y]); 
      G = minMaxCalc (Y[x][y] - 0.344f * U[x][y] - 0.714f * V[x][y]); 
      B = minMaxCalc (Y[x][y] + 1.77f * U[x][y]); 
      //Log.i("TESTEST","A: "+A); 
      /*Log.i("TESTEST","R: "+R); 
      Log.i("TESTEST","G: "+G); 
      Log.i("TESTEST","B: "+B);*/ 
      processedImage.setPixel(x, y, Color.argb(A, R, G, B)); 
     } 
    } 

}

我的下一步是绘制直方图be前后。我只想在这里得到一个意见。

+1

我会首先创建带有几个纯色块的测试图像来测试它。 – 2012-07-26 19:13:03

+0

那张图片对我来说看起来不错。我希望你的算法能够使图像变亮,以至于其中的一部分是纯白色的。如果你发红,那很糟糕。确保你的RGB-> YUV-> RGB路径(没有均衡)确实是身份函数。 – 2012-07-26 21:50:56

+0

谢谢你的评论。首先,我将使用纯色来查看结果,其次在纯色图像上,我会确保在运行没有histeq的转换时我会得到相同的图像。 – 2012-07-27 00:50:02

回答

0

问题有点老,但让我回答。

原因是直方图均衡化的工作方式。该算法试图使用所有的0-255范围,而不是给定的图像范围。

所以如果你给它一个黑色的图像,它会改变相对较亮的像素为白色。黑色的颜色相对较暗。

如果你给它一个明亮的图像,出于同样的原因它会变暗。