Hough變換原理


上篇博客:霍夫變換(直線檢測、圓檢測)中談到關於霍夫變換的原理,但是沒有談到具體實現;

具體的實現如下圖:

 

如下圖,假定在一個8*8的平面像素中有一條直線,並且從左上角(1,8)像素點開始分別計算θ為0°、45°、90°、135°、180°時的ρ,圖中可以看出ρ分別為1、(9√2)/2、8、(7√2)/2、-1,並給這5個值分別記一票,同理計算像素點(3,6)點θ為0°、45°、90°、135°、180°時的ρ,再給計算出來的5個ρ值分別記一票,此時就會發現ρ = (9√2)/2的這個值已經記了兩票了,以此類推,遍歷完整個8*8的像素空間的時候ρ = (9√2)/2就記了5票, 別的ρ值的票數均小於5票,所以得到該直線在這個8*8的像素坐標中的極坐標方程為 (9√2)/2=x*Cos45°+y*Sin45°,到此該直線方程就求出來了。(PS:但實際中θ的取值不會跨度這么大,一般是PI/180)。

這個網站說明的非常清楚:霍夫線變換¶

最重要的一句:這就是霍夫線變換要做的. 它追蹤圖像中每個點對應曲線間的交點. 如果交於一點的曲線的數量超過了 閾值, 那么可以認為這個交點所代表的參數對 (\theta, r_{\theta}) 在原圖像中為一條直線.

下面看看閾值對圖像檢測的影響

//-----------------------------------【頭文件包含部分】---------------------------------------
//		描述:包含程序所依賴的頭文件
//---------------------------------------------------------------------------------------------- 
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

//-----------------------------------【命名空間聲明部分】--------------------------------------
//		描述:包含程序所使用的命名空間
//----------------------------------------------------------------------------------------------- 
using namespace std;
using namespace cv;


//-----------------------------------【全局變量聲明部分】--------------------------------------
//		描述:全局變量聲明
//-----------------------------------------------------------------------------------------------
Mat g_srcImage, g_dstImage, g_midImage;//原始圖、中間圖和效果圖
vector<Vec4i> g_lines;//定義一個矢量結構g_lines用於存放得到的線段矢量集合
					  //變量接收的TrackBar位置參數
int g_nthreshold = 100;

//-----------------------------------【全局函數聲明部分】--------------------------------------
//		描述:全局函數聲明
//-----------------------------------------------------------------------------------------------

static void on_HoughLines(int, void*);//回調函數
static void ShowHelpText();


//-----------------------------------【main( )函數】--------------------------------------------
//		描述:控制台應用程序的入口函數,我們的程序從這里開始
//-----------------------------------------------------------------------------------------------
int main()
{
	//改變console字體顏色
	system("color 3F");

	ShowHelpText();

	//載入原始圖和Mat變量定義   
	Mat g_srcImage = imread("E:\\VS2015Opencv\\vs2015\\project\\picture\\07.jpg");  //該目錄下應該有一張名為07.jpg的素材圖

									   //顯示原始圖  
	imshow("【原始圖】", g_srcImage);

	//創建滾動條
	namedWindow("【效果圖】", 1);
	createTrackbar("值", "【效果圖】", &g_nthreshold, 200, on_HoughLines);

	//進行邊緣檢測和轉化為灰度圖
	Canny(g_srcImage, g_midImage, 50, 200, 3);//進行一次canny邊緣檢測
	cvtColor(g_midImage, g_dstImage, CV_GRAY2BGR);//轉化邊緣檢測后的圖為灰度圖

												  //調用一次回調函數,調用一次HoughLinesP函數
	on_HoughLines(g_nthreshold, 0);
	HoughLinesP(g_midImage, g_lines, 1, CV_PI / 180, 80, 50, 10);

	//顯示效果圖  
	imshow("【效果圖】", g_dstImage);


	waitKey(0);

	return 0;

}


//-----------------------------------【on_HoughLines( )函數】--------------------------------
//		描述:【頂帽運算/黑帽運算】窗口的回調函數
//----------------------------------------------------------------------------------------------
static void on_HoughLines(int, void*)
{
	//定義局部變量儲存全局變量
	Mat dstImage = g_dstImage.clone();
	Mat midImage = g_midImage.clone();

	//調用HoughLinesP函數
	vector<Vec4i> mylines;
	HoughLinesP(midImage, mylines, 1, CV_PI / 180, g_nthreshold + 1, 50, 10);

	//循環遍歷繪制每一條線段
	for (size_t i = 0; i < mylines.size(); i++)
	{
		Vec4i l = mylines[i];
		line(dstImage, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(23, 180, 55), 1, CV_AA);
	}
	//顯示圖像
	imshow("【效果圖】", dstImage);
}

//-----------------------------------【ShowHelpText( )函數】----------------------------------
//		描述:輸出一些幫助信息
//----------------------------------------------------------------------------------------------
static void ShowHelpText()
{
	//輸出一些幫助信息
	printf("\n\n\n\t請調整滾動條觀察圖像效果~\n\n");
	printf("\n\n\t\t\t\t\t\t\t\t by_ly"
		);
}

  

 

 

  從平面坐標到極坐標轉換三個參數C(x0,y0,r        是圓心

假設平面坐標的任意一個圓上的點,轉換到極坐標中:      處有最大值,霍夫變換正是利用這個原理實現圓的檢測。

參考這個網站:霍夫圓變換¶


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM