版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dashujua/article/details/82354256
简单示例代码:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
void on_HoughLines(int, void*);
void on_HoughCircles();
int g_houghThresh = 100; //霍夫线变换阈值
int g_maxHoughThresh = 400;
int g_houghType = 0; //0:HoughLines(); 1:HoughLinesP()
int g_maxHoughType = 1;
const char* houghThreshStr = "阈值";
const char* houghTypeStr = "变换类型";
Mat srcHoughLines, srcHoughLinesP, srcHoughCircles;
Mat dstHoughLines, dstHoughLinesP, dstHoughCircles;
Mat edgeHoughLines, edgeHoughLinesP, grayHoughCircles;
int main()
{
srcHoughLines = imread("sudoku.png");
srcHoughLinesP = imread("sudoku.png");
srcHoughCircles = imread("smarties.png");
imshow("霍夫线原图", srcHoughLines);
imshow("霍夫圆原图", srcHoughCircles);
namedWindow("霍夫线效果图", WINDOW_AUTOSIZE);
namedWindow("霍夫圆效果图", WINDOW_AUTOSIZE);
createTrackbar(houghTypeStr, "霍夫线效果图", &g_houghType, g_maxHoughType, on_HoughLines);
createTrackbar(houghThreshStr, "霍夫线效果图", &g_houghThresh, g_maxHoughThresh, on_HoughLines);
on_HoughLines(0, 0);
on_HoughCircles();
waitKey(0);
return 0;
}
void on_HoughLines(int, void*)
{
switch (g_houghType)
{
case 0:
{
//霍夫线变换之前先进性边缘检测,并转成灰度图
Canny(srcHoughLines, edgeHoughLines, 50, 150);
cvtColor(edgeHoughLines, dstHoughLines, CV_GRAY2BGR);
// HoughLines() 返回 极坐标系中 r和theta 的集合
vector<Vec2f> houghLines;
HoughLines(edgeHoughLines, houghLines, 1, CV_PI / 180, g_houghThresh, 0, 0);
for (int i = 0; i < houghLines.size(); i++)
{
float rho = houghLines[i][0], theta = houghLines[i][1];
Point p1, p2;
double a = cos(theta), b = sin(theta);
double x0 = rho * a, y0 = rho * b;
//得到直线上到 p0 点距离为 1000 的两个点 p1,p2
p1.x = cvRound(x0 - 1000 * b);
p1.y = cvRound(y0 + 1000 * a);
p2.x = cvRound(x0 + 1000 * b);
p2.y = cvRound(y0 - 1000 * a);
//画线
line(dstHoughLines, p1, p2, Scalar(0, 0, 255), 1, LINE_AA);
}
imshow("霍夫线效果图", dstHoughLines);
break;
}
case 1:
{
Canny(srcHoughLinesP, edgeHoughLinesP, 50, 150);
cvtColor(edgeHoughLinesP, dstHoughLinesP, COLOR_GRAY2BGR);
//HoughLinesP() 函数返回直线的两个端点的坐标集合。p1(x1,y1),p2(x2,y2)
vector<Vec4i> houghLinesP;
HoughLinesP(edgeHoughLinesP, houghLinesP,1,CV_PI/180,g_houghThresh);
for (int i = 0; i < houghLinesP.size(); i++)
{
Point p1 = Point(houghLinesP[i][0], houghLinesP[i][1]);
Point p2 = Point(houghLinesP[i][2], houghLinesP[i][3]);
//画线
line(dstHoughLinesP, p1, p2, Scalar(0, 0, 255), 1, LINE_AA);
}
imshow("霍夫线效果图", dstHoughLinesP);
break;
}
default:
break;
}
}
void on_HoughCircles()
{
cvtColor(srcHoughCircles, grayHoughCircles, COLOR_BGR2GRAY);
medianBlur(grayHoughCircles, dstHoughCircles, 5);
//霍夫圆变换返回 圆心坐标及半径长度 的集合。(x0,y0),radius。
vector<Vec3f> houghCircles;
HoughCircles(grayHoughCircles, houghCircles, HOUGH_GRADIENT, 1, grayHoughCircles.rows/16, 100, 30, 1, 30);
for (int i = 0; i < houghCircles.size(); i++)
{
Point center(houghCircles[i][0], houghCircles[i][1]);
int radius = cvRound(houghCircles[i][2]);
//画出圆心
circle(srcHoughCircles, center, 1, Scalar(0, 100, 100), 3, LINE_AA);
//画出圆轮廓
circle(srcHoughCircles, center, radius, Scalar(255, 0, 255), 3, LINE_AA);
}
imshow("霍夫圆效果图", srcHoughCircles);
}
代码运行结果如下: