OpenCv使用摄像头进行霍夫圆变换识别圆形并返回圆心坐标

希望大家学会分享,你懂得别人未必懂,大家一起学习。

效果图:

OpenCv使用摄像头进行霍夫圆变换识别圆形并返回圆心坐标_第1张图片OpenCv使用摄像头进行霍夫圆变换识别圆形并返回圆心坐标_第2张图片

代码的实现如下(底下有参数的解释):

#include "stdafx.h"
//---------------------------------【头文件、命名空间包含部分】----------------------------
// 描述:包含程序所使用的头文件和命名空间
//------------------------------------------------------------------------------------------------
#include
#include
#include
using namespace cv;
using namespace std;


//-----------------------------------【main( )函数】------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main( )
{
//打开摄像头
char c = 0;
VideoCapture capture(0);
while (1)

{
                Mat frame;
capture >> frame;
        
//【1】Mat变量定义   
Mat midImage;//目标图的定义

//【2】转为灰度图并进行图像平滑
cvtColor(frame,midImage, CV_BGR2GRAY);//转化边缘检测后的图为灰度图
GaussianBlur( midImage, midImage, Size(9, 9), 2, 2 );

//【3】进行霍夫圆变换
vector circles;
HoughCircles( midImage, circles, CV_HOUGH_GRADIENT,1.5, 10, 200, 100, 0, 0 );

//【4】依次在图中绘制出圆
for( size_t i = 0; i < circles.size(); i++ )
{
//参数定义
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
//绘制圆心
circle( frame, center, 3, Scalar(0,255,0), -1, 8, 0 );
//绘制圆轮廓
circle( frame, center, radius, Scalar(155,50,255), 3, 8, 0 );
//打印圆心坐标
printf("x = %d,y = %d\n",cvRound(circles[i][0]),cvRound(circles[i][1]));
}


//【5】显示效果图  
namedWindow("效果");
imshow("效果", frame2);
c = cvWaitKey(30);
if (c == 27)//Esc键退出
{
break;

}
return 0;  
}
/*----------------------------------------各参数的意思----------------------------------------
cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 );
InputArray src: 输入图像即要进行颜色空间变换的原图像,可以是Mat类 
OutputArray dst: 输出图像即进行颜色空间变换后存储图像,也可以Mat类 
int code: 转换的代码或标识,即在此确定将什么制式的图片转换成什么制式的图片
int dstCn = 0: 目标图像通道数,如果取值为0,则由src和code决定

void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT);
src,输入图像,即源图像,填Mat类的对象即可。它可以是单独的任意通道数的图片,但需要注意,图片深度应该为CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
    dst,即目标图像,需要和源图片有一样的尺寸和类型。比如可以用Mat::Clone,以源图片为模板,来初始化得到如假包换的目标图。
    ksize,高斯内核的大小。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数(并不能理解)。或者,它们可以是零的,它们都是由sigma计算而来。
    sigmaX,表示高斯核函数在X方向的的标准偏差。
    sigmaY,表示高斯核函数在Y方向的的标准偏差。若sigmaY为零,就将它设为sigmaX,如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来。
    为了结果的正确性着想,最好是把第三个参数Size,第四个参数sigmaX和第五个参数sigmaY全部指定到。
    borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。

cvHoughCircles(CvArr *image,void *circle_storage,int method,double dp,double min_dist,double param1,double param2,int min_radius,int max_radius)
image:输入8bit(灰度)图像,其内容可被函数所改变
circle_storage:检测到的圆存储仓,可以是内存存储仓 (此种情况下,一个线段序列在存储仓中被创建,并且由函数返回)或者是包含圆参数的特殊类型的具有单行/单列的CV_32FC3型矩阵(CvMat*). 矩阵头为函数所修改,使得它的 cols/rows 将包含一组检测到的圆。如果 circle_storage 是矩阵,而实际圆的数目超过矩阵尺寸,那么最大可能数目的圆被返回,每个圆由三个浮点数表示:圆心坐标(x,y)和半径.)
method:Hough 变换方式,目前只支持CV_HOUGH_GRADIENT, which is basically 21HT, described in [Yuen03].
dp:寻找圆弧圆心的累计分辨率,这个参数允许创建一个比输入图像分辨率低的累加器。(这样做是因为有理由认为图像中存在的圆会自然降低到与图像宽高相同数量的范畴)。如果dp设置为1,则分辨率是相同的;如果设置为更大的值(比如2),累加器的分辨率受此影响会变小(此情况下为一半),dp的值不能比1小
min_dist:该参数是让算法能明显区分的两个不同圆之间的最小距离
param1:用于Canny的边缘阀值上限,下限被置为上限的一半
param2:累加器的阀值
min_radius:最小圆半径
max_radius:最大圆半径

cvCircle(CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int lineType=8, int shift=0)
img为源图像指针
center为画圆的圆心坐标
radius为圆的半径
color为设定圆的颜色,规则根据B(蓝)G(绿)R(红)
thickness 如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充
line_type 线条的类型。默认是8
shift 圆心坐标点和半径值的小数点位数
---------------------------------------------------------------------------------------------*/

你可能感兴趣的:(有趣的OpenCv)