当前位置:   article > 正文

OpenCV透视变换示例

OpenCV透视变换示例

公众号推送看到的

由于深度学习平时训练的是pytorch框架的东西  传统opencv处理图像用的非常少

温故而知新

示例入下图

 把这本书矫正

做法是

先缩小图二分之一,高斯模糊+边缘检测+膨胀 去噪(图像噪点基本没有 所有参数看不出好坏),找轮廓,找出面积最大的那个矩形轮廓,确定四个点的映射顺序,透视变换

结果

完整代码

  1. //
  2. // Created by smallflyfly on 2022/10/12.
  3. //
  4. #include <opencv2/opencv.hpp>
  5. using namespace std;
  6. using namespace cv;
  7. const static double AREA_FILTER = 1000.0;
  8. void showIm(const Mat& im) {
  9. imshow("im", im);
  10. waitKey(0);
  11. destroyAllWindows();
  12. }
  13. void drawPoints(const Mat& im, vector<Point> points) {
  14. int index = 1;
  15. for (Point& point : points) {
  16. circle(im, point, 5, Scalar(0, 255, 255), FILLED);
  17. putText(im, to_string(index++), point, FONT_HERSHEY_COMPLEX, 4, Scalar(255, 0, 255), 4);
  18. }
  19. showIm(im);
  20. }
  21. void preProcess(Mat& im) {
  22. cvtColor(im, im, CV_BGR2GRAY);
  23. GaussianBlur(im, im, Size(3, 3), 3, 0);
  24. Canny(im, im, 25, 75);
  25. Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
  26. dilate(im, im, kernel);
  27. // showIm(im);
  28. }
  29. vector<Point> getContours(const Mat &im) {
  30. vector<vector<Point>> contours;
  31. findContours(im, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
  32. vector<Vec4i> hierarchy;
  33. findContours(im, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE);
  34. // vector<vector<Point>> conPoly(contours.size());
  35. vector<Rect> boundRect(contours.size());
  36. vector<Point> biggest;
  37. double maxArea = 0.0;
  38. for (auto &contour : contours) {
  39. vector<Point> conPoly;
  40. double area = contourArea(contour);
  41. if (area > AREA_FILTER) {
  42. double peri = arcLength(contour, true);
  43. approxPolyDP(contour, conPoly, 0.02*peri, true);
  44. if (area > maxArea && conPoly.size() == 4) {
  45. maxArea = area;
  46. biggest = {conPoly[0]*2, conPoly[1]*2, conPoly[2]*2, conPoly[3]*2};
  47. }
  48. }
  49. }
  50. return biggest;
  51. }
  52. Mat getWarp(const Mat& imOrigin, vector<Point> points) {
  53. Mat warpIm;
  54. Point2f src[4] = {points[0], points[1], points[2], points[3]};
  55. Point2f dst[4] = {{0.0, 0.0}, {0.0, 320.0}, {320.0, 320.0}, {320.f, 0.0}};
  56. Mat mat = getPerspectiveTransform(src, dst);
  57. warpPerspective(imOrigin, warpIm, mat, Point(320, 320));
  58. return warpIm;
  59. }
  60. int main() {
  61. Mat imgOrigin = imread("warp-image.jpg");
  62. showIm(imgOrigin);
  63. Mat resizeIm;
  64. resize(imgOrigin, resizeIm, Size(), 0.5, 0.5);
  65. preProcess(resizeIm);
  66. vector<Point> recPoints = getContours(resizeIm);
  67. drawPoints(imgOrigin, recPoints);
  68. // reOrderPoints(recPoints);
  69. Mat imWrap = getWarp(imgOrigin, recPoints);
  70. showIm(imWrap);
  71. return 0;
  72. }

 原文做了点的重排列

我是根据显示图像点顺序确定四个点的顺序

原文链接

在 C++ 中使用 OpenCV 对图像中的对象进行扭曲透视

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/153445
推荐阅读
相关标签
  

闽ICP备14008679号