转自51CTO博客作者Ronny的文章,原文地址
一、Canny检测轮廓
int main()
{
Mat I=imread("../cat.png");
cvtColor(I,I,CV_BGR2GRAY);
Mat contours;
Canny(I,contours,125,350);
threshold(contours,contours,128,255,THRESH_BINARY);
namedWindow("Canny");
imshow("Canny",contours);
waitKey();
return 0;
}
二、直线检测
void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 );
void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta,int threshold, double minLineLength=0, double maxLineGap=0 );
int main()
{
Mat image=imread("../car.png");
Mat I;
cvtColor(image,I,CV_BGR2GRAY);
Mat contours;
Canny(I,contours,125,350);
threshold(contours,contours,128,255,THRESH_BINARY);
vector<Vec4i> lines;
// 检测直线,最小投票为90,线条不短于50,间隙不小于10
HoughLinesP(contours,lines,1,CV_PI/180,80,50,10);
drawDetectLines(image,lines,Scalar(0,255,0));
namedWindow("Lines");
imshow("Lines",image);
waitKey();
return 0;
}
上面程序将检测到的线条保存在lines变量内,我们需要进一步将它们画在图像上:
void drawDetectLines(Mat& image,const vector<Vec4i>& lines,Scalar & color)
{
// 将检测到的直线在图上画出来
vector<Vec4i>::const_iterator it=lines.begin();
while(it!=lines.end())
{
Point pt1((*it)[0],(*it)[1]);
Point pt2((*it)[2],(*it)[3]);
line(image,pt1,pt2,color,2); // 线条宽度设置为2
++it;
}
}
三、轮廓的提取与描述
int main()
{
using namespace cv;
Mat image=imread("../shape.png");
cvtColor(image,image,CV_BGR2GRAY);
vector<vector<Point>> contours;
// find
findContours(image,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
// draw
Mat result(image.size(),CV_8U,Scalar(0));
drawContours(result,contours,-1,Scalar(255),2);
namedWindow("contours");
imshow("contours",result);
waitKey();
return 0;
}
// 轮廓表示为一个矩形
Rect r = boundingRect(Mat(contours[0]));
rectangle(result, r, Scalar(255), 2);
// 轮廓表示为一个圆
float radius;
Point2f center;
minEnclosingCircle(Mat(contours[1]), center, radius);
circle(result, Point(center), static_cast<int>(radius), Scalar(255), 2);
// 轮廓表示为一个多边形
vector<Point> poly;
approxPolyDP(Mat(contours[2]), poly, 5, true);
vector<Point>::const_iterator itp = poly.begin();
while (itp != (poly.end() - 1))
{
line(result, *itp, *(itp + 1), Scalar(255), 2);
++itp;
}
line(result, *itp, *(poly.begin()), Scalar(255), 2);
// 轮廓表示为凸多边形
vector<Point> hull;
convexHull(Mat(contours[3]), hull);
vector<Point>::const_iterator ith = hull.begin();
while (ith != (hull.end() - 1))
{
line(result, *ith, *(ith + 1), Scalar(255), 2);
++ith;
}
line(result, *ith, *(hull.begin()), Scalar(255), 2);