1)最小外接圆
轮廓最小外接圆–minEnclosingCircle()
void minEnclosingCircle(InputArray points,CV_OUT Point2f¢er,CV_OUT float&radius);
&&points:输入的二维点集,可以填Mat类型或者std::vector
&¢er:Point2f&类型的center,圆的输出圆心
&&radius:float类型,表示圆的输出半径
//绘制轮廓的外接圆
Mat srcImg=imread("10.png");
imshow("src",srcImg);
Mat dstImg=srcImg.clone();
GaussianBlur(srcImg,srcImg,Size(3,3),0,0);
cvtColor(srcImg,srcImg,CV_BGR2GRAY);
Canny(srcImg,srcImg,100,200);
imshow("Canny",srcImg);
vector<vector<Point>>contours;
vector<Vec4i>hierarcy;
findContours(srcImg,contours,hierarcy,CV_RETR_TREE,CV_CHAIN_APPROX_NONE);
cout<<"num="<<contours.size()<<endl;
vector<Rect>boundRect(contours.size());
vector<RotatedRect>box(contours.size());
Point2f rect[4];
Point2f center;//定义圆的中心坐标
float radius;//定义圆的半径
for(int i=0;i<contours.size();i++)//遍历轮廓
{
minEnclosingCircle(Mat(contours[i],center,radius));
boundRect[i]=boundingRect(Mat(contours[i]));
drawContours(dstImg,contours,i,Scalar(0,0,255),2,8);
circle(dstImg,center,radius,Scalar(0,255,0),2,8);
}
imshow("dst",dstimg);
2)椭圆拟合
轮廓椭圆拟合–fitEllipse()
RatatedRect fitEllipse(InputArray points);
&& points:输入的二维点集,可以填Mat类型,或者std::vector
&&返回值:RotatedRect类旋转矩形对象
//轮廓的椭圆拟合
vector<RotatedRect>box(contours.size());
Point2f rect[4];
for(int i=0;i<contours.size();i++)
{
box[i]=fitEllipse(Mat(contours[i]));
box[i].points(rect);
ellipse(dstImg,boc[i],Scalar(0,255,0),2,8);
}
imshow("dst",dstzImg);
waitKey(0);
3)逼近多边形曲线
逼近多边形曲线–approxPolyDP()
void approxPolyDP(InputArray curve,OutputArray approxCurve,double epsilon,bool closed);
&&curve:输入的二维点集,可以填Mat类型或std::vector
&&approxCurve:多边形逼近的结果,其类型和输入二维点集类型一致
&&epsilon:逼近的精度,为原始曲线和近似曲线间的最大值
&&closed:如果其为真,则近似的曲线为封闭曲线,否则近似的曲线不封闭
//轮廓的多边形逼近
vector<vector<Point>contours_poly(contours.size());
for(int i=0;i<contours.size();i++)
{
approxPolyDP(Mat(contous[i],contours_poly[i],3,true);
drawContours(dstImg,contours,i,Scalar(0,255,255),2,8);
drawContors(dstImg2,contours_poly,i,Scalar(0,255,255),2,8);//绘制多边形逼近
}
imshow("dst",dstImg);
inshow("approx",dstImg2);
waitKey(0);
4)计算轮廓面积
计算轮廓面积–contourArea()
double contourArea(InputArray contour,bool oriented=false);
&&contour:输入的二维点集或轮廓,可以填Mat类型或std::vector
&&oriented:默认值false,表示返回面积为绝对值,负则带符号
&&返回值:double类型返回轮廓面积
5)计算轮廓长度(周长或者曲线长度)
计算轮廓长度 –arcLength()
double arcLength(InputArray curve,bool closed);
&&curve:输入的二维点集,可以填Mat类型或者std::vector
&&colsed:用于指示曲线是否封闭的标识符 ,默认值true,表示曲线封闭
&&返回值:double类型返回轮廓长度
注:contourArea()&&arcLength()可用于轮廓的筛选
vector<vector<Point>>contours;
vector<Vec4i>hierarcy;
findContours(srcImg,contours,hierarcy,CV_RETR_TREE,CV_CHAIN_APPROX_NONE);
cout<<"num="<<contours.size()<<endl;
for(int i=0;i<contours.size();i++)
{
double area=contourArea(contous[i]);
double length=arcLength(contours[i],true);
if(length>300)
drawContours(dstImg,contours,i,Scalar(0,0,255),2,8);
}
imshow("dst",dstImg);
waitKey(0);
6)利用mask提取不规则轮廓
//提取不规则轮廓
Mat srcImg=imread("220。jpg");
imshow("src",srcImg);
Mat dstImg=srcImg.clone();
Mat tempImg=srcImg.clone();//原图备份
Mat tempImg2(srcImg.rows,srcImg.cols,CV_8UC3,Scalar:all(0));
Mat draw(srcImg.rows,srcImg.cols,CV_8UC3,Scalar:all(0));
Mat tempImg3(srcImg,.rows,srcImg.cols,CV_8UC3,Scalar::all(0));
GaussianBlur(srcImg,srcImg,Size(3,3),0,0);
cvtColor(srcImg,srcImg,CV_BGR2GRAY);
threshold(srcImg,srcImg,100,255,CV_THRESH_BINARY);
imshow("threshold",srcImg);
vector<vector<Point>>contours;
vector<Vec4i>hierarcy;
findContours(srcImg,contours,hierarcy,CV_RETR_TREE,CV_CHAIN_APPROX_NONE);
while(1)
{
for(int i=0;i<contours.sizez();i++)
{
tempImg2.copyTo(draw);//每次进入将draw清空为全黑
tempImg2.copyTo(tempImg3);//每次进入将tempImg3清空为全黑
drawContours(draw,contours,i,Scalar(255,255,255),-1,8);
Mat mask;
cvtColor(draw,mask,CV_BGR2GRAY);
tempImh.copyTo(tempImg3,mask);//将tempImg复制到tempImg3(只有mask部分被复制)
imshow("draw",draw);
imshow("result",tempImg3);
}
break;
}