0
点赞
收藏
分享

微信扫一扫

OpenCV + CPP 系列(廿七)轮廓(拟合)包围框(矩形框、圆形框)


文章目录

  • ​​一、函数介绍​​
  • ​​approxPolyDP,boundingRect,minEnclosingCircle​​
  • ​​拟合函数 fitEllipse、minAreaRect​​
  • ​​二、演示​​

​​OpenCV—Python 轮廓检测 绘出矩形框(findContours\ boundingRect\rectangle)​​

一、函数介绍

approxPolyDP,boundingRect,minEnclosingCircle

多边形逼近:基于RDP算法实现, 以指定的精度逼近多边形曲线,目的是减少多边形轮廓点数。函数签名如下:


InputArray curve,       存储在 std::vector 或Mat中的二维点的输入向量

OutputArray approxCurve,   近似的结果。类型应与输入曲线的类型相匹配。


double epsilon,        指定近似精度的参数。这是原始曲线与其近似值之间的最大距离。


bool closed         如果为真,则近似曲线是闭合的


)


矩形包围框,返回 Rect (左上角,右下角),


Rect boundingRect( InputArray array

);


minEnclosingCircle:顾名思义,最小包围圆,


InputArray points,      二维点的输入向量,存储在 std::vector<> 或Mat

CV_OUT Point2f& center,   输出圆心


CV_OUT float& radius    输出圆半径


);


拟合函数 fitEllipse、minAreaRect

拟合椭圆,围绕一组 2D 点拟合椭圆。该函数计算最适合(在最小二乘意义上)一组 2D 点的椭圆。它返回椭圆内切的旋转矩形。由于数据点靠近包含Mat元素的边界,因此返回的ellipse/rotatedRect 数据可能包含负索引。


RotatedRect fitEllipse( InputArray points

);


最小面积矩形 , 查找包含输入 2D 点集的最小区域的旋转矩形。该函数计算并返回指定点集的最小面积边界矩形(可能已旋转)。当数据接近包含的Mat元素边界时,返回的RotatedRect可以包含负索引。


RotatedRect minAreaRect( InputArray points

);


二、演示

实现流程

  1. 首先把图像从RGB转为灰度
  2. 二值图像
  3. 去除二值化图像的零星点(可选)
  4. 在通过发现轮廓得到候选点
  5. 凸包API调用
  6. 绘制显示。

void QuickDemo::boundbox_Demo(Mat& image) {
Mat gray_img, bin_img, drawImg;
vector<vector<Point>> contours;

cvtColor(image, gray_img, COLOR_BGR2GRAY);
threshold(gray_img, bin_img, 210, 255, THRESH_BINARY_INV);
imshow("bin_img0", bin_img);

// 去除二值化图像的零星点
Mat kernel_ = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));
cv::morphologyEx(bin_img, bin_img, MORPH_CLOSE, kernel_, Point(-1, -1), 2);
imshow("bin_img1", bin_img);


findContours(bin_img, contours, RETR_TREE, CHAIN_APPROX_SIMPLE);
if (contours.size() == 0) { return; }

vector<vector<Point>> contours_ploy(contours.size()); // 逼近多边形点
vector<Rect> ploy_rects(contours.size()); // 多边形框
vector<Point2f> ccs(contours.size()); // 圆中心点
vector<float> radius(contours.size()); // 圆半径

vector<RotatedRect> minRects(contours.size());
vector<RotatedRect> myeliipse(contours.size());

for (size_t i = 0; i < contours.size(); i++) {
approxPolyDP(Mat(contours[i]), contours_ploy[i], 3, true);
ploy_rects[i] = boundingRect(contours_ploy[i]);
minEnclosingCircle(contours_ploy[i], ccs[i], radius[i]);

if (contours_ploy[i].size() > 5) {
myeliipse[i] = fitEllipse(contours_ploy[i]);
minRects[i] = minAreaRect(contours_ploy[i]);
}
}

image.copyTo(drawImg);
RNG rng(1234);
Point2f pts[4];
for (size_t t = 0; t < contours.size(); t++) {
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
rectangle(drawImg, ploy_rects[t], color, 2, 8);
circle(drawImg, ccs[t], radius[t], color, 2, 8);

if (contours_ploy[t].size() > 5) {
ellipse(drawImg, myeliipse[t], color, 1, 8);
minRects[t].points(pts);
for (int r = 0; r < 4; r++) {
line(drawImg, pts[r], pts[(r + 1) % 4], color, 2, 8);
}
}
}
imshow("drawImg", drawImg);
}

OpenCV + CPP 系列(廿七)轮廓(拟合)包围框(矩形框、圆形框)_数据


举报

相关推荐

0 条评论