我自己实施的otsu返回了一个高质量的二值化图像,但如果图像有更多的黑色"像素它会返回一个完整的黑色图像,如果图像有"更多的白色"它返回一个完整的白色图像。
我使用drawable,如果我使用相机,它会返回具有相同想法的输出(全黑或全白)。即使图像更黑或更白,我怎样才能正确地对图像进行二值化?
(当我尝试比较并检查输出时,返回全黑或全白的图像可以通过sauvola进行二值化。我没有把sauvola输出放在避免长帖但我可以在需要时发布它。)
以下是Otsu的一些输出:
Otsu二值化代码
Bitmap BWimg = Bitmap.createBitmap(gImg.getWidth(), gImg.getHeight(), gImg.getConfig());
int width = gImg.getWidth();
int height = gImg.getHeight();
int A, R, G, B, colorPixel;
// histo-thresh
double Wcv = 0;
int[] Bx = new int[256];
int[] By = new int[256];
int[] Fx = new int[256];
int[] Fy = new int[256];
double Bw = 0, Bm = 0, Bv = 0, Bp = 0;
double Fw = 0, Fm = 0, Fv = 0, Fp = 0;
int c = 0, ImgPix = 0;
// pixel check for histogram
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
colorPixel = gImg.getPixel(x, y);
A = Color.alpha(colorPixel);
R = Color.red(colorPixel);
G = Color.green(colorPixel);
B = Color.blue(colorPixel);
int gray = (int) (0.2989 * R + 0.5870 * G + 0.1140 * B);
if (gray > 128) { // white - foreground
Fx[gray] = gray;
Fy[gray] = Fy[gray] + 1;
Fw = Fw + 1;
Fp = Fp + 1;
}
else { // black - background
Bx[gray] = gray;
By[gray] = By[gray] + 1;
Bw = Bw + 1;
Bp = Bp + 1;
}
ImgPix = ImgPix + 1;
}
}
//BG hist
Bw = Bw / ImgPix; //BG weight
int i;
for (i = 0; i < Bx.length; i++) { //BG mean
Bm = Bm + (Bx[i] * By[i]);
Bm = Bm / Bp;
}
for (i = 0; i < Bx.length; i++) { //BG variance
Bv = Bv + (Math.pow((Bx[i] - Bm), 2) * By[i]); // (Bx[i]-Bm) * (Bx[i]-Bm)
}
Bv = Bv / Bp;
//FG hist
Fw = Fw / ImgPix; //BG weight
for (i = 0; i < Bx.length; i++) { //BG mean
Fm = Fm + (Fx[i] * Fy[i]);
}
Fm = Fm / Fp;
for (i = 0; i < Bx.length; i++) { //BG variance
Fv = Fv + (Math.pow((Fx[i] - Fm), 2) * Fy[i]); // (Fx[i]-Fm) * (Fx[i]-Fm)
}
Fv = Fv / Fp;
// within class variance
Wcv = (Bw * Bv) + (Fw * Fv);
//int gray2 = 0;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
colorPixel = gImg.getPixel(x, y);
A = Color.alpha(colorPixel);
R = Color.red(colorPixel);
G = Color.green(colorPixel);
B = Color.blue(colorPixel);
//int gray2 = (int) ((0.2989 * R) + (0.5870 * G) + (0.1140 * B));
int gray2 = (R + G + B);
if (gray2 > Wcv) {
gray2 = 255;
}
else {
gray2 = 0;
}
BWimg.setPixel(x, y, Color.argb(A, gray2, gray2, gray2));
}
}
return BWimg;
答案 0 :(得分:1)
我上周二得到了答案但忘记发布了。我把它运行了。
@Morrison Chang感谢关于我的代码的小推动和澄清
Bitmap BWimg = Bitmap.createBitmap(gImg.getWidth(), gImg.getHeight(), gImg.getConfig());
int width = gImg.getWidth();
int height = gImg.getHeight();
int A, R, G, B, colorPixel;
double Wcv = 0, th = 0;
int[] tPXL = new int[256];
int[][] pxl = new int[width][height];
double Bw, Bm, Bv, Fw, Fm, Fv;
int np, ImgPix = 0, fth = 0;
// pixel check for histogram //
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
colorPixel = gImg.getPixel(x, y);
A = Color.alpha(colorPixel);
R = Color.red(colorPixel);
G = Color.green(colorPixel);
B = Color.blue(colorPixel);
int gray = (int) ( (0.2126 * R) + (0.7152 * G) + (0.0722 * B) ); // (int) ( (0.299 * R) + (0.587 * G) + (0.114 * B) );
pxl[x][y] = gray;
tPXL[gray] = tPXL[gray] + 1;
ImgPix = ImgPix + 1;
}
}
// ----- histo-variance ----- //
for (int t = 0; t < 256; t++){
Bw = 0; Bm = 0; Bv = 0;
Fw = 0; Fm = 0; Fv = 0;
np = 0;
if (t == 0){ // all white/foreground as t0 ----- //
Fw = 1;
for (int d = 0; d < 256; d++) { //mean
Fm = Fm + (d * tPXL[d]);
}
Fm = Fm / ImgPix;
for (int e = 0; e < 256; e++) { //variance
Fv = Fv + (Math.pow((e - Fm), 2) * tPXL[e]);
}
Fv = Fv / ImgPix;
}
else { // main thresholding
for (int d = 0; d < (t-1); d++){ // BG weight & mean + BG pixel
Bw = Bw + tPXL[d];
Bm = Bm + (d * tPXL[d]);
np = np + tPXL[d];
}
Bw = Bw / ImgPix;
Bm = Bm / np;
for (int e = 0; e < (t-1); e++) { //BG variance
Bv = Bv + (Math.pow((e - Bm), 2) * tPXL[e]);
}
Bv = Bv / np;
for (int j = t; j < 256; j++) { // FG weight & mean + BG pixel
Fw = Fw + tPXL[j];
Fm = Fm + (j * tPXL[j]);
np = ImgPix - np;
}
Fw = Fw / ImgPix;
Fm = Fm / np;
for (int k = t; k < 256; k++) { //FG variance
Fv = Fv + (Math.pow((k - Fm), 2) * tPXL[k]);
}
Fv = Fv / np;
}
// within class variance
Wcv = (Bw * Bv) + (Fw * Fv);
if (t == 0){
th = Wcv;
}
else if (Wcv < th){
th = Wcv;
fth = t;
}
}
// set binarize pixel
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int fnpx = pxl[x][y];
colorPixel = gImg.getPixel(x, y);
A = Color.alpha(colorPixel);
if (fnpx > fth) { //R > fth
fnpx = 255;
BWimg.setPixel(x, y, Color.argb(A, fnpx, fnpx, fnpx));
}
else {
fnpx = 0;
BWimg.setPixel(x, y, Color.argb(A, fnpx, fnpx, fnpx));
}
}
}
return BWimg;