1. 程式人生 > >【opencv】hough圓變換

【opencv】hough圓變換

霍夫梯度法原理如下:首先對影象應用canny邊緣檢測,然後對邊緣影象中每一個非0點,考慮其區域性梯度,通過sobel計算。利用得到的梯度,由斜率指定的直線上的每一個點都在累加器中被累加,同時,標記邊緣影象中每一個非0畫素的位置。然後從累加器中這些點中選擇候選的中心,這些中心都大於給定閾值並且大於其所有近鄰。這些候選的中心按照累加值降序排列,以便於最支援畫素的中心首先出現。接下來對每一箇中心,考慮所有的非0畫素。這些畫素按照其與中心的距離排序。從到最大半徑的最小距離算起,選擇非0畫素最支援的一條半徑。如果一箇中心受到邊緣影象非0畫素最充分的支援,並且到前期被選擇的中心有足夠的距離,它將會被保留。這個實現可以使演算法執行起來更快,能夠幫助解決三維累加器中其他稀疏分佈問題。

void HoughCircles( 
InputArray image,//輸入影象8位
OutputArray circles,//陣列或儲存器
int method, //CV_HOUGH_GRADIENT 目前只有梯度法
double dp, //累加器影象解析度 ≥1
double minDist,//不同圓之間最小距離
double param1=100, //canny上限閾值,下限閾值=上限閾值/2cvCanny( img, edges, MAX(canny_threshold/2,1), canny_threshold, 3 );</span>
double param2=100,//累加器閾值
int minRadius=0, //最小圓半徑
int maxRadius=0 //最大圓半徑
);


cvCircle( 
CvArr* img, //輸入影象
CvPoint center, //圓心
int radius,//半徑
CvScalar color, //顏色
int thickness CV_DEFAULT(1),//粗細
int line_type CV_DEFAULT(8), 
int shift CV_DEFAULT(0)//0
);

樣圖:圓直徑依次為 80,90,100,110,120


未經平滑處理結果:cvcircle繪製時,半徑與圓心損失精度



經平滑處理結果:cvcircle繪製時,半徑與圓心損失精度



using namespace cv;

int main()
{
	IplImage* img = cvLoadImage("correct_Img_1.jpg",0);//轉為灰度圖

	cvSmooth( img, img, CV_GAUSSIAN, 5, 5);//平滑處理

	vector<Vec3f> circles;

	HoughCircles( (Mat)img, circles, CV_HOUGH_GRADIENT, 1.5 ,10, 80, 110, 35 ,65);//hough圓變換

	//img = cvLoadImage("correct_Img_1.jpg",1);

	for (int i = 0; i < circles.size(); i++)
	{
		CvPoint center;//圓心
		center.x = circles[i][0];
		center.y = circles[i][1];

		int radius = circles[i][2];//半徑

		cvCircle( img, center, radius, Scalar(0,255,0), 1, 8, 0);//繪製圓
		
		cvCircle( img, center, 3, Scalar(0,255,0), 3, 8, 0);//繪製圓心

		std::cout<<"圓心為:"<<circles[i][0]<<","<<circles[i][1]<<"	直徑為:"<<2*circles[i][2]<<"\n";//為了保證精度,以原值輸出
	}
	cvSaveImage("out.jpg",img);
	cvNamedWindow("hough圓檢測",1);
	cvShowImage("hough圓檢測",img);

	cvWaitKey(0);

	cvReleaseImage(&img);
	cvDestroyWindow("hough圓檢測");

	return 0;
}