Как полностью бинаризовать все захваченные фотографии в otsu
Я сделал свою собственную реализацию Оцу для своего проекта. Я следовал математическому алгоритму, чтобы сделать это. Я пытался использовать гистограмму, но мне было трудно, поэтому я просто следовал ее логике.
Я использую drawable для отладки и легко пробую вывод без хлопот захвата изображения с помощью камеры каждый раз. Я вызываю функции в своем основном классе.
Мой текущий вывод возвращает хорошую бинаризацию, но иногда он возвращает полный черный, если изображение имеет "больше черного объекта/пикселя", и полный белый, если изображение имеет "больше белого объекта/пикселя".
Плохой Выход 1
Плохой Выход 2
Плохой Выход 3 (изображение, используемое здесь, захвачено камерой)
Что я уже пробовал:
Вот мой код: (Android)
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; //FG weight for (i = 0; i < Bx.length; i++) { //FG mean Fm = Fm + (Fx[i] * Fy[i]); } Fm = Fm / Fp; for (i = 0; i < Bx.length; i++) { //FG 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;
Это 2 хороших выхода:
Хороший Выход 1
Хороший Выход 2