当前位置:   article > 正文

OpenCV图像处理实际案例(一)---图像倾斜矫正(仿射变换)和去边(轮廓查找+ROI提取)_图像倾斜校正例图

图像倾斜校正例图

本博客算法及代码参考自贾志刚老师的《OpenCV图像处理-小案例实战》,若涉及侵权问题,望通知,会第一时间删除。

算法功能:

        1.图像角度倾斜矫正 (基于仿射变换)

         2.去掉多余的边(轮廓查找+ROI提取)

原始图像如下:

算法思路:

       一、进行图像角度纠正

       二、取出ROI区域,去掉多余的白边

代码实现:

  1. /*
  2. =======图像旋转+切边=======
  3. */
  4. #include <opencv2/opencv.hpp>
  5. #include <iostream>
  6. #include <math.h>
  7. using namespace cv;
  8. using namespace std;
  9. Mat Check_Skew(Mat&);
  10. void FindROI(Mat&);
  11. int threshold_value = 100;
  12. int max_level = 255;
  13. const char* output_win = "Contours Result";
  14. const char* roi_win = "Final Result";
  15. int main(int argc, char** argv) {
  16. Mat src = imread("D:/VS2015_Projects/opencv_workspace/img/img_skew.jpg");
  17. if (src.empty()) {
  18. printf("could not load image...\n");
  19. return -1;
  20. }
  21. namedWindow("input image", CV_WINDOW_AUTOSIZE);
  22. imshow("input image", src);
  23. namedWindow(output_win, CV_WINDOW_AUTOSIZE);
  24. Mat img_skew = Check_Skew(src);
  25. // namedWindow(roi_win, CV_WINDOW_AUTOSIZE);
  26. //createTrackbar("Threshold:", output_win, &threshold_value, max_level, FindROI);
  27. FindROI(img_skew);
  28. waitKey(0);
  29. return 0;
  30. }
  31. //角度矫正
  32. Mat Check_Skew(Mat& src) {
  33. Mat gray_src,canny_output;
  34. cvtColor(src, gray_src, COLOR_BGR2GRAY);
  35. //边缘检测
  36. Canny(gray_src, canny_output, threshold_value, threshold_value * 2, 3, false);
  37. //轮廓查找
  38. vector<vector<Point>> contours;
  39. vector<Vec4i> hireachy;
  40. findContours(canny_output, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
  41. Mat drawImg = Mat::zeros(src.size(), CV_8UC3);
  42. float maxw = 0;
  43. float maxh = 0;
  44. double degree = 0;
  45. //角度获取
  46. for (size_t t = 0; t < contours.size(); t++) {
  47. RotatedRect minRect = minAreaRect(contours[t]);
  48. degree = abs(minRect.angle);
  49. if (degree > 0) {
  50. maxw = max(maxw, minRect.size.width);
  51. maxh = max(maxh, minRect.size.height);
  52. }
  53. }
  54. //轮廓绘制
  55. RNG rng(12345);
  56. for (size_t t = 0; t < contours.size(); t++) {
  57. RotatedRect minRect = minAreaRect(contours[t]);
  58. if (maxw == minRect.size.width && maxh == minRect.size.height) {
  59. degree = minRect.angle;
  60. Point2f pts[4];
  61. minRect.points(pts);
  62. Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
  63. for (int i = 0; i < 4; i++) {
  64. line(drawImg, pts[i], pts[(i + 1) % 4], color, 2, 8, 0);
  65. }
  66. }
  67. }
  68. printf("max contours width : %f\n", maxw);
  69. printf("max contours height : %f\n", maxh);
  70. printf("max contours angle : %f\n", degree);
  71. imshow(output_win, drawImg);
  72. //获得旋转矩阵
  73. Point2f center(src.cols / 2, src.rows / 2);
  74. Mat rotm = getRotationMatrix2D(center, degree, 1.0);
  75. //旋转图像
  76. Mat dst;
  77. warpAffine(src, dst, rotm, src.size(), INTER_LINEAR, 0, Scalar(255, 255, 255));
  78. //显示结果
  79. imshow("Correct Image", dst);
  80. return dst;
  81. }
  82. //去边
  83. void FindROI(Mat& img) {
  84. Mat gray_src;
  85. cvtColor(img, gray_src, COLOR_BGR2GRAY);
  86. //边缘检测
  87. Mat canny_output;
  88. Canny(gray_src, canny_output, threshold_value, threshold_value * 2, 3, false);
  89. //轮廓查找
  90. vector<vector<Point>> contours;
  91. vector<Vec4i> hireachy;
  92. findContours(canny_output, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
  93. //绘制轮廓
  94. int minw = img.cols*0.75;
  95. int minh = img.rows*0.75;
  96. RNG rng(12345);
  97. Mat drawImage = Mat::zeros(img.size(), CV_8UC3);
  98. Rect bbox;
  99. for (size_t t = 0; t < contours.size(); t++) {
  100. //查找可倾斜的最小外接矩
  101. RotatedRect minRect = minAreaRect(contours[t]);
  102. //获得倾斜角度
  103. float degree = abs(minRect.angle);
  104. if (minRect.size.width > minw && minRect.size.height > minh && minRect.size.width < (img.cols - 5)) {
  105. printf("current angle : %f\n", degree);
  106. Point2f pts[4];
  107. minRect.points(pts);
  108. bbox = minRect.boundingRect();
  109. Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
  110. for (int i = 0; i < 4; i++) {
  111. line(drawImage, pts[i], pts[(i + 1) % 4], color, 2, 8, 0);
  112. }
  113. }
  114. }
  115. imshow(output_win, drawImage);
  116. //提取ROI区域
  117. if (bbox.width > 0 && bbox.height > 0) {
  118. Mat roiImg = img(bbox);
  119. imshow(roi_win, roiImg);
  120. }
  121. return;
  122. }

实现效果

 

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

闽ICP备14008679号