gpt4 book ai didi

java - java中的大津阈值

转载 作者:行者123 更新时间:2023-11-30 10:52:25 26 4
gpt4 key购买 nike

我正在尝试使用 tesseract 对数字执行 ocr,发现当我使用 photoshop 中的阈值过滤器对图像进行预处理时,我得到了一些非常好的结果。我试图以编程方式复制它并找到了以下有用的教程:http://developer.bostjan-cigan.com/java-image-binarization/当我运行代码时,虽然我只是得到一个全黑的图像。有谁知道我该如何解决这个问题?

package otsubinarize;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class OtsuBinarize {

private static BufferedImage original, grayscale, binarized;

public static void main(String[] args) throws IOException {

File original_f = new File("/Users/unknown1/Desktop/t1.png");
String output_f = "/Users/unknown1/Desktop/t1";
original = ImageIO.read(original_f);
grayscale = toGray(original);
binarized = binarize(grayscale);
writeImage(output_f);

}

private static void writeImage(String output) throws IOException {
File file = new File(output+".jpg");
ImageIO.write(binarized, "jpg", file);
}

// Return histogram of grayscale image
public static int[] imageHistogram(BufferedImage input) {

int[] histogram = new int[100];

for(int i=0; i<histogram.length; i++) histogram[i] = 0;

for(int i=0; i<input.getWidth(); i++) {
for(int j=0; j<input.getHeight(); j++) {
int red = new Color(input.getRGB (i, j)).getRed();
histogram[red]++;
}
}

return histogram;

}

// The luminance method
private static BufferedImage toGray(BufferedImage original) {

int alpha, red, green, blue;
int newPixel;

BufferedImage lum = new BufferedImage(original.getWidth(), original.getHeight(), original.getType());

for(int i=0; i<original.getWidth(); i++) {
for(int j=0; j<original.getHeight(); j++) {

// Get pixels by R, G, B
alpha = new Color(original.getRGB(i, j)).getAlpha();
red = new Color(original.getRGB(i, j)).getRed();
green = new Color(original.getRGB(i, j)).getGreen();
blue = new Color(original.getRGB(i, j)).getBlue();

red = (int) (0.21 * red + 0.71 * green + 0.07 * blue);
// Return back to original format
newPixel = colorToRGB(alpha, red, red, red);

// Write pixels into image
lum.setRGB(i, j, newPixel);

}
}

return lum;

}

// Get binary treshold using Otsu's method
private static int otsuTreshold(BufferedImage original) {

int[] histogram = imageHistogram(original);
int total = original.getHeight() * original.getWidth();

float sum = 0;
for(int i=0; i<100; i++) sum += i * histogram[i];

float sumB = 0;
int wB = 0;
int wF = 0;

float varMax = 0;
int threshold = 0;

for(int i=0 ; i<100 ; i++) {
wB += histogram[i];
if(wB == 0) continue;
wF = total - wB;

if(wF == 0) break;

sumB += (float) (i * histogram[i]);
float mB = sumB / wB;
float mF = (sum - sumB) / wF;

float varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF);

if(varBetween > varMax) {
varMax = varBetween;
threshold = i;
}
}

return threshold;

}

private static BufferedImage binarize(BufferedImage original) {

int red;
int newPixel;

int threshold = otsuTreshold(original);

BufferedImage binarized = new BufferedImage(original.getWidth(), original.getHeight(), original.getType());

for(int i=0; i<original.getWidth(); i++) {
for(int j=0; j<original.getHeight(); j++) {

// Get pixels
red = new Color(original.getRGB(i, j)).getRed();
int alpha = new Color(original.getRGB(i, j)).getAlpha();
if(red > threshold) {
newPixel = 100;
}
else {
newPixel = 0;
}
newPixel = colorToRGB(alpha, newPixel, newPixel, newPixel);
binarized.setRGB(i, j, newPixel);

}
}

return binarized;

}

// Convert R, G, B, Alpha to standard 8 bit
private static int colorToRGB(int alpha, int red, int green, int blue) {

int newPixel = 0;
newPixel += alpha;
newPixel = newPixel << 8;
newPixel += red; newPixel = newPixel << 8;
newPixel += green; newPixel = newPixel << 8;
newPixel += blue;

return newPixel;

}

}

最佳答案

它们是不同的问题:

  • 如果在方法 toGray 中对权重系数求和,您会发现总和不是 1。查看 CIE 页面上的系数(精度更高,总和为 1) .
  • 用同样的方法,您创建了一个新的灰度图像,但您使用与原始图像相同的编码,这是一个彩色图像。类型应为 TYPE_BYTE_GRAY
  • 在您的方法直方图中,您实例化了 100 个元素。您使用的灰度图像通常编码为 256 个灰度级,但也可以是 65536 个。
  • 我没有相同的方法来计算 Otsu 阈值。看一下 ImageJ 源代码,您将找到正确的方法。

总体评价:您使用getRGB 来访问像素值,这是一个糟糕的方法。使用 getRaster().getSample 代替(更快更容易),或者最快的方法是访问 DataBuffer

关于java - java中的大津阈值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34358364/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com