我正在尝试使用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;
}
}
答案 0 :(得分:1)
他们是不同的问题:
toGray
中的权重系数求和,您将看到总和不是1.查看CIE页面上的系数(精度更高,总和为1)。TYPE_BYTE_GRAY
。总体评论:您使用getRGB
来访问像素值,这是一种糟糕的方法。使用getRaster().getSample
代替(更快更容易),或者最快的方法是访问DataBuffer
。