doc_cropper.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #include "native_structs.h"
  2. //#include "opencv2/core/types_c.h"
  3. //#include "opencv2/core/core_c.h"
  4. #include <opencv2/opencv.hpp>
  5. //#include <opencv2/imgproc/imgproc.hpp>
  6. //#include <algorithm>
  7. static void captureDoc(std::vector<cv::Point> &points, cv::Mat &input, cv::Mat &output)
  8. {
  9. assert(points.size() == 4);
  10. cv::Point ptTopLeft = points[0];
  11. cv::Point ptTopRight = points[1];
  12. cv::Point ptBottomLeft = points[2];
  13. cv::Point ptBottomRight = points[3];
  14. float w1 = sqrt(pow(ptBottomRight.x - ptBottomLeft.x, 2) + pow(ptBottomRight.x - ptBottomLeft.x, 2));
  15. float w2 = sqrt(pow(ptTopRight.x - ptTopLeft.x, 2) + pow(ptTopRight.x - ptTopLeft.x, 2));
  16. float h1 = sqrt(pow(ptTopRight.y - ptBottomRight.y, 2) + pow(ptTopRight.y - ptBottomRight.y, 2));
  17. float h2 = sqrt(pow(ptTopLeft.y - ptBottomLeft.y, 2) + pow(ptTopLeft.y - ptBottomLeft.y, 2));
  18. float maxWidth = (w1 < w2) ? w1 : w2;
  19. float maxHeight = (h1 < h2) ? h1 : h2;
  20. cv::Point2f src[4], dst[4];
  21. src[0].x = ptTopLeft.x;
  22. src[0].y = ptTopLeft.y;
  23. src[1].x = ptTopRight.x;
  24. src[1].y = ptTopRight.y;
  25. src[2].x = ptBottomRight.x;
  26. src[2].y = ptBottomRight.y;
  27. src[3].x = ptBottomLeft.x;
  28. src[3].y = ptBottomLeft.y;
  29. dst[0].x = 0;
  30. dst[0].y = 0;
  31. dst[1].x = maxWidth - 1;
  32. dst[1].y = 0;
  33. dst[2].x = maxWidth - 1;
  34. dst[2].y = maxHeight - 1;
  35. dst[3].x = 0;
  36. dst[3].y = maxHeight - 1;
  37. cv::Mat undistorted = cv::Mat(cv::Size(maxWidth, maxHeight), CV_8UC4);
  38. cv::warpPerspective(input, undistorted, cv::getPerspectiveTransform(src, dst), cv::Size(maxWidth, maxHeight));
  39. output = undistorted;
  40. undistorted.release();
  41. }
  42. extern "C" __attribute__((visibility("default"))) __attribute__((used))
  43. bool native_doc_crop(const char *imgPath, const char *outPath, CoordinateArray *coordList) {
  44. int len = coordList->length;
  45. std::vector<cv::Point> points(len);
  46. cv::Mat input = cv::imread(imgPath), croppedImg;
  47. auto width = input.size().width;
  48. auto height = input.size().height;
  49. for (int i = 0; i < len; i++) {
  50. points[i].x = coordList->coordsPtr[i].x * width;
  51. points[i].y = coordList->coordsPtr[i].y * height;
  52. }
  53. captureDoc(points, input, croppedImg);
  54. auto ret = imwrite(outPath, croppedImg);
  55. return ret;
  56. }