首页 > 学院 > 开发设计 > 正文

opencv激光点追踪代码

2019-11-06 06:18:49
字体:
来源:转载
供稿:网友
话不多说,开始贴代码。说明:这是在vs中使用的。
#include "highgui.h"#include "cv.h" #include <iostream>#include <stdlib.h>#include <stdio.h> // 求最大值max,最小值min,绝对值abs,正负标志sign#define max(a, b) ((a) > (b) ? (a) : (b))#define min(a, b) ((a) < (b) ? (a) : (b))  #define abs(x) ((x) > 0 ? (x) : -(x))#define sign(x) ((x) > 0 ? 1 : -1) //物体位移动的最小值和最大值#define STEP_MIN 5#define STEP_MAX 100  iplImage *image; // 物体放置地点CvPoint objectPos = cvPoint(-1, -1);// 被跟踪的颜色和允许范围---------------可调--------------------int h = 0, s = 0, v = 0, tolerance =5;int H_slider_pos=173,S_slider_pos=150,V_slider_pos=255; /* * 功能:将原图转换为二值图 * 输入:image图片,被检测的像素值nbPixels * 输出:被检测物体的重心 */CvPoint binarisation(IplImage* image, int *nbPixels) { 	int x, y;	CvScalar pixel;	IplImage *hsv, *mask;	IplConvKernel *kernel;	int sommeX = 0, sommeY = 0;	*nbPixels = 0; 	// 创建一个mask图像	mask = cvCreateImage(cvGetSize(image), image->depth, 1); 	//得到hsv格式图像	hsv = cvCloneImage(image);	cvCvtColor(image, hsv, CV_BGR2HSV); 	//按照颜色范围给mask图像赋值(像素值在范围内则被置为0xff)	cvInRangeS(hsv, cvScalar(h - tolerance -1, s - 5*tolerance, 0), cvScalar(h + tolerance -1, s + 5*tolerance, 255), mask); 	//创建结构元素----一个5X5的椭圆,锚点在(2,2)	kernel = cvCreateStructuringElementEx(5, 5, 2, 2, CV_SHAPE_ELLIPSE); 		//膨胀	cvDilate(mask, mask, kernel, 1);	//腐蚀	cvErode(mask, mask, kernel, 1);   	//计算出查找的重心	for(x = 0; x < mask->width; x++) {		for(y = 0; y < mask->height; y++) {  			//计算符合的像素点的个数  和X,Y值的和			if(((uchar *)(mask->imageData + y*mask->widthStep))[x] == 255) {				sommeX += x;				sommeY += y;				(*nbPixels)++;			}		}	} 	//显示mask图像	cvShowImage("视频二值化", mask); 	//释放结构元素	cvReleaseStructuringElement(&kernel); 	//释放mask图像内存	cvReleaseImage(&mask);	//释放hsv图像内存    cvReleaseImage(&hsv); 	//如果找到了符合的点,将所有的点的X,Y坐标求均值并返回	if(*nbPixels > 0)		return cvPoint((int)(sommeX / (*nbPixels)), (int)(sommeY / (*nbPixels)));	else		return cvPoint(-1, -1);} /* * 功能:在被跟踪的物体重心上画圆 * 输入:image图片,物体重心objectNextPos,像素点个数nbPixels * 输出:无 */void addObjectToVideo(IplImage* image, CvPoint objectNextPos, int nbPixels) { 	int objectNextStepX, objectNextStepY; 	// 计算下一个红点位置	if (nbPixels > 10) 	{ 		if (objectPos.x == -1 || objectPos.y == -1) 		{			objectPos.x = objectNextPos.x;			objectPos.y = objectNextPos.y;		} 		if (abs(objectPos.x - objectNextPos.x) > STEP_MIN) 		{			objectNextStepX = max(STEP_MIN, min(STEP_MAX, abs(objectPos.x - objectNextPos.x) / 2));			objectPos.x += (-1) * sign(objectPos.x - objectNextPos.x) * objectNextStepX;		}		if (abs(objectPos.y - objectNextPos.y) > STEP_MIN) {			objectNextStepY = max(STEP_MIN, min(STEP_MAX, abs(objectPos.y - objectNextPos.y) / 2));			objectPos.y += (-1) * sign(objectPos.y - objectNextPos.y) * objectNextStepY;		} 	} else { 		objectPos.x = -1;		objectPos.y = -1; 	} 	// 在image图像上画一个半径为15的红色圆点	if (nbPixels > 10)		cvDrawCircle(image, objectPos, 10, CV_RGB(255, 0, 0), -1); /*	CvFont* font;	char string[]="i am happy";	cvInitFont(font,CV_FONT_HERSHEY_SIMPLEX,1.0f,1.0f,0,1,8);	cvPutText(image,string,objectPos,font,CV_RGB(0,0,255));*/	cvShowImage("动态追踪", image); } /* * 功能:得到鼠标点击处的像素值(被跟踪的像素值) * 输入:event事件,坐标x,y ,标志flags,属性指针param * 输出:无 */void getObjectColor(int event, int x, int y, int flags, void *param = NULL) { 	// 定义一个var[4]数组变量pixel	CvScalar pixel;	//定义hsv图像	IplImage *hsv;		//鼠标按下	if(event == CV_EVENT_LBUTTONUP)	{ 		// 获取hsv图像		hsv = cvCloneImage(image);		cvCvtColor(image, hsv, CV_BGR2HSV); 		// 获取像素值		pixel = cvGet2D(hsv, y, x); 				h = (int)pixel.val[0];		s = (int)pixel.val[1];		v = (int)pixel.val[2];		PRintf("%d/n",hsv->depth);		printf("%d,%d,%d/n",h,s,v);		// 释放image内存    		cvReleaseImage(&hsv); 	} }//修改HSV值void H_changed(int pos){	h=H_slider_pos;}void S_changed(int pos){	s=S_slider_pos;}void V_changed(int pos){	v=V_slider_pos;}/*****************************************                主程序******************************************/ int main() { 		IplImage *hsv;	CvCapture *capture;	char key=NULL; 	int nbPixels;		CvPoint objectNextPos; 	// 读取摄像头 	capture = cvCreateCameraCapture(1); 	// 检测摄像头捕获是否成功    	if (!capture) {		printf("Can't initialize the video capture./n");        	return -1; 	} 	// 创建两个视频窗口   	cvNamedWindow("动态追踪", CV_WINDOW_AUTOSIZE);   	cvNamedWindow("视频二值化", CV_WINDOW_AUTOSIZE);	cvMoveWindow("动态追踪", 0, 100);	cvMoveWindow("视频二值化", 650, 100);		//创建颜色控制的滚动条	//cvCreateTrackbar("H:","GeckoGeek Mask",&H_slider_pos,255,H_changed);	//cvCreateTrackbar("S:","GeckoGeek Mask",&S_slider_pos,255,S_changed);	//cvCreateTrackbar("V:","GeckoGeek Mask",&V_slider_pos,255,V_changed);/*	// 点击鼠标选择被跟踪的颜色	cvSetMouseCallback("GeckoGeek Color Tracking", getObjectColor);*//*	//红瓶盖	h=174;	s=146;	v=160;*//*	//红瓶盖	h=171;	s=151;	v=84;*//*	//皮肤	h=11;	s=51;	v=124;*//*	//激光1	h=173;	s=150;//s最大值190,最小值130	v=255;*//*		//激光2	h=173;	s=150;	v=255;*/	// 按Q退出	while(key != 'Q' && key != 'q') { 		// 得到当前图像		image = cvQueryFrame(capture); 		// 若无图像,退出当前循环继续获取图像		if(!image)			continue;		//得到被检测的颜色重心		objectNextPos = binarisation(image, &nbPixels);		//添加红色圆点到被检测颜色的重心		addObjectToVideo(image, objectNextPos, nbPixels); 		//等待10ms		key = cvWaitKey(10); 	} 	// 销毁窗口	cvDestroyWindow("动态追踪");	cvDestroyWindow("视频二值化"); 	// 释放capture资源	cvReleaseCapture(&capture); 	return 0; }感谢wg_chn大神提供的指导!
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表