服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - 使用OpenCV检测图像中的矩形

使用OpenCV检测图像中的矩形

2021-09-16 14:10知来者逆 C/C++

这篇文章主要为大家详细介绍了使用OpenCV检测图像中的矩形,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了OpenCV检测图像中矩形的具体代码,供大家参考,具体内容如下

前言

1.OpenCV没有内置的矩形检测的函数,如果想检测矩形,要自己去实现。
2.我这里使用的OpenCV版本是3.30.

矩形检测

1.得到原始图像之后,代码处理的步骤是:

(1)滤波增强边缘。
(2)分离图像通道,并检测边缘。
(3) 提取轮廓。
(4)使用图像轮廓点进行多边形拟合。
(5)计算轮廓面积并得到矩形4个顶点。
(6)求轮廓边缘之间角度的最大余弦。
(7)画出矩形。

2.代码

  1. //检测矩形
  2. //第一个参数是传入的原始图像,第二是输出的图像。
  3. void findSquares(const Mat& image,Mat &out)
  4. {
  5. int thresh = 50, N = 5;
  6. vector<vector<Point> > squares;
  7. squares.clear();
  8.  
  9. Mat src,dst, gray_one, gray;
  10.  
  11. src = image.clone();
  12. out = image.clone();
  13. gray_one = Mat(src.size(), CV_8U);
  14. //滤波增强边缘检测
  15. medianBlur(src, dst, 9);
  16. //bilateralFilter(src, dst, 25, 25 * 2, 35);
  17.  
  18. vector<vector<Point> > contours;
  19. vector<Vec4i> hierarchy;
  20.  
  21. //在图像的每个颜色通道中查找矩形
  22. for (int c = 0; c < image.channels(); c++)
  23. {
  24. int ch[] = { c, 0 };
  25.  
  26. //通道分离
  27. mixChannels(&dst, 1, &gray_one, 1, ch, 1);
  28.  
  29. // 尝试几个阈值
  30. for (int l = 0; l < N; l++)
  31. {
  32. // 用canny()提取边缘
  33. if (l == 0)
  34. {
  35. //检测边缘
  36. Canny(gray_one, gray, 5, thresh, 5);
  37. //膨脹
  38. dilate(gray, gray, Mat(), Point(-1, -1));
  39. imshow("dilate", gray);
  40. }
  41. else
  42. {
  43. gray = gray_one >= (l + 1) * 255 / N;
  44. }
  45.  
  46. // 轮廓查找
  47. //findContours(gray, contours, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
  48. findContours(gray, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
  49.  
  50. vector<Point> approx;
  51.  
  52. // 检测所找到的轮廓
  53. for (size_t i = 0; i < contours.size(); i++)
  54. {
  55. //使用图像轮廓点进行多边形拟合
  56. approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
  57.  
  58. //计算轮廓面积后,得到矩形4个顶点
  59. if (approx.size() == 4 &&fabs(contourArea(Mat(approx))) > 1000 &&isContourConvex(Mat(approx)))
  60. {
  61. double maxCosine = 0;
  62.  
  63. for (int j = 2; j < 5; j++)
  64. {
  65. // 求轮廓边缘之间角度的最大余弦
  66. double cosine = fabs(angle(approx[j % 4], approx[j - 2], approx[j - 1]));
  67. maxCosine = MAX(maxCosine, cosine);
  68. }
  69.  
  70. if (maxCosine < 0.3)
  71. {
  72. squares.push_back(approx);
  73. }
  74. }
  75. }
  76. }
  77. }
  78.  
  79. for (size_t i = 0; i < squares.size(); i++)
  80. {
  81. const Point* p = &squares[i][0];
  82.  
  83. int n = (int)squares[i].size();
  84. if (p->x > 3 && p->y > 3)
  85. {
  86. polylines(out, &p, &n, 1, true, Scalar(0, 255, 0), 3, LINE_AA);
  87. }
  88. }
  89. imshow("dst",out);
  90. }
  91.  
  92. static double angle(Point pt1, Point pt2, Point pt0)
  93. {
  94. double dx1 = pt1.x - pt0.x;
  95. double dy1 = pt1.y - pt0.y;
  96. double dx2 = pt2.x - pt0.x;
  97. double dy2 = pt2.y - pt0.y;
  98. return (dx1*dx2 + dy1*dy2) / sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
  99. }

3.运行结果

使用OpenCV检测图像中的矩形

使用OpenCV检测图像中的矩形

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

原文链接:https://blog.csdn.net/matt45m/article/details/95753563

延伸 · 阅读

精彩推荐