OpenCV学习三十:approxPolyDP 多边拟合函数

approxPolyDP 主要功能是把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合。

原理图:对比之前黑点连线,之后蓝色连线:

C++: void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)

 

参数详解;

InputArray curve:一般是由图像的轮廓点组成的点集

OutputArray approxCurve:表示输出的多边形点集

double epsilon:主要表示输出的精度,就是另个轮廓点之间最大距离数,5,6,7,,8,,,,,

bool closed:表示输出的多边形是否封闭

 

 
  1. #include <opencv2/opencv.hpp>

  2. #include <stdio.h>

  3. #include <stdlib.h>

  4. #include <iostream>

  5.  
  6.  
  7. using namespace cv;

  8. using namespace std;

  9.  
  10.  
  11. int main(int argc, char** argv)

  12. {

  13. Mat img = imread("4.jpg", -1);

  14. pyrDown(img, img, Size(img.cols/2, img.rows/2), 4);

  15. imshow("img", img);imwrite("img.jpg", img);

  16.  
  17. //通过canny算法找轮廓,这样 findcontours 的结果会好些

  18. Mat canny_out;

  19. Canny(img, canny_out, 45, 127, 3, false);

  20. imshow("canny_out", canny_out);imwrite("canny_out.jpg", canny_out);

  21.  
  22. //寻找轮廓

  23. vector<vector<Point>> contours;

  24. vector<Vec4i> hierachy;

  25. findContours(canny_out, contours, hierachy, RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(-1,-1));

  26. drawContours(img, contours, -1, Scalar(0,0,255), 1, 8, hierachy);

  27.  
  28. //定义圆形、方形、旋转矩形、椭圆的存储容器

  29. vector<vector<Point>> contours_ploy(contours.size());

  30. vector<Rect> rects_ploy(contours.size());

  31. vector<Point2f> circle_centers(contours.size());

  32. vector<float> circle_radius(contours.size());

  33. vector<RotatedRect> RotatedRect_ploy;//注意:由于下面赋值的过程中有个点数大于5的条件,所以这里没有直接初始化,才有下面pushback的方法添加值。

  34. vector<RotatedRect> ellipse_ploy;//注意,这里是画椭圆,但是容器类型是 RotatedRect

  35.  
  36. //将结果放到各自的容器中

  37. for (size_t i = 0; i< contours.size(); i++)

  38. {

  39. approxPolyDP(contours[i], contours_ploy[i], 5, true);

  40. rects_ploy[i] = boundingRect(contours_ploy[i]);

  41. minEnclosingCircle(contours_ploy[i], circle_centers[i], circle_radius[i]);

  42.  
  43. if (contours_ploy[i].size() >5)

  44. {

  45. RotatedRect temp1 = minAreaRect(contours_ploy[i]);

  46. RotatedRect_ploy.push_back(temp1);

  47.  
  48. RotatedRect temp2 = fitEllipse(contours_ploy[i]);

  49. ellipse_ploy.push_back(temp2);

  50. }

  51. }

  52.  
  53. //定义最终绘图的图片

  54. Mat draw_rect(img.size(), img.type(), Scalar::all(0)),

  55. draw_rotateRect(img.size(), img.type(), Scalar::all(0)),

  56. draw_circle(img.size(), img.type(), Scalar::all(0)),

  57. draw_ellipse(img.size(), img.type(), Scalar::all(0));

  58.  
  59. //绘图圆形、矩形

  60. RNG rng(12345);

  61. for (size_t i = 0; i<contours.size(); i++)

  62. {

  63. Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255));

  64. rectangle(draw_rect, rects_ploy[i], color, 1, 8);

  65. circle(draw_circle, circle_centers[i], circle_radius[i], color, 1, 8);

  66. }

  67. imshow("draw_rect", draw_rect);imwrite("draw_rect.jpg", draw_rect);

  68. imshow("draw_circle", draw_circle);imwrite("draw_circle.jpg", draw_circle);

  69.  
  70. //绘图椭圆形、旋转矩形

  71. Point2f pot[4];

  72. for (size_t i = 0; i<ellipse_ploy.size(); i++)

  73. {

  74. Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255));

  75. ellipse(draw_ellipse, ellipse_ploy[i], color, 1, 8);

  76.  
  77. RotatedRect_ploy[i].points(pot);

  78. for(int j=0; j<4; j++)

  79. {

  80. line(draw_rotateRect, pot[j], pot[(j+1)%4], color);

  81. }

  82. }

  83. imshow("draw_ellipse", draw_ellipse);imwrite("draw_ellipse.jpg", draw_ellipse);

  84. imshow("draw_rotateRect", draw_rotateRect);imwrite("draw_rotateRect.jpg", draw_rotateRect);

  85.  
  86.  
  87. waitKey();

  88. return 1;

  89. }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值