findContours 会找到
vector<vector<cv::Point>> contours;
vector<Vec4i> hierarchy;
f4 = Mat::zeros(frame.rows, frame.cols, CV_8UC3);
f5 = Mat::zeros(frame.rows, frame.cols, CV_8UC3);
findContours(f2, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, cv::Point());
int idx=0;
for( ; idx >= 0; idx = hierarchy[idx][0] ){
Scalar color( arc4random()&255, arc4random()&255, arc4random()&255 );
drawContours( f4, contours, idx, color, CV_FILLED, LINE_8, hierarchy );
drawContours( f5, contours, idx, color, 3, LINE_8, hierarchy );
}
// drawContours(f5, contours, -1, {0,255,0}, CV_FILLED, LINE_8);
如果在空mat上绘制,先把mat的区域设置好,填充满黑色。
获得轮廓
Moments m = moments(contours[idx]);
质心
int cx = int(m.m10/m.m00);
int cy = int(m.m01/m.m00);
面积 (面积小可以踢掉
m.m00
曲线优化 (epsilon百分比越低,越贴近原轮廓
vector<cv::Point> approxCurve;
double epsilon = 0.002*arcLength(contours[idx], true);
approxPolyDP(contours[idx], approxCurve, epsilon, true);
vector<vector<cv::Point>> poolApproxCurve;
poolApproxCurve.push_back(approxCurve);
drawContours( f5 , poolApproxCurve, 0, color, CV_FILLED, LINE_8 );
将所有点囊括在内
convexHull(contours[idx], approxCurve,false,true);
for (int i=0; i<approxCurve.size(); i++) {
circle(f3, approxCurve[i], 2, Scalar(255),30);
}
外框
cv::Rect r = boundingRect(approxCurve);
rectangle(f5, {r.x,r.y}, {r.x+r.width,r.y+r.height}, color,5);
旋转外框
cv::RotatedRect rr = minAreaRect(approxCurve);
Mat boxPoints2f,boxPointsCov;
boxPoints(rr, boxPoints2f);
boxPoints2f.assignTo(boxPointsCov,CV_32S);
polylines(f5, boxPointsCov, true,color,5);
外切圆
Point2f pot;
float radius;
minEnclosingCircle(approxCurve, pot, radius);
circle(f5, pot, radius, color,5);
外切椭圆
RotatedRect re = fitEllipse(approxCurve);
ellipse(f5, re, color,5);
Vec4f lineData;
fitLine(approxCurve, lineData, DIST_L2, 0, 0.01, 0.01);
int lefty = (-lineData[2]*lineData[1]/lineData[0])+lineData[3];
int righty = ((f5.cols-lineData[2])*lineData[1]/lineData[0])+lineData[3];
line(f5, cv::Point(f5.cols-1,righty),cv::Point(0,lefty), color, 10);
参考:OpenCV C++ 简单小技巧 - 轮廓 (14
参考:opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形
findContours发现轮廓
findContours(
InputOutputArray binImg, //输入8bit图像,0值像素值不变,非0的像素看成1;(变为二值图像)
OutputArrayOfArrays contours,//输出找到的轮廓对象
OutputArray, hierachy// 图像的拓扑结构
int mode, //轮廓返回的模式(RETR_TREE等)
int method,//发现方法(CHAIN_APPROX_SIMPLE等)
Point offset=Point()//轮廓像素的位移(默认没有位移(0, 0))
)
drawContours(
InputOutputArray binImg, // 输出图像
OutputArrayOfArrays contours,//找到的全部轮廓对象
Int contourIdx//轮廓索引号
const Scalar & color,//绘制颜色
int thickness,//绘制线宽
int lineType ,//线的类型(默认8)
InputArray hierarchy,//拓扑结构图
int maxlevel,//最大层数(0只绘制当前的,1表示绘制绘制当前及其内嵌的轮廓)
Point offset=Point()//轮廓位移
)
示例:
#include
using namespace cv;
int main()
{
Mat src,dst;
src = imread("E:/image/image/shape.jpg");
if(src.empty())
{
printf("can not load image \n");
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src);
dst = Mat::zeros(src.size(), CV_8UC3);
blur(src,src,Size(3,3));
cvtColor(src,src,COLOR_BGR2GRAY);
Canny(src, src, 20, 80, 3, false);
std::vector<std::vector<Point>> contours;
std::vector<Vec4i> hierarchy;
findContours(src, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
RNG rng(0);
for(int i = 0; i < contours.size(); i++)
{
Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255));
drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point(0,0));
}
namedWindow("output", CV_WINDOW_AUTOSIZE);
imshow("output",dst);
waitKey();
return 0;
}
参考:opencv3/C++轮廓的提取与筛选
参考:【OpenCV(C++)】查找并绘制图像轮廓