0

I tried to make my own implementation of Otsu. I already read some source code from java and some sites that explains the formula and tried to implement it. I want to share this to ask if anyone can help me or at least tell about what can I do or improve.

I already coded get width, height and the background and foreground weight, mean, variance, and within class variance.

Note that I have not implemented how to set or find the exact threshold or even change the picture to black-white(binarize) using within class variance. If you can help me, feel welcome to. I also see some java codes that has treshhold = i or treshhold = t but I can't see how they made the image to black-white.

Here is my code:

Otsu.java

    Bitmap tempImg = (Bitmap) original;
    Bitmap OImg = Bitmap.createBitmap(tempImg.getWidth(), tempImg.getHeight(), tempImg.getConfig());

    int width = tempImg.getWidth();
    int height = tempImg.getHeight();
    int A, R, G, B,colorPixel;

    for (int x = 0; x < width; x++) { //original image to grayscale
        for (int y = 0; y < height; y++) {

            colorPixel = tempImg.getPixel(x, y);

            A = Color.alpha(colorPixel);
            R = Color.red(colorPixel);
            G = Color.green(colorPixel);
            B = Color.blue(colorPixel);

            R = (R + G + B) / 3;
            G = R;
            B = R;

            OImg.setPixel(x, y, Color.argb(A, R, G,B ));
        }
    }
    return OImg;
}

public static Bitmap Botsu(Bitmap gImg){

    Bitmap tempImg = (Bitmap) gImg;
    Bitmap BWimg = Bitmap.createBitmap(tempImg.getWidth(), tempImg.getHeight(), tempImg.getConfig());

    int width = tempImg.getWidth();
    int height = tempImg.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, ImgPixB = 0, ImgPixF = 0, newPixel = 0;

        // pixel check for histogram

    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {

            colorPixel = tempImg.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
                for (int z=0; z<Fx.length; z++){
                    if (Fx[z] == gray){
                        c++;
                    }
                }
                if (c==1){
                    Fy[gray] = Fy[gray]+1; //y axis - counter for pixels for each x
                }
                else{
                    Fx[x] = gray; //x axis - 0-255
                    Fy[gray] = Fy[gray]+1;
                }
            }//By[Bx[x]]
            else{ // black - background
                for (int z=0; z<Bx.length; z++){
                    if (Bx[z] == gray){
                        c++;
                    }
                }
                if (c==1){
                    By[gray] = By[gray]+1; //y axis - counter for pixels for each x
                }
                else{
                    Bx[x] = gray; //x axis - 0-255
                    By[gray] = By[gray]+1;
                }
            }
        }
    }

    for (int b=0; b<By.length; b++){
        ImgPixB = ImgPixB + By[b];
    }
    for (int f=0; f<Fy.length; f++){
        ImgPixF = ImgPixF + Fy[f];
    }
    ImgPix = ImgPixB + ImgPixF;

    //bg part hist
    for (int i=0; i<By.length; i++){ //weight
        Bw = Bw + By[i];
    }
    Bw = Bw/ImgPix;
    for (int i=0; i<By.length; i++){ //pixel sum
        Bp = Bp + By[i];
    }
    for (int i = 0; i<Bx.length; i++){ //mean
        Bm = Bm + (Bx[i]*By[Bx[i]]);
    }
    Bm = Bm/Bp;
    for (int i=0; i<Bx.length; i++){ //variance
        Bv = Bv + (Math.pow((Bx[i]-Bm),2)*By[Bx[i]]); // (Bx[i]-Bm) * (Bx[i]-Bm)
    }
    Bv = Bv/Bp;

    //fg part hist
    for (int i=0; i<Fy.length; i++){ //weight
        Fw = Fw + Fy[i];
    }
    Fw = Fw/ImgPix;
    for (int i=0; i<Fy.length; i++){ //pixel sum
        Fp = Fp + Fy[i];
    }
    for (int i = 0; i<Fx.length; i++){ //mean
        Fm = Fm + (Fx[i]*Fy[Fx[i]]);
    }
    Fm = Fm/Fp;
    for (int i=0; i<Fx.length; i++){ //variance
        Fv = Fv + (Math.pow((Fx[i]-Fm),2)*Fy[Fx[i]]); // (Bx[i]-Bm) * (Bx[i]-Bm)
    }
    Fv = Fv/Fp;

    // within class variance
    Wcv = (Bw * Bv) + (Fw * Fv);

    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {

            colorPixel = tempImg.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);
            int gray2 = (int) (Wcv * R + Wcv * G + Wcv * B);
            if (gray2 > 128) {
                gray2 = 255;
            }
            else if (gray2 <129){
                gray2 = 0;
            }

            BWimg.setPixel(x, y, Color.argb(A, gray2, gray2, gray2));
        }
    }

    return BWimg;

x[z] is for x-axis andy[gray] is for y-axis. I based this on the graph on Lab Book

x = 0-255
y = how many pixels is on a certain color shade

feel free to send more samples that can help me.

OUTPUT: (I added 2 function with 3 output that has an output. Other value will only return few black dots or just white image.)

if (gray2 > 128) {
    gray2 = 255;
}
else if (gray2 < 129){
    gray2 = 0;
}

enter image description hereenter image description here

if (gray2 > 64 && gray2 < 129) {
    gray2 = 255;
}
else if (gray2 < 65){
    gray2 = 0;
}

enter image description here

Ray
  • 50
  • 11
  • you might want to try [CodeReview](https://codereview.stackexchange.com) instead – Chisko Apr 05 '18 at 20:43
  • sorry but what should i do there? ask for question or the same question or look for some answers? – Ray Apr 05 '18 at 20:49
  • 1
    Ask the question there. This is more for debugging or unsolved problems. That forum is more for improvement, as you seek. – Chisko Apr 05 '18 at 20:53
  • Ang im back here because a user said if I need help solving a problem Stack Overflow is probably a better option. – Ray Apr 05 '18 at 23:58
  • You probably not phrased the question correctly. If you stated as here that you are looking for possible optimizations then that user is just wrong – Chisko Apr 06 '18 at 00:58
  • I literally copied my question from here. So i dont know what part they didnt understand or how they understand my question. And my question is already put on hold. "This question appears to be off-topic for this site." – Ray Apr 06 '18 at 01:25
  • Hi again. I added some outputs from my experimented solution. – Ray Apr 06 '18 at 02:19

0 Answers0