PaperContourDetector.java 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package com.epson.cameracopy.device;
  2. import android.util.Pair;
  3. import org.opencv.core.Mat;
  4. import org.opencv.core.MatOfPoint;
  5. import org.opencv.core.MatOfPoint2f;
  6. import org.opencv.core.Point;
  7. import org.opencv.core.Size;
  8. import org.opencv.imgproc.Imgproc;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. public class PaperContourDetector {
  12. private static final double DETECT_AREA_RATIO = 0.8d;
  13. public static Pair<Point[], Boolean> detectPaperContour(Mat mat) {
  14. List<MatOfPoint> findPaperContourCandidate = findPaperContourCandidate(mat);
  15. if (findPaperContourCandidate.size() <= 0) {
  16. return null;
  17. }
  18. return findPaperRect(mat, findMax(findPaperContourCandidate));
  19. }
  20. public static List<MatOfPoint> findPaperContourCandidate(Mat mat) {
  21. Mat mat2 = new Mat();
  22. Imgproc.Canny(mat, mat2, 1.0d, 120.0d);
  23. Mat mat3 = new Mat();
  24. Imgproc.morphologyEx(mat2, mat2, 4, mat3, new Point(-1.0d, -1.0d), 1);
  25. mat3.release();
  26. ArrayList arrayList = new ArrayList();
  27. Mat mat4 = new Mat();
  28. Imgproc.findContours(mat2, arrayList, mat4, 1, 4);
  29. mat4.release();
  30. mat2.release();
  31. return arrayList;
  32. }
  33. private static MatOfPoint findMax(List<MatOfPoint> list) {
  34. double d = 0.0d;
  35. MatOfPoint matOfPoint = null;
  36. for (MatOfPoint next : list) {
  37. if (next.cols() * next.rows() >= 4) {
  38. double contourArea = Imgproc.contourArea(next);
  39. if (contourArea > d) {
  40. matOfPoint = next;
  41. d = contourArea;
  42. }
  43. }
  44. }
  45. return matOfPoint;
  46. }
  47. private static Pair<Point[], Boolean> findPaperRect(Mat mat, MatOfPoint matOfPoint) {
  48. boolean z;
  49. if (matOfPoint == null || matOfPoint.rows() < 1 || matOfPoint.cols() < 1) {
  50. return null;
  51. }
  52. MatOfPoint2f matOfPoint2f = new MatOfPoint2f(matOfPoint.toArray());
  53. MatOfPoint2f matOfPoint2f2 = new MatOfPoint2f();
  54. for (int i = 300; i >= 100; i -= 100) {
  55. Imgproc.approxPolyDP(matOfPoint2f, matOfPoint2f2, i, true);
  56. if (matOfPoint2f2.rows() * matOfPoint2f2.cols() >= 4) {
  57. break;
  58. }
  59. }
  60. matOfPoint2f.release();
  61. Point[] array = matOfPoint2f2.toArray();
  62. MatOfPoint matOfPoint2 = new MatOfPoint(array);
  63. if (array.length == 4) {
  64. matOfPoint2f2.release();
  65. boolean isContourConvex = Imgproc.isContourConvex(matOfPoint2);
  66. matOfPoint2.release();
  67. if (!isContourConvex) {
  68. return null;
  69. }
  70. Size size = mat.size();
  71. double d = size.width;
  72. double d2 = size.height;
  73. int length = array.length;
  74. double d3 = 0.0d;
  75. double d4 = d2;
  76. double d5 = 0.0d;
  77. double d6 = d;
  78. int i2 = 0;
  79. while (true) {
  80. if (i2 >= length) {
  81. z = true;
  82. break;
  83. }
  84. Point point = array[i2];
  85. int i3 = i2;
  86. if (size.width <= 1.0d && size.height <= 1.0d) {
  87. z = false;
  88. break;
  89. }
  90. if (d6 > point.f432x) {
  91. d6 = point.f432x;
  92. }
  93. if (d3 < point.f432x) {
  94. d3 = point.f432x;
  95. }
  96. if (d4 > point.f433y) {
  97. d4 = point.f433y;
  98. }
  99. if (d5 < point.f433y) {
  100. d5 = point.f433y;
  101. }
  102. i2 = i3 + 1;
  103. }
  104. if (z) {
  105. z = (d3 - d6) / size.width >= DETECT_AREA_RATIO || (d5 - d4) / size.height >= DETECT_AREA_RATIO;
  106. }
  107. return new Pair<>(array, Boolean.valueOf(z));
  108. }
  109. int length2 = array.length;
  110. return null;
  111. }
  112. }