0

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

我已经编写了获取宽度、高度以及背景和前景权重、均值、方差和类内方差的代码。

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

这是我的代码:

大津.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;
}

在此处输入图像描述在此处输入图像描述

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

在此处输入图像描述

4

0 回答 0