大津直方图自我实现

时间:2018-04-05 20:38:58

标签: android algorithm android-studio histogram image-thresholding

我试图自己实现Otsu。我已经从java和一些解释公式的网站上读了一些源代码并尝试实现它。我想分享一下,问一下是否有人可以帮助我,或者至少告诉我能做些什么或改进。

我已编码获取宽度,高度以及背景和前景权重,均值,方差和类间差异。

请注意,我还没有实现如何设置或找到确切的阈值,甚至没有使用类方差来将图片更改为黑白(二值化)。如果你能帮助我,欢迎来到。我也看到一些有treshhold = itreshhold = t的java代码,但我看不出它们是如何将图像变成黑白的。

这是我的代码:

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]用于x轴,y[gray]用于y轴。我的基础是Lab Book

上的图表
x = 0-255
y = how many pixels is on a certain color shade

随时发送更多可以帮助我的样本。

输出:(我添加了2个具有输出的3个输出功能。其他值只返回少量黑点或只是白色图像。)

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

enter image description here enter image description here

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

enter image description here

0 个答案:

没有答案