本章内容:
1. HoughLines直线检测
2. HoughLinesP直线检测
3. 圆检测
1. HoughLines直线检测
输出结果:
2. HoughLinesP直线检测
输出结果
3. 圆检测
输出结果:
源码
#include <ostream>
#include <opencv.hpp>
#include <math.h>int main(int argc, char *argv[])
{
/*
本章内容:
1. HoughLines直线检测
2. HoughLinesP直线检测
3. 圆检测
*/
cv::String fileName = "/home/wang/dev/Image/c10.tif";
cv::String fileName1 = "/home/wang/dev/Image/pingpang.jpeg";
cv::Mat src = cv::imread(fileName);
cv::Mat src2 = cv::imread(fileName1);
if(src.data == NULL){
printf("图像读入失败\n");
return -1;
}
/*1. HoughLines直线检测
CV_EXPORTS_W void HoughLines( InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double srn = 0, double stn = 0,
double min_theta = 0, double max_theta = CV_PI );
参数分析:
@param lines Output vector of lines. Each line is represented by a 2 or 3 element vector
@param rho Distance resolution of the accumulator in pixels. //rho分辨率
@param theta Angle resolution of the accumulator in radians. // 旋转角度分辨率
@param threshold Accumulator threshold parameter. // 阈值
*/
cv::Mat gray;
cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);
cv::Mat src1 = src.clone();
cv::Mat dstCanny;
cv::Canny(gray,dstCanny,50,100); // 计算边缘
std::vector<cv::Vec2f> lines1;
cv::HoughLines(dstCanny,lines1,1,CV_PI/180,150);
// vector<cv::Vec2f> 的索引
/* 直线转换过程
1. 获取rho,theta值,
2. 计算直线的(x0,y0)中心点
3. 根据斜率和中心点定义直线,
总结:这种条件下无法获取直线的真实长度,值保留了直线的趋势
*/
std::cout <<"直线数目: " << lines1.size() << std::endl;
for(int i=0; i < lines1.size();i++){
float rho = lines1[i][0],theta = lines1[i][1];
float a = cos(theta), b=sin(theta);
int x0 = rho*a, y0= rho*b;
cv::Point pt1,pt2;
float lineLen = 1000;
pt1.x = cvRound(x0 - lineLen*b);
pt1.y = cvRound(y0 + a*lineLen);
pt2.x = cvRound(x0 + lineLen*b);
pt2.y = cvRound(y0 - a*lineLen);
cv::line(src,pt1,pt2,cv::Scalar(0,0,255),4);
}cv::imshow("gray", gray);
cv::imshow("HoughLines", dstCanny);
cv::imshow("src", src);/* 2. HoughLinesP直线检测
api接口: CV_EXPORTS_W void HoughLinesP( InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double minLineLength = 0, double maxLineGap = 0 );
参数分析:
@param lines Output vector of lines. // 4-元素 Vector,(x1,x2,y1,y2)
@param minLineLength Minimum line length. 构成一条直线所需要的最小点数
@param maxLineGap 同一直线上的点允许的最大距离
*/
std::vector<cv::Vec4f> lines2;
cv::HoughLinesP(dstCanny,lines2,1,CV_PI/180,100,100,50);
std::cout << "lines2: " << lines2.size() << std::endl;for(int i=0; i < lines2.size(); i++){
cv::Point pt1(lines2[i][0],lines2[i][1]),pt2(lines2[i][2],lines2[i][3]);
cv::line(src1,pt1,pt2,cv::Scalar(0,0,255),4);
}
cv::imshow("src1", src1);/* 3.圆检测
api接口:CV_EXPORTS_W void HoughCircles( InputArray image, OutputArray circles,
int method, double dp, double minDist,
double param1 = 100, double param2 = 100,
int minRadius = 0, int maxRadius = 0 );
简单参数分析:
@param circles Output vector : // 输出类型:(x, y, radius)or (x, y, radius, votes)
@param method Detection method, see #HoughModes. The available methods are #HOUGH_GRADIENT and #HOUGH_GRADIENT_ALT.
@param dp 霍夫空间分辨率,反比与输入图像分辨率
@param minDist : 圆心与圆心之间的最小距离
@param param1 Canny检测算子高阈值
@param param2 霍夫空间阈值
@param minRadius 检测圆最小距离
@param maxRadius 检测圆最大距离
// 不同版本实现的方法有差异,
enum method{
HOUGH_GRADIENT = 3,
HOUGH_GRADIENT_ALT = 4,
}
*/
cv::Mat gray1;
cv::cvtColor(src2,gray1,cv::COLOR_BGR2GRAY);
std::vector<cv::Vec3f> circles;
cv::HoughCircles(gray1,circles,cv::HOUGH_GRADIENT,1,10,100,50,0,0);
std::cout << "的个数:"<<circles.size() << std::endl;
// 画圆
for(int i=0;i<circles.size();i++){
cv::Vec3f c=circles[i];
cv::circle(src2,cv::Point(c[0],c[1]),c[2],cv::Scalar(0,0,255),4);
}
cv::imshow("gray1",gray1);
cv::imshow("src2",src2);
cv::waitKey(0);
return 1;
}