阈值Java_亲测有效!一种完美动态阈值白平衡算法 Java实现。
幾年沒發文了,重新拿起技術!
最近做圖像處理,要自動處理顏色平衡問題,很多什么直方圖優化之類的,都不完美。所以在博客園找到了這個前輩的文章。
http://www.cnblogs.com/Imageshop/archive/2013/04/20/3032062.html#commentform
很可惜,這篇文章,首先沒有源碼,其次給出的一些計算過程有問題。所以我直接查看論文原文,以及一些映射公式,現在分享Java實現的版本:
核心算法:
BufferedImage img = ImageIO.read(new File("model3.jpg"));int pixelsize = img.getWidth() *img.getHeight();double[][][] YCbCr = new double[img.getWidth()][img.getHeight()][3];double Mr = 0, Mb = 0, Ymax = 0;for (int i = 0; i < img.getWidth(); i++) {for (int j = 0; j < img.getHeight(); j++) {
YCbCr[i][j]=toYCbCr(img.getRGB(i, j));
Mr+= YCbCr[i][j][2];
Mb+= YCbCr[i][j][1];
Ymax= Math.max(Ymax, YCbCr[i][j][0]);
}
}
Mr/=pixelsize;
Mb/=pixelsize;double Dr = 0, Db = 0;for (int i = 0; i < YCbCr.length; i++) {for (int j = 0; j < YCbCr[i].length; j++) {
Db+= Math.abs(YCbCr[i][j][1] -Mb);
Dr+= Math.abs(YCbCr[i][j][2] -Mr);
}
}
Dr/=pixelsize;
Db/=pixelsize;double[][] Y = new double[img.getWidth()][img.getHeight()];double[] Yhistogram = new double[256];double Ysum = 0;for (int i = 0; i < Y.length; i++) {for (int j = 0; j < Y[i].length; j++) {int value = (Math.abs(YCbCr[i][j][1] - (Mb + Db * Math.signum(Mb))) < 1.5 * Db) & // (Math.abs(YCbCr[i][j][2]) - (1.5 * Mr + Dr * Math.signum(Mr))) < 1.5 * Dr ? 1 : 0;if (value <= 0)continue;double y = YCbCr[i][j][0];
Y[i][j]=y;
Yhistogram[(int) Y[i][j]]++;
Ysum++;
}
}double Yhistogramsum = 0;double Ymin = 0;for (int i = Yhistogram.length - 1; i >= 0; i--) {
Yhistogramsum+=Yhistogram[i];if (Yhistogramsum > 0.1 *Ysum) {
Ymin=i;break;
}
}double Raver = 0, Gaver = 0, Baver = 0;double averSum = 0;for (int i = 0; i < Y.length; i++) {for (int j = 0; j < Y[i].length; j++) {if (Y[i][j] >Ymin) {int color =img.getRGB(i, j);int r = (color >> 16) & 0xFF;int g = (color >> 8) & 0xFF;int b = color & 0xFF;
Raver+=r;
Gaver+=g;
Baver+=b;
averSum++;
}
}
}
Raver/=averSum;
Gaver/=averSum;
Baver/=averSum;double Rgain = Ymax / Raver, Ggain = Ymax / Gaver, Bgain = Ymax /Baver;for (int i = 0; i < img.getWidth(); i++) {for (int j = 0; j < img.getHeight(); j++) {
Color color= newColor(img.getRGB(i, j));int r = ensureColor((int) Math.floor(color.getRed() *Rgain));int g = ensureColor((int) Math.floor(color.getGreen() *Ggain));int b = ensureColor((int) Math.floor(color.getBlue() *Bgain));
img.setRGB(i, j,newColor(r, g, b).getRGB());
}
}
ImageIO.write(img,"jpg", new File("xxx.jpg"));
其中計算YCrCb的算法如下:
// https://mathematica.stackexchange.com/questions/29786/how-to-convert-rgb-to-ycbcr
private double[] toYCbCr(intcolor) {int r = (color >> 16) & 0xFF;int g = (color >> 8) & 0xFF;int b = color & 0xFF;double Y = 16 + (65.481 * r / 255 + 128.553 * g / 255 + 24.966 * b / 255);double Cb = 128 + (-37.797 * r / 255 - 74.203 * g / 255 + 112 * b / 255);double Cr = 128 + (112 * r / 255 - 93.786 * g / 255 - 18.214 * b / 255);return new double[] { Y, Cb, Cr };
}
最后還有一個像素范圍檢測:
private int ensureColor(doublecolor) {if (color < 0)return 0;if (color > 255)return 255;return (int) color;
}
實際效果:
效果非常好。我也看了下原作者的問題,應該是計算YCrCb出錯了。
本次分享完畢啦!好幾年沒有在博客園發文了,說下近況了。第一次進博客園是10多年前,在上海交大讀研究生的一個窮小孩。研究生畢業之后一直磕磕碰碰在創業,到了現在36了,仍然在創業。也許將來創業成功了,這些博客都能成為勵志經歷。不成功,那就繼續努力。
最近正在投身微信公眾號,也小有成就,做了全國最大的樂高公眾號。希望將來有一天能有所成。
感謝各位園友的閱讀,希望這篇文章有幫助!
總結
以上是生活随笔為你收集整理的阈值Java_亲测有效!一种完美动态阈值白平衡算法 Java实现。的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java调用存储过程sqlserver_
- 下一篇: java的函数库_Dagli首页、文档和