Pārlūkot izejas kodu

Refactor: 抽取opencv相关操作

wudi 5 gadi atpakaļ
vecāks
revīzija
a33e7caa16

+ 50 - 0
src/main/java/com/mokasz/image_pool/algorithm/OpenCvService.java

@@ -0,0 +1,50 @@
+package com.mokasz.image_pool.algorithm;
+
+import org.bytedeco.javacpp.Loader;
+import org.bytedeco.opencv.opencv_java;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfByte;
+import org.opencv.img_hash.PHash;
+import org.opencv.imgcodecs.Imgcodecs;
+
+public class OpenCvService {
+    // 静态初始化 OpenCV
+    static {
+        Loader.load(opencv_java.class);
+    }
+    private final PHash pHash = PHash.create();
+    public static final int HashLength = 8;
+
+    private static void transformMatToArrayOfFloat(Mat mat, float[] floats) {
+        if (mat.width() != HashLength || mat.height() != 1) {
+            throw new RuntimeException("Matrix dimension is not 1x8");
+        }
+        for (int i = 0; i < HashLength; i++) {
+            floats[i] = (float) mat.get(0, i)[0];
+        }
+    }
+
+    public void calculatePHash (byte[] fileBytes, float[] vector) {
+        Mat input = Imgcodecs.imdecode(new MatOfByte(fileBytes), Imgcodecs.IMREAD_UNCHANGED);
+        Mat output = new Mat();
+        pHash.compute(input, output);
+        transformMatToArrayOfFloat(output, vector);
+    }
+
+    public void transformBinaryArray(float[] octets, float[] binaries) {
+        for (int i = 0; i < HashLength; i++) {
+            for (int j = 0; j < HashLength; j++) {
+                int v = (int) octets[i];
+                binaries[i * 8 + j] = (v & (1 << j)) >> j;
+            }
+        }
+    }
+
+    public String getReadableHash(float[] floats) {
+        StringBuilder stringBuilder = new StringBuilder();
+        for (int i = 0; i < HashLength; i++) {
+            stringBuilder.append(String.format("%02X", (int) floats[i]));
+        }
+        return stringBuilder.toString();
+    }
+}