摄像头方案设计

摄像头方案设计

  1. 功能介绍
  • 初始化模式采用霍夫圆检测模式,寻求画面内符合条件的最佳圆形;
  • 按下功能按键1(该程序设计为‘R’)选定当前圆所在的矩形范围为感兴趣区域;
  • 采用camshift方式进入图形描边模式;
  • 按下功能键2(该程序设计为‘a’)停止记录小球运动轨迹;
  • 调用预处理模式,并返回容器储存的一系列坐标点。
  1. 思路分析
  • 调用VideoCapture video(0),打开本机摄像头;
  • 采用标志位的方式判定当前状态(ROI选择模式/轨迹记录模式),其中标志位判定为0时进入ROI选择模式,为1时进入轨迹模式,为其他值时退出循环:
    • ROI选择模式:调用HoughCircles检测圆(pretreat),并以圆心为矩阵中心,直径为矩形的长和宽进行区域选定,同时完成ROI区域的calchist计算,为记录模式做准备;
    • 轨迹记录模式:利用camshift算法(对当前页面进行直方图统计,获取最接近的ROI模式中直方图统计的区域)进行当前画面上目标的轨迹跟踪,并调用line函数在黑色背景上进行轨迹记录。
  • 调用waitKey判断功能按键‘a’是否按下,若按下则在销毁实时显示窗口,并进行后续预处理操作.
  1. 代码介绍
bool video_record(std::vector<cv::Point2i> &ptdata)
{
	using namespace cv;
	using namespace std;
	VideoCapture video(0);
	//VideoCapture video("nvcamerasrc ! video/x-raw(memory:NVMM), width=(int)640, height=(int)360,format=(string)I420, framerate=(fraction)25/1 ! nvvidconv flip-method=0 ! video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink");
	Mat Circle_frame,frame;
	Mat roi,maskroi;
	Mat hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj;
	int hsize = 16;
	int calc_flag = 0;
	int point_flag = 1;
	int slection_flag =0;
	int vmin = 10, vmax = 256, smin = 30;
	float hranges[] = {0,180};
	const float* phranges = hranges;
	vector<Vec3f> circles;
	Point start,end;
	Rect trackWindow,selection;
	vector<Mat> maskroi_channels;
	
	video.read(Circle_frame);
	Mat Back_Ground= Mat::zeros(Circle_frame.size(),Circle_frame.type());
	Mask = cv::Mat::zeros(Circle_frame.size(),Circle_frame.type());

	while(true)
	{
		video.read(Circle_frame);
		imshow("src",Circle_frame);
		
		if (waitKey(5) == 'q')
			break;
		Circle_frame.copyTo(frame);
		cvtColor(Circle_frame,hsv,COLOR_BGR2HSV);
		
		int _vmin = vmin, _vmax = vmax;
		inRange(hsv, Scalar(0, smin, MIN(_vmin,_vmax)),Scalar(180, 256, MAX(_vmin, _vmax)), mask);
		int ch[] = {0, 0};
		hue.create(hsv.size(), hsv.depth());
		mixChannels(&hsv, 1, &hue, 1, ch, 1);
	
		//calc_flag = 0时,进行霍夫圆检测
		if(calc_flag == 0)
		{
			cvtColor(frame,frame,COLOR_BGR2GRAY);
			GaussianBlur(frame,frame,Size(5,5),2,2);
   		HoughCircles(frame,circles,HOUGH_GRADIENT,1,frame.rows/4,150,40);
			if(circles.size() != 0)
			{	
				int cir_x = circles[0][0];
				int cir_y = circles[0][1];
				int r = circles[0][2];
					
				if((cir_x - r > 0) && (cir_y - r > 0) && (cir_x + r < Circle_frame.cols)&& (cir_y + r < Circle_frame.rows))
				{
					selection = Rect(cir_x - r,cir_y - r,2*r,2*r);
						
					maskroi = Circle_frame(Rect(cir_x - r,cir_y - r,2*r,2*r));
						
					imshow("roi",maskroi);
					
					if (waitKey(5) == 'r' && !maskroi.empty())
					{
						calc_flag = 1;
						frame.release();
						destroyWindow("roi");
					}
					Mat roi(hue, selection), maskroi(mask, selection);
					calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
					normalize(hist, hist, 0, 255, NORM_MINMAX);
					trackWindow = selection;
					histimg = Scalar::all(0);
					int binW = histimg.cols / hsize;
					Mat buf(1, hsize, CV_8UC3);
					for( int i = 0; i < hsize; i++ )
						buf.at<Vec3b>(i) = Vec3b(saturate_cast<uchar>(i*180./hsize), 255, 255);
					cvtColor(buf, buf, COLOR_HSV2BGR);
					for( int i = 0; i < hsize; i++ )
					{
						int val = saturate_cast<int>(hist.at<float>(i)*histimg.rows/255);
						rectangle( histimg, Point(i*binW,histimg.rows),Point((i+1)*binW,histimg.rows - val),Scalar(buf.at<Vec3b>(i)), -1, 8 );
						imshow("histimg",histimg);
				  }
					
				}	
			}
		}
		else if(calc_flag == 1)
		{
			calcBackProject(&hue, 1, 0, hist, backproj, &phranges);
			backproj &= mask;
			RotatedRect trackBox = CamShift(backproj, trackWindow,TermCriteria( TermCriteria::EPS | TermCriteria::COUNT, 10, 1 ));	
			cout<<trackBox.center<<endl;	
			
			if(point_flag == 1)
			{
				start = trackBox.center;
				end = start;
				point_flag = 2;
			}
			if(point_flag > 1)
			{
				end = trackBox.center;
				line(Back_Ground,start,end,Scalar(255,255,255),3,LINE_AA,0);
				imshow("Back_Ground",Back_Ground); 
				start = end;
			}
			     
      if (waitKey(5) == 'a' && !Back_Ground.empty())
      {
 				calc_flag = 2;    
      }

		}
		else
			break;
	}
	
	Circle_frame.release();

	pretreat_record(Back_Ground , ptdata);

	Back_Ground.release();

	return true;
}

  1. 待改进问题
  • 霍夫圆检测存在不稳定性,参数调节需要依据环境情况进行调节,具有经验性.主要问题如下:
    • 最大值最小值参数设定存在问题,无法确定理想的参数来应对所有的圆检测
  • camshift算法依赖于颜色进行判定跟踪,易受目标近似颜色背景的干扰;
  • 实际测试过程中易出现检测过程产生不完全封闭图像的情况,干扰后续判断.
  1. 优势
  • 不需要鼠标选定ROI区域,提高了系统的自动化程度和鲁棒性;
  • 仅采用霍夫圆检测进行前期ROI选定,因此可以在最理想情况下进行目标区域选定,不需要反复调节参数,在一定程度以上提高了圆检测的准确定;
  • 在ROI模式中若存在多个圆形目标,可以自主选择最佳感兴趣区域。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值