1.普通霍夫变换HoughLines
霍夫变换中,直线用下述方程来表示:ρ=cosθ+sinθ;
//使用霍夫变换检测直线
#include<opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("road.jpg");
if (!src.data){ printf("error"); exit(0); };
Mat dst;
dst = Mat::zeros(src.size(), src.type());
//应用Canny算法
Canny(src,dst, 125, 350);
//Hough变换检测直线
std::vector<Vec2f>lines;//定义一个矢量结构lines用于存放得到的线段矢量集合
HoughLines(dst, lines, 1, CV_PI / 180, 80);
//使用迭代器进行图像遍历
std::vector<cv::Vec2f>::const_iterator begin = lines.begin();
while (begin != lines.end())
{
float rho = (*begin)[0];//第一个参数为距离ρ
float theta = (*begin)[1];//第二个参数为角度θ
if (theta<CV_PI / 4. || theta>3.*CV_PI / 4.)//垂直线
{
//线与第1行的交点
cv::Point pt1(0, (rho / sin(theta)));
//线与最后一行的交点
cv::Point pt2(dst.rows, (rho - dst.rows*cos(theta)) / sin(theta));
//在原图src中绘制线
cv::line(src, pt1, pt2, cv::Scalar(0, 255, 255), 1);
}
else//水平线
{
//线与第1列的交点
cv::Point pt1(rho / cos(theta), 0);
//线与最后一列的交点
cv::Point pt2((rho - dst.cols*sin(theta)) / cos(theta), dst.cols);
//绘制线
cv::line(src, pt1, pt2, cv::Scalar(255, 0, 255), 1);
}
begin++;
}
imshow("result", dst);
imshow("src", src);
waitKey(0);
return 0;
}
2.概率霍夫变换HoughLinesP
概率霍夫变换是HoughLines的改进,可以检测到线段,同时避免了意外的像素排列或多条线穿过同一组像素带来的错误检测。
使用此函数实现
cv::HoughLinesP(med, lines, 1, CV_PI / 180, 80, 50, 3);
med代表源图像(需为9位单通道2进制);lines表示矢量结构,详细使用见代码;
1以及CV_PI/180表示步进尺寸;80代表最小投票数;
50代表直线最小长度;3代表沿直线方向的最大缺口;
//使用概率霍夫变换检测直线
#include<opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("road.jpg");
if (!src.data){ printf("error"); exit(0); };
Mat dst;
//Canny边缘检测
Canny(src,dst, 125, 350);
//进行概率霍夫变换
vector<Vec4i> lines;//定义一个矢量结构存放得到的线段矢量集合;
HoughLinesP(dst, lines, 1, CV_PI / 180, 80, 50, 3);
//绘制线段
for (size_t i = 0; i < lines.size(); i++)//size_t即unsigned int
{
Vec4i k = lines[i];//此处为英文字母l
line(src, Point(k[0], k[1]), Point(k[2], k[3]), Scalar(0, 2555, 255), 3);
}
imshow("result", dst);
imshow("src", src);
waitKey(0);
return 0;
}
3.Hough变换检测圆
使用此函数
HoughCircles(dst, circles, CV_HOUGH_GRADIENT, 2, 52, 200, 160, 15, 100);
dst代表要检测的图像; circles是表示矢量结构,详细使用见代码;
CV_HOUGH_GRADIENT是固定的函数;2代表累加器的分辨率(表示图像的尺寸的1/2);
52表示两个圆圆心的最小距离;200表示Canny的高阈值;
100表示最小投票数,越小检测到的圆越多;
15和100分别表示最小半径和最大半径;
在调用cv::HoughCircles前要对图像进行平滑处理,可用GaussianBlur函数进行平滑
//使用霍夫变换检测园
#include<opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("002.jpg");
if (!src.data){ printf("error"); exit(0); };
Mat dst,src1;
src1 = imread("002.jpg");
//边缘检测
Canny(src, dst, 125, 350);
//图像平滑
GaussianBlur(dst, dst, Size(5, 5), 1.5);
//霍夫圆变换
vector<Vec3f>circles;
HoughCircles(dst, circles, CV_HOUGH_GRADIENT, 2, 52, 200, 160, 15, 100);
std::vector<cv::Vec3f>::const_iterator begin = circles.begin();
while (begin != circles.end())
{
//绘制园
<pre name="code" class="cpp"> /*第二个参数Point表示圆心,(*begin)[2]表示半径*/
circle(src, Point((*begin)[0], (*begin)[1]), (*begin)[2], Scalar(255), 2); begin++;}// imshow("result", dst);imshow("src", src);imshow("原图", src1);waitKey(0);return 0;}