问题描述
当我第一次遇到问题时,我读了这篇文章:Tesseract Doc on Improving Quality。我尝试对图像进行各种转换,并确实获得了一些显着的改进。但是,离合理还有很长的路要走。
这是游戏结果画面看起来像是游戏之外的样子: 这是Tess4J给我的尝试对未经处理的图像进行OCR:
行动后报告
斧头阿玛拉
umermmax Su‘rends’
5公里:Irun
非常规的小胜利
美国陆军Uncnnvermuna’
AocsPTAaLE。 6mm x失败
sscunsn V目标x失败
Failed x参数。可接受
6650 mes 9104
55毫米0K 0毫米0K
21毫米毫米77毫米毫米
39 Mm警告53 Mm警告
u Mm Mwssmg 2 Mm Mwssmg
u谈论欲望0谈论欲望
3武装Vmwc的欲望0武装Vauc的欲望
一个0m:Vauc’s Lust a一个0m:Vauc’es Lust 0安曼欲望0安曼欲望
Flewew Map Em
这很糟糕。这就是我所期望的:
行动后报告
Al Amarah
非常规投降
技能:铁
非常规的小胜利
美国陆军非常规部队
可接受的地面失败
安全目标失败
失败的参数ACCEPTABLE
6650分9104
56位男士可以0位男士可以
21人被杀77人被杀
39人受伤53人受伤
0名男子失踪2名男子失踪
0辆失去的坦克0辆失去的坦克
3辆丢失的装甲车0辆丢失的装甲车
0丢失的其他车辆0丢失的车辆
0飞机丢失0飞机丢失
将鼠标指向评估以获取详细信息
评论地图结束
我做了一些图像处理和实验-您可以在下面的代码中看到其中的一些内容。我发现最好的结果是从转换为灰度,反转,增加对比度和锐化:
哪位得到了我
行动后报告
斧头阿玛拉
Unmrwenmnna的投降
5公里:[run
非常规的小胜利
我们,Unmnvenmona陆军‘
可接受的。地面£3失败
安全M Targzcs 23失败
Failed 53参数。可接受
5550 F'mncs 9104
55人,英国0人,好
21人毫米77人毫米
39名男子受伤52名男子Wuundad
0名男子Mwssmg 2名男子Mwssmg
u坦克毫秒:0坦克毫秒:
3装甲Vehwc的毫秒:0装甲Vamcx毫秒:
0 Omar Vamcxes毫秒:0 Omar Vamcxes毫秒:
0安曼毫秒:0安曼毫秒:
嗯,嗯哼,嗯,我是笨蛋
‘Flewew Map E’结束E
我还尝试将引擎模式切换为TessOcrEngineMode.OEM_TESSERACT_CUBE_COMBINED
,但这并没有太大帮助:
行动后报告
Al Amarah
市政厅投降
技能:[运行
非常规的小胜利
我们,陆军UttuoptgeptCiomtl
可接受的。地面£3失败
安全M Targzcs 23失败
Failed 53参数。可接受
5550 F'mncs 9104
55人,英国0人,好
21人毫米77人毫米
39人受伤53人Wuundad
0名男子失踪2名男子失踪
u坦克毫秒:0坦克毫秒:
3装甲维希尔斯ms:0装甲维希尔斯ms:
0 Omar Vehirtles毫秒:0 Omar Vehirtles毫秒:
0安曼毫秒:0安曼毫秒:
mm meuxe u Hummus m详细信息
l查看地图E l结束E
我应该对Tess4J的配置进行哪些更改或更改,以使游戏结束屏幕成功运行OCR?
这是我的代码(请注意,这只是一个测试类,但是我实现了一系列基本的图像处理方法来进行黑白转换,负片,散光,腐蚀,缩放,锐化等操作。
package com.lesliesoftware.tesstest;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.awt.image.RescaleOp;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.lesliesoftware.lcommon.util.StringUtil;
import com.lesliesoftware.lcommon.util.file.FileHelper;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import net.sourceforge.tess4j.ITessAPI.TessOcrEngineMode;
public class cmendScreenProcessImage {
public static void main (String[] args) {
File endScreenImageFile = new File ("P:\\Tesstest\\test\\CombatMissionEndScreen2019.07.03.png");
Tesseract tesseract = new Tesseract ();
try {
// Process the image
// Read the raw image
BufferedImage imageData = ImageIO.read (endScreenImageFile);
boolean preProcessImage = true;
if (preProcessImage) {
File intermediateFile = endScreenImageFile;
imageData = convertimageToGreyScale (imageData);
intermediateFile = writeNewImageFile (intermediateFile,"_GreyScale",imageData);
imageData = convertimageToNegative (imageData);
intermediateFile = writeNewImageFile (intermediateFile,"_Negative",imageData);
imageData = increaseContrast (imageData,1.2f,0.8f);
intermediateFile = writeNewImageFile (intermediateFile,"_Contrast",imageData);
// imageData = zoomImageBy (imageData,2.0f,2.0f);
// intermediateFile = writeNewImageFile (intermediateFile,"_Zoom",imageData);
// imageData = dilateGrayscaleImage (imageData);
// intermediateFile = writeNewImageFile (intermediateFile,"_Dilate",imageData);
imageData = sharpenImage (imageData);
intermediateFile = writeNewImageFile (intermediateFile,"_Sharpen",imageData);
// imageData = erodeGrayscaleImage (imageData);
// intermediateFile = writeNewImageFile (intermediateFile,"_Erode",imageData);
//
// imageData = erodeGrayscaleImage (imageData);
// intermediateFile = writeNewImageFile (intermediateFile,imageData);
endScreenImageFile = writeNewImageFile (endScreenImageFile,"_Processed",imageData);
System.out.println ("Final image can be found at: " + endScreenImageFile.getAbsolutePath ());
}
// Setup the tesseract object
tesseract.setDatapath ("P:/Tess4J/tessdata");
boolean useCubeCombined = false;
if (useCubeCombined) {
tesseract.setocrEngineMode (TessOcrEngineMode.OEM_TESSERACT_CUBE_COMBINED);
tesseract.setLanguage ("eng");
}
// Run the character recognition
String text = tesseract.doOCR (imageData);
// Output the results
System.out.print (text);
} catch (IOException exception) {
System.out.println ("File IO Error!:");
exception.printstacktrace();
} catch (TesseractException exception) {
System.out.println ("OCR Error!:");
exception.printstacktrace();
}
}
private static BufferedImage sharpenImage (BufferedImage imageData) {
// A 3x3 kernel that sharpens an image
Kernel kernel = new Kernel (3,3,new float[] {
-1,-1,9,-1
});
BufferedImageOp op = new ConvolveOp(kernel);
imageData = op.filter(imageData,null);
return imageData;
}
/**
* This method will perform erosion operation on the grayscale image img.
*
* Code taken from https://github.com/yusufshakeel/Java-Image-Processing-Project/blob/master/DYimageFX-project/src/dyimagefx/morph/Erosion.java
* Except the erode code is really a dilation and the dilation is really an erode so method contents have been swapped here
*
* @param img The image on which erosion operation is performed
*/
public static BufferedImage erodeGrayscaleImage(BufferedImage imageData){
/**
* Dimension of the image img.
*/
int width = imageData.getWidth();
int height = imageData.getHeight();
//buff
int buff[];
//output of dilation
int output[] = new int[width*height];
//perform dilation
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
buff = new int[9];
int i = 0;
for(int ty = y - 1; ty <= y + 1; ty++){
for(int tx = x - 1; tx <= x + 1; tx++){
if(ty >= 0 && ty < height && tx >= 0 && tx < width){
//pixel under the mask
int rgb = imageData.getRGB(tx,ty);
buff[i] = (rgb >> 16) & 0x000000FF;;
// buff[i] = imageData.getRed(tx,ty);
i++;
}
}
}
//sort buff
java.util.Arrays.sort(buff);
//save highest value
output[x+y*width] = buff[8];
}
}
/**
* Save the dilation value in image img.
*/
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
int v = output[x+y*width];
Color colour = new Color (v,v,v);
imageData.setRGB (x,y,colour.getRGB ());
// imageData.setPixel(x,255,v);
}
}
return imageData;
}
/**
* This method will perform dilation operation on the grayscale image img.
*
* Code taken from https://github.com/yusufshakeel/Java-Image-Processing-Project/blob/master/DYimageFX-project/src/dyimagefx/morph/dilation.java
* Except the erode code is really a dilation and the dilation is really an erode so method contents have been swapped here
*
* @param img The image on which dilation operation is performed
*/
public static BufferedImage dilateGrayscaleImage(BufferedImage imageData){
/**
* Dimension of the image img.
*/
int width = imageData.getWidth();
int height = imageData.getHeight();
//buff
int buff[];
//output of erosion
int output[] = new int[width*height];
//perform erosion
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
buff = new int[9];
int i = 0;
for(int ty = y - 1; ty <= y + 1; ty++){
for(int tx = x - 1; tx <= x + 1; tx++){
/**
* 3x3 mask [kernel or structuring element]
* [1,1,1
* 1,1]
*/
if(ty >= 0 && ty < height && tx >= 0 && tx < width){
//pixel under the mask
int rgb = imageData.getRGB(tx,ty);
i++;
}
}
}
//sort buff
java.util.Arrays.sort(buff);
//save lowest value
output[x+y*width] = buff[9-i];
}
}
/**
* Save the erosion value in image img.
*/
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
int v = output[x+y*width];
Color colour = new Color (v,v);
}
}
return imageData;
}
private static BufferedImage increaseContrast (BufferedImage imageData,float brighten,float offset) throws IOException {
// Create the RescaleOP object
RescaleOp rescale = new RescaleOp (brighten,offset,null);
// Perform the scaling operation - increase brightness
BufferedImage contrastimageData = rescale.filter (imageData,null);
return contrastimageData;
}
private static BufferedImage zoomImageBy (BufferedImage imageData,float xScale,float yScale) throws IOException {
// Make an empty image buffer to store image later
int zoomWidth = (int)(imageData.getWidth () * xScale);
int zoomHight = (int)(imageData.getHeight () * yScale);
BufferedImage zoomImageData = new BufferedImage (zoomWidth,zoomHight,imageData.getType ());
// Creating a 2D platform on the buffer image for drawing the new image
Graphics2D graphic = zoomImageData.createGraphics ();
// Draw new image starting from 0 0 to the zoomed image size
graphic.drawImage (imageData,zoomWidth,null);
graphic.dispose ();
return zoomImageData;
}
public static File writeNewImageFile (File inputimageFile,String additionToName,BufferedImage zoomImageData) throws IOException {
// Append additionToName to the original file name
String rootFileNameStr = FileHelper.getFileName (inputimageFile);
String rootFileNameExt = FileHelper.getFileExtension (inputimageFile);
File outputimageFile = new File (inputimageFile.getParentFile (),rootFileNameStr + additionToName + StringUtil.DOT + rootFileNameExt);
// Write the modified image
ImageIO.write(zoomImageData,rootFileNameExt,outputimageFile);
return outputimageFile;
}
private static BufferedImage convertimageToNegative (BufferedImage imageData) throws IOException {
// Loop for each pixel to convert to negative using the algorithm from https://www.geeksforgeeks.org/image-processing-java-set-4-colored-image-negative-image-conversion/?ref=lbp
int width = imageData.getWidth();
int height = imageData.getHeight();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int p = imageData.getRGB(x,y);
int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;
//subtract RGB from 255
r = 255 - r;
g = 255 - g;
b = 255 - b;
//set new RGB value
p = (a<<24) | (r<<16) | (g<<8) | b;
imageData.setRGB(x,p);
}
}
return imageData;
}
private static BufferedImage convertimageToGreyScale (BufferedImage imageData) throws IOException {
// Loop for each pixel to convert to greyscale - using algorithm from https://www.geeksforgeeks.org/image-processing-in-java-set-3-colored-image-to-greyscale-image-conversion/?ref=lbp
int width = imageData.getWidth();
int height = imageData.getHeight();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// Here (x,y) denotes the coordinate of image for modifying the pixel value.
int p = imageData.getRGB(x,y);
int a = (p>>24)&0xff;
int r = (p>>16)&0xff;
int g = (p>>8)&0xff;
int b = p&0xff;
// calculate average
int avg = (r+g+b)/3;
// replace RGB value with avg
p = (a<<24) | (avg<<16) | (avg<<8) | avg;
imageData.setRGB(x,p);
}
}
return imageData;
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)