OpenCV學習:霍夫直線和圓檢測

第十七課 霍夫變換 直線
1.霍夫直線變換介紹
Hough Line Transform用來做直線檢測
前提條件-完成邊緣檢測
平面空間到極座標空間轉換
對於一條直線上的所有點來說,變換到極座標中,從0~360空間,可以得到r的大小,屬於同一條直線
上的點在極座標空間上(r,θ)必然在一個點上有最強的信號出現,根據此反算到平面座標上就可以
得到直線上個點的像素座標,從而得到直線。
2.相關API學習

	標準的霍夫變換cv::HoughLines從平面座標轉換到霍夫空間
	一般爲有經驗的開發者使用,需要自己反變換到平面空間

	HoughLines(
	inputArray src,//輸入8bit的灰度圖像
	outputArray lines,//用輸出的極座標來表示直線
	double rho,//生成極座標時候的像素掃描步長
	double theta,//生成極座標是的角步長,一半取值CV_P1/180
	int threshold,//閾值,只有獲得足夠交點的極座標點纔會被看成直線
	double srn=0,//是否應用多尺度的霍夫變換,如果不是設置爲零表示經典的霍夫變換
	double stn=0,//是否應用多尺度的霍夫變換,如果不是設置爲零表示經典的霍夫變換
	double min_theta=0,//表示掃描範圍在0到180之間,默認即可
	double max_theta=CV_P1//)
	
	霍夫變換直線概率cv::HoughLinesP最終輸出的是直線的兩個點
	HoughLinesP(
	inputArray src,//輸入8bit的灰度圖像
	outputArray lines,//用輸出的極座標來表示直線
	double rho,//生成極座標時候的像素掃描步長
	double theta,//生成極座標是的角步長,一半取值CV_P1/180
	int threshold,//閾值,只有獲得足夠交點的極座標點纔會被看成直線
	double minLIneLength=0,//最小直線長度
	double maxLineGap//最大間隔)	

3.代碼演示

	#include <opencv2/opencv.hpp>
	#include <iostream>
	#include <math.h>

	using namespace cv;
	using namespace std;

	int main(int argc, char**argv)
	{
		Mat src, dst;
		src = imread("H:/pictures/xingtai.png");

		if (!src.data)
		{
			cout << "could not load image.." << endl;

			return -1;
		}
		char input_title[] = "input image";
		char output_title[] = "output image";
		namedWindow(input_title, CV_WINDOW_AUTOSIZE);
		namedWindow(output_title, CV_WINDOW_AUTOSIZE);
		imshow(input_title, src);

		Mat gray_src,edge_src;
		cvtColor(src, gray_src, CV_BGR2GRAY);
		Canny(gray_src, edge_src, 150, 200);
		cvtColor(edge_src, dst,CV_GRAY2BGR);
		imshow("edge image", edge_src);

		vector<Vec4f> plines;
		HoughLinesP(edge_src, plines, 1, CV_PI / 180.0, 10, 0, 10);
		Scalar color = Scalar(0, 255, 255);
		for (size_t i = 0; i < plines.size();i++)
		{
			Vec4f hline = plines[i];
			line(dst, Point(hline[0], hline[1]), Point(hline[2], hline[3]), color, 3, LINE_AA);

		}
		imshow(output_title, dst);

		waitKey(0);
		return 0;
	}

第十八課 霍夫圓檢測
1.霍夫圓檢測原理
從平面座標到極座標轉換爲三個參數,C(x0,y0,r)其中x0,y0爲圓心
假設平面座標的任意一個圓上的點轉換到極座標中:C(x0,y0,r)處有最大值,霍夫變換正是用這個原理
進行圓檢測
2.相關API
霍夫圓檢測對噪聲比較敏感,要先對圖像進行中值濾波
基於效率的考慮OpenCV中霍夫圓檢測是基於圖像梯度的實現,分爲兩步:
檢測邊緣,發現可能的圓心
基於第一步的基礎從候選圓心上計算最佳半徑
一般爲有經驗的開發者使用,需要自己反變換到平面空間

	HoughCircles(
	inputArray src,//輸入8bit的單通道灰度圖像
	outputArray circles,//輸出結果,發現圓信息
	int method,//方法-HOUGH_GRADIENT
	double dp,//dp=1
	double mindist,//10 最短距離,可以分辨兩個圓的,否則認爲是同心圓
	double param1,//canny edge detection low threshold
	double param2,//中心點累加器閾值-候選圓心
	int minradius,//最小半徑
	int maxradius//最大半徑)

3.代碼演示

	#include <opencv2/opencv.hpp>
	#include <iostream>
	#include <math.h>

	using namespace cv;
	using namespace std;
	int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("H:/pictures/round.png");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}
	char INPUT_TITLE[] = "input image";
	char OUTPUT_TITLE[] = "hough circle demo";
	namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE);
	namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);
	imshow(INPUT_TITLE, src);

	// 中值濾波
	Mat moutput;
	medianBlur(src, moutput, 3);
	cvtColor(moutput, moutput, CV_BGR2GRAY);

	// 霍夫圓檢測
	vector<Vec3f> pcircles;
	HoughCircles(moutput, pcircles, CV_HOUGH_GRADIENT, 1, 10, 100, 38, 5, 200);
	src.copyTo(dst);
	for (size_t i = 0; i < pcircles.size(); i++) {
		Vec3f cc = pcircles[i];
		circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 0, 255), 2, LINE_AA);
		circle(dst, Point(cc[0], cc[1]), 2, Scalar(198, 23, 155), 2, LINE_AA);
	}
	imshow(OUTPUT_TITLE, dst);

	waitKey(0);
	return 0;
	}
發佈了20 篇原創文章 · 獲贊 4 · 訪問量 2540
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章