好文推荐:http://blog.sina.com.cn/s/blog_891c7ae40101kvtr.html
下面展示findContours和drawContours函数
#include "cv.h"
#include "highgui.h"
using namespace cv;
using namespace std;
Mat srcGray;
int lThreshold=100;
void barChange(int pos, void* userdata);
int main(int argc,char *argv[])
{
Mat src;
src=imread("fish.jpg");
cvtColor(src,srcGray,CV_BGR2GRAY);
blur(srcGray,srcGray,Size(3,3));
namedWindow("srcGray");
imshow("srcGray",srcGray);
createTrackbar("Low Threshold:","srcGray",&lThreshold,255,barChange);
barChange(0,0);
waitKey(0);
destroyAllWindows();
return 0;
}
void barChange(int pos, void* userdata)
{
Mat srcCanny,dstContours;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
Canny(srcGray,srcCanny,lThreshold,lThreshold*2,3);
findContours(srcCanny,contours,hierarchy,CV_RETR_TREE,CHAIN_APPROX_SIMPLE);
cout<<"size:"<<contours.size()<<endl;
dstContours=Mat::zeros(srcCanny.size(),CV_8UC3);
for (int i=0;i<contours.size();i++)
drawContours(dstContours,contours,i,Scalar(0,255,255),1,8,hierarchy,0);
imshow("dstContours",dstContours);
}
实验效果:
轮廓凸包:convexHull
#include "cv.h"
#include "highgui.h"
using namespace cv;
using namespace std;
Mat srcGray;
int lThreshold=100;
void barChange(int pos, void* userdata);
int main(int argc,char *argv[])
{
Mat src;
src=imread("fish.jpg");
cvtColor(src,srcGray,CV_BGR2GRAY);
blur(srcGray,srcGray,Size(3,3));
namedWindow("srcGray");
imshow("srcGray",srcGray);
createTrackbar("Low Threshold:","srcGray",&lThreshold,255,barChange);
barChange(0,0);
waitKey(0);
destroyAllWindows();
return 0;
}
void barChange(int pos, void* userdata)
{
Mat srcCanny,dstContours;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
Canny(srcGray,srcCanny,lThreshold,lThreshold*2,3);
findContours(srcCanny,contours,hierarchy,CV_RETR_TREE,CHAIN_APPROX_SIMPLE);
cout<<"size:"<<contours.size()<<endl;
vector<vector<Point>> hull(contours.size());
for (int i=0;i<contours.size();i++)
{
convexHull(contours[i],hull[i]);
}
dstContours=Mat::zeros(srcCanny.size(),CV_8UC3);
for (int i=0;i<contours.size();i++)
{
drawContours(dstContours,contours,i,Scalar(0,255,255),2,8,vector<Vec4i>(),0);
drawContours(dstContours,hull,i,Scalar(0,0,255),1,8,vector<Vec4i>(),0);
}
imshow("dstContours",dstContours);
}
效果:
创建轮廓矩形框和圆形框
• Use the OpenCV function boundingRect
• Use the OpenCV function minEnclosingCircle
#include "cv.h"
#include "highgui.h"
using namespace cv;
using namespace std;
Mat srcGray;
int lThreshold=100;
void barChange(int pos, void* userdata);
int main(int argc,char *argv[])
{
Mat src;
src=imread("fish.jpg");
cvtColor(src,srcGray,CV_BGR2GRAY);
blur(srcGray,srcGray,Size(3,3));
namedWindow("srcGray");
imshow("srcGray",srcGray);
createTrackbar("Low Threshold:","srcGray",&lThreshold,255,barChange);
barChange(0,0);
waitKey(0);
destroyAllWindows();
return 0;
}
void barChange(int pos, void* userdata)
{
Mat srcThreshold,dstContours;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
threshold(srcGray,srcThreshold,lThreshold,255,THRESH_BINARY);
findContours(srcThreshold,contours,hierarchy,CV_RETR_TREE,CHAIN_APPROX_SIMPLE);
cout<<"size:"<<contours.size()<<endl;
vector<vector<Point>> poly(contours.size());
vector<Rect> boundRect(contours.size());
vector<Point2f> center(contours.size());
vector<float> radius(contours.size());
for (int i=0;i<contours.size();i++)
{
approxPolyDP(contours[i],poly[i],3,true);
boundRect[i]=boundingRect(poly[i]);
minEnclosingCircle(poly[i],center[i],radius[i]);
}
dstContours=Mat::zeros(srcGray.size(),CV_8UC3);
for (int i=0;i<contours.size();i++)
{
drawContours(dstContours,poly,i,Scalar(0,255,255),2,8,vector<Vec4i>(),0);
rectangle(dstContours,boundRect[i].tl(),boundRect[i].br(),Scalar(128,128,128));
circle(dstContours,center[i],(int)radius[i],Scalar(255,255,255));
}
imshow("dstContours",dstContours);
}<strong style="color: rgb(204, 0, 0); ">
</strong>
效果:
#include "cv.h"
#include "highgui.h"
using namespace cv;
using namespace std;
Mat srcGray;
int lThreshold=100;
void barChange(int pos, void* userdata);
int main(int argc,char *argv[])
{
Mat src;
src=imread("fish.jpg");
cvtColor(src,srcGray,CV_BGR2GRAY);
blur(srcGray,srcGray,Size(3,3));
namedWindow("srcGray");
imshow("srcGray",srcGray);
createTrackbar("Low Threshold:","srcGray",&lThreshold,255,barChange);
barChange(0,0);
waitKey(0);
destroyAllWindows();
return 0;
}
void barChange(int pos, void* userdata)
{
Mat srcThreshold,dstContours;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
threshold(srcGray,srcThreshold,lThreshold,255,THRESH_BINARY);
findContours(srcThreshold,contours,hierarchy,CV_RETR_TREE,CHAIN_APPROX_SIMPLE);
cout<<"size:"<<contours.size()<<endl;
vector<RotatedRect> minRect(contours.size());
vector<RotatedRect> minEllipse(contours.size());
for (int i=0;i<contours.size();i++)
{
minRect[i]=minAreaRect(contours[i]);
if (contours[i].size()>5)
{
minEllipse[i]=fitEllipse(contours[i]);
}
}
dstContours=Mat::zeros(srcGray.size(),CV_8UC3);
Point2f rectPoint[4];
for (int i=0;i<contours.size();i++)
{
drawContours(dstContours,contours,i,Scalar(0,255,255),2,8,vector<Vec4i>(),0);
ellipse(dstContours,minEllipse[i],Scalar(255,255,255));
minRect[i].points(rectPoint);
for (int j=0;j<4;j++)
{
line(dstContours,rectPoint[j],rectPoint[(j+1)%4],Scalar(180,180,180));
}
}
imshow("dstContours",dstContours);
}
效果: