1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
package info.selflearner.ocr_telegram.util;
import info.selflearner.ocr_telegram.exception.PassportNotFoundException;
import info.selflearner.ocr_telegram.model.Passport;
import net.sourceforge.tess4j.*;
import net.sourceforge.tess4j.util.LoadLibs;
import org.json.JSONArray;
import org.json.JSONObject;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class OCR {
private static final ITesseract TESSERACT = new Tesseract();
static {
TESSERACT.setDatapath("src/main/resources/tessdata/");
TESSERACT.setVariable("user_defined_dpi", "300");
System.setProperty("java.library.path", LoadLibs.extractTessResources("win32-x86-64").getPath());
}
public static String perform(File file, String languages) throws TesseractException {
TESSERACT.setLanguage(languages);
String ocrResult = TESSERACT.doOCR(file);
file.delete();
return ocrResult;
}
public static Passport performPassport(File file) throws IOException, InterruptedException, PassportNotFoundException {
for (int imageRotateAngle = 0; imageRotateAngle <= 270; imageRotateAngle += 90) {
if (imageRotateAngle == 90) {
System.out.println("Rotating image to 90 degrees...");
rotateImageVertically(file, true);
} else if (imageRotateAngle == 180) {
System.out.println("Rotating image to 180 degrees...");
rotateImageHorizontally(file);
} else if (imageRotateAngle == 270) {
System.out.println("Rotating image to 270 degrees...");
rotateImageVertically(file, false);
}
Runtime.getRuntime().exec(new String[]{"surya_ocr", file.getPath(), "--results_dir", System.getProperty("java.io.tmpdir"), "--langs=en"}).waitFor();
JSONArray jsonTextLines = new JSONObject(Files.readAllLines(Path.of(System.getProperty("java.io.tmpdir"), "/", file.getName().split("\\.")[0], "/results.json")).getFirst())
.getJSONArray(file.getName().split("\\.")[0]).getJSONObject(0).getJSONArray("text_lines");
int mrzStartingIndex = -1;
for (int arrayIndex = 0; arrayIndex < jsonTextLines.length() && mrzStartingIndex == -1; arrayIndex++) {
if (jsonTextLines.getJSONObject(arrayIndex).getString("text").indexOf("P<") == 0) {
mrzStartingIndex = arrayIndex;
}
}
if (mrzStartingIndex != -1) {
System.out.println("MRZ1: " + jsonTextLines.getJSONObject(mrzStartingIndex).getString("text"));
System.out.println("MRZ2: " + jsonTextLines.getJSONObject(mrzStartingIndex + 1).getString("text"));
try {
return new Passport(new String[]{jsonTextLines.getJSONObject(mrzStartingIndex).getString("text"), jsonTextLines.getJSONObject(mrzStartingIndex + 1).getString("text")},
new int[]{(int) (jsonTextLines.getJSONObject(mrzStartingIndex).getDouble("confidence") * 100), (int) (jsonTextLines.getJSONObject(mrzStartingIndex + 1).getDouble("confidence") * 100)});
} catch (Exception _) {
}
}
}
throw new PassportNotFoundException("Passport not found");
}
private static void rotateImageVertically(File image, boolean counterClockwise) throws IOException {
BufferedImage bufferedImage = ImageIO.read(image);
BufferedImage output = new BufferedImage(bufferedImage.getHeight(), bufferedImage.getWidth(), bufferedImage.getType());
AffineTransform affineTransform = getAffineTransform(counterClockwise, bufferedImage);
AffineTransformOp affineTransformOp = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR);
affineTransformOp.filter(bufferedImage, output);
ImageIO.write(output, "jpg", image);
}
public static void rotateImageHorizontally(File image) throws IOException {
BufferedImage imageToRotate = ImageIO.read(image);
int widthOfImage = imageToRotate.getWidth();
int heightOfImage = imageToRotate.getHeight();
int typeOfImage = imageToRotate.getType();
BufferedImage output = new BufferedImage(widthOfImage, heightOfImage, typeOfImage);
Graphics2D graphics2D = output.createGraphics();
graphics2D.rotate(Math.toRadians(180), widthOfImage / 2.0, heightOfImage / 2.0);
graphics2D.drawImage(imageToRotate, null, 0, 0);
ImageIO.write(output, "jpg", image);
}
private static AffineTransform getAffineTransform(boolean counterClockwise, BufferedImage bufferedImage) {
int imageWidth = bufferedImage.getWidth();
int imageHeight = bufferedImage.getHeight();
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate((!counterClockwise ? Math.PI : -Math.PI) / 2, imageWidth / 2.0, imageHeight / 2.0);
double offset = (imageWidth - imageHeight) / 2.0;
if (!counterClockwise) {
affineTransform.translate(offset, offset);
} else {
affineTransform.translate(-offset, -offset);
}
return affineTransform;
}
}
|