OpenCV学习之路(十五) 霍夫变换

版权声明:本文为博主原创文章,未经博主允许不得转载。 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);

}

代码运行结果如下:

猜你喜欢

转载自blog.csdn.net/dashujua/article/details/82354256
今日推荐