opencv 识别网球 ,或者绿色的小球 输出重心坐标

本文深入探讨了图像处理和视频特效算法的核心内容,包括OpenGL ES滤镜、OpenCV图像处理、人脸标定AR等技术,旨在提升用户体验并实现创新的视觉效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

void image_process(IplImage *image)
 {
  int iLowH =26;  
  int iHighH = 69;  
  int iLowS = 42;   
  int iHighS = 206;    
  int iLowV = 0;  
  int iHighV = 198;
   CvMemStorage* storage2 = cvCreateMemStorage();
   CvSeq* contour3 = NULL;
   CvMoments moments; 
   CvMat *region; 
   CvPoint pt1,pt2;
   double m00 = 0, m10, m01, mu20, mu11, mu02, inv_m00; 
   double a, b, c; 
   int xc, yc; 

    CvMemStorage* storage = cvCreateMemStorage();
 	CvSeq * circles=NULL;

   // Circle cir[6];
    CvPoint P0;
    CvPoint CenterPoint;
   // cvNamedWindow("win1"); 
	//cvShowImage("win1",image);
	//cvNamedWindow("image",CV_WINDOW_AUTOSIZE);//用于显示图像的窗口
	//cvNamedWindow("hsv",CV_WINDOW_AUTOSIZE);	
	//cvNamedWindow("saturation",CV_WINDOW_AUTOSIZE);
	//cvNamedWindow("value",CV_WINDOW_AUTOSIZE);
	//cvNamedWindow("pImg8u",1);
	IplImage *hsv=cvCreateImage(cvGetSize(image),8,3);//给hsv色系的图像申请空间
	IplImage *hue=cvCreateImage(cvGetSize(image),8,1);  //色调
	IplImage *saturation=cvCreateImage(cvGetSize(image),8,1);//饱和度
	IplImage *value=cvCreateImage(cvGetSize(image),8,1);//亮度
	IplImage *imgThresholded=cvCreateImage(cvGetSize(hue),8,1); 
	cvNamedWindow("yuan",1);
	cvCvtColor(image,hsv,CV_BGR2HSV);//将RGB色系转为HSV色系
	cvShowImage("yuan",image);
	//cvShowImage("hsv",hsv);
	cvSplit(hsv, hue, 0, 0, 0 );//分离三个通道
	cvSplit(hsv, 0, saturation, 0, 0 );
	cvSplit(hsv, 0, 0, value, 0 );
	int value_1=0;
	  
	cvInRangeS(
	   hsv,  
	   cvScalar(iLowH, iLowS, iLowV), 
	   cvScalar(iHighH, iHighS, iHighV),
	   imgThresholded
	   ); 
	 cvNamedWindow("imgThresholded",1);
	 cvShowImage("imgThresholded",imgThresholded);


	 IplImage*pContourImg= cvCreateImage( cvGetSize(image), 8, 1 ); 
	cvCopy(imgThresholded,pContourImg);
	 cvNamedWindow("pContourImg",1);
	 cvShowImage("pContourImg",pContourImg);
	 IplImage* dst = cvCreateImage( cvGetSize(image), 8, 3 );  
	CvMemStorage* storage3 = cvCreateMemStorage(0);  
	CvSeq* contour = 0; 
	// 提取轮廓  
    int contour_num = cvFindContours(pContourImg, storage3, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);  
    cvZero(dst);        // 清空数组  
    CvSeq *_contour = contour;   
    double maxarea = 100;  
    double minarea = 10;  
    int m = 0;  
    for( ; contour != 0; contour = contour->h_next )    
    {    
  
        double tmparea = fabs(cvContourArea(contour));  
        if(tmparea < minarea)     
        {    
            cvSeqRemove(contour, 0); // 删除面积小于设定值的轮廓  
            continue;  
        }    
        CvRect aRect = cvBoundingRect( contour, 0 );   
        if ((aRect.width/aRect.height)<1)    
        {    
            cvSeqRemove(contour, 0); //删除宽高比例小于设定值的轮廓  
            continue;  
        }    
        if(tmparea > maxarea)    
        {    
            maxarea = tmparea;  
        }    
        m++;  
        // 创建一个色彩值  
    //    CvScalar color = CV_RGB( 0, 0, 255 );  
  
     /*   max_level 绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓  
        如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种  
        如果值为负数,函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓 */ 
     //   cvDrawContours(dst, contour, color, color, 0, 1, 8);   //绘制外部和内部的轮廓  
    }    
    contour = _contour;  
    int count = 0;  double tmparea=0;
    for(; contour != 0; contour = contour->h_next)  
    {    
        count++;  
         tmparea = fabs(cvContourArea(contour));  
        if (tmparea >= maxarea)    
        {    
            CvScalar color = CV_RGB( 0, 255, 0);  
            cvDrawContours(dst, contour, color, color, -1, 1, 8);  
			cout<<"222"<<endl;
			cout<<"面积为"<<tmparea<<endl;
			cout<<endl;

			CvRect aRect = cvBoundingRect( contour, 0 ); 
			//找重心
			{
				CvPoint2D32f center = cvPoint2D32f(0, 0);
				int countOfPoint = 0;
				for(int i = aRect.x; i < aRect.x + aRect.width; ++i){
					for(int j = aRect.y; j < aRect.y + aRect.height; ++j){
						if(*(image->imageData + image->widthStep * j + i) != 0){
							center.x += i;
							center.y += j;
							countOfPoint++;
						}
					}
				}

				center.x /= countOfPoint;
				center.y /= countOfPoint;
				cout<<"重心坐标为x:"<<center.x<<endl;
         		cout<<"重心坐标为y:"<<center.y<<endl;
				cvCircle(dst, cvPoint(center.x, center.y), 5, cvScalar(0, 255), 2);
			}

		}



  //  //Threshold the image
  //   cvErode(imgThresholded,imgThresholded);
  //   cvErode(imgThresholded,imgThresholded);
	 //cvErode(imgThresholded,imgThresholded);
	 //cvErode(imgThresholded,imgThresholded);	   
	 //IplImage* pImg8u=cvCloneImage(imgThresholded);
	
	 //cvCanny(pImg8u, pImg8u,40, 50, 5);
	 //cvShowImage("pImg8u",pImg8u);
	 //circles=cvHoughCircles(pImg8u,storage,CV_HOUGH_GRADIENT,
		//2,   //最小分辨率,应当>=1
		//pImg8u->height/15,   //该参数是让算法能明显区分的两个不同圆之间的最小距离
		//80,    //用于Canny的边缘阀值上限,下限被置为上限的一半
		//65,    //累加器的阀值
		//25,      //最小圆半径 
		//50      //最大圆半径
		//);
  }

	cvShowImage( "contour", dst );
	}

### 如何使用 OpenCV 实现网球检测和识别 #### 准备工作 为了成功实现网球的检测与识别,需要安装必要的软件包。确保环境中已安装 `opencv` 和其他辅助库。 对于 Python 用户来说,可以通过 pip 安装 opencv-python 库: ```bash pip install opencv-python ``` #### 获取视频流或图片序列 通常情况下,网球跟踪可以从摄像设备获取实时视频流或者预先录制好的视频文件开始。这一步骤涉及打开摄像头并读取每一帧图像数据[^2]。 ```python import cv2 cap = cv2.VideoCapture(0) # 打开默认相机 while True: ret, frame = cap.read() if not ret: break # 后续处理... cv2.imshow('frame', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() ``` #### 预处理阶段 在实际追踪之前,可能需要对原始图像做一些预处理操作来提高后续特征提取的效果。比如转换色彩空间到 HSV 或者灰度图,应用高斯模糊减少噪声干扰等[^1]。 ```python hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) blurred = cv2.GaussianBlur(hsv_frame, (11, 11), 0) ``` #### 设定颜色范围筛选球体 根据网球的颜色特性设定合适的阈值区间,在此范围内寻找符合条件的目标区域。考虑到光照变化等因素的影响,建议采用较宽泛但合理的上下限设置。 ```python lower_yellow = (20, 100, 100) upper_yellow = (30, 255, 255) mask = cv2.inRange(blurred, lower_yellow, upper_yellow) masked_image = cv2.bitwise_and(frame, frame, mask=mask) ``` #### 形态学变换优化轮廓 经过上述步骤得到二值化后的掩模图像后,还可以进一步利用形态学运算改善边界质量,去除孤立的小斑点以及填补内部孔洞等问题,从而获得更清晰完整的物体轮廓信息[^4]。 ```python kernel = np.ones((5, 5),np.uint8) opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel) ``` #### 轮廓分析找到圆形物体 最后一步就是基于改进过的二值图像进行轮廓发现,并计算各个候选区域内圆心位置及其半径大小,以此判断是否为所求得网球实体。 ```python contours, _ = cv2.findContours(closing.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:] for c in contours: ((x, y), radius) = cv2.minEnclosingCircle(c) M = cv2.moments(c) center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"])) if radius > 10: # 只考虑较大尺寸的对象 cv2.circle(frame, (int(x), int(y)), int(radius), (0, 255, 255), 2) cv2.circle(frame, center, 5, (0, 0, 255), -1) cv2.imshow("Frame", frame) ``` 以上即是一个基本框架下的网球检测流程说明,具体参数调整需视实际情况而定。值得注意的是,除了单纯依靠颜色匹配外,也可以引入更多高级技术手段如深度学习模型来进行更加精准可靠的分类判定[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值