My self implemented otsu returns a good quality of binarize image but if the image has "more black" pixels it returns a full black image and if the image has "more white" pixels it returns a full white image.
Im using drawable and if I use camera it returns the output with the same idea (full black or full white). How can I correctly binarize the image even if the image has more black or more white?
(the image that returns with full black or full white can be binarize by sauvola as I try to compare and check the output. I didn't put the sauvola output to avoid long post but I can post it if needed.)
Here are some of the output on Otsu:
Bad Output:
(the image below is from camera capture)
Otsu Binarization Code
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;