summaryrefslogtreecommitdiff
path: root/src/main/java/info/selflearner/ocr_telegram/util/OCR.java
blob: 55e577fa90ba78e8f54d43945ef8aec8d803fa5d (plain)
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;
    }

}