OpenCvService.java 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. package com.mokasz.pool.image.algorithm;
  2. import org.bytedeco.javacpp.Loader;
  3. import org.bytedeco.opencv.opencv_java;
  4. import org.opencv.core.Mat;
  5. import org.opencv.core.MatOfByte;
  6. import org.opencv.img_hash.PHash;
  7. import org.opencv.imgcodecs.Imgcodecs;
  8. import org.springframework.stereotype.Service;
  9. @Service
  10. public class OpenCvService {
  11. // 静态初始化 OpenCV
  12. static {
  13. Loader.load(opencv_java.class);
  14. }
  15. private final PHash pHash = PHash.create();
  16. public static final int HashLength = 8;
  17. private static void transformMatToArrayOfFloat(Mat mat, float[] floats) {
  18. if (mat.width() != HashLength || mat.height() != 1) {
  19. throw new RuntimeException("Matrix dimension is not 1x8");
  20. }
  21. for (int i = 0; i < HashLength; i++) {
  22. floats[i] = (float) mat.get(0, i)[0];
  23. }
  24. }
  25. public void calculatePHash(byte[] fileBytes, float[] vector) {
  26. Mat input = Imgcodecs.imdecode(new MatOfByte(fileBytes), Imgcodecs.IMREAD_UNCHANGED);
  27. Mat output = new Mat();
  28. pHash.compute(input, output);
  29. transformMatToArrayOfFloat(output, vector);
  30. }
  31. public void transformBinaryArray(float[] octets, float[] binaries) {
  32. for (int i = 0; i < HashLength; i++) {
  33. for (int j = 0; j < HashLength; j++) {
  34. int v = (int) octets[i];
  35. binaries[i * HashLength + j] = (v & (1 << j)) >> j;
  36. }
  37. }
  38. }
  39. public String getReadableHash(float[] floats) {
  40. StringBuilder stringBuilder = new StringBuilder();
  41. for (int i = 0; i < HashLength; i++) {
  42. stringBuilder.append(String.format("%02X", (int) floats[i]));
  43. }
  44. return stringBuilder.toString();
  45. }
  46. }