# 接小球练习项目 **Repository Path**: llyxietan/getBall ## Basic Information - **Project Name**: 接小球练习项目 - **Description**: No description available - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2020-08-28 - **Last Updated**: 2024-11-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 1 接小球练习项目前言 ## 1.1 项目目的 通过摄像头获取运动物体的空间位置A:(X,Y,Z),并驱动机械臂A抓取运动物体 ## 1.2 项目问题分解 + 子问题1: - **物体追踪**:获取图片中特定物体的像素坐标B:(x,y) - **采用技术**:物体颜色追踪 + 子问题2: - **立体视觉**:将二维的像素坐标B转换为三维的空间坐标A - **采用技术**:双目立体匹配 + 子问题3: - **运动物体轨迹预测**:通过获取运动物体的n个空间坐标A,预测运动物体的轨迹 - **采用技术**:拟合 + 子问题4(测试): - **通过拟合数据驱使物理设备**:所得空间坐标(相机坐标系)是像素单位的情况下,需要测试像素与mm的映射比例和保持高精度的最佳距离区间(距离指物体和摄像头的距离) - **采用技术**:双目立体匹配 ## 1.3 项目目标 获取满足精度要求的运动物体的空间坐标轨迹,且确保在边缘端运行依旧满足时延要求(当摄像头为60-90fps时,每帧的算法时间是有限的) ## 1.4 本项目的其他思路 以下是项目学习过程中,非施行但具有参考意义的思路: + [基于视频流的羽毛球检测跟踪及轨迹预判算法应用研究;关键词:硕士毕设,三帧差分](http://d.wanfangdata.com.cn/thesis/D01761274) # 2 物体追踪/物体识别 ## 2.1算法一 ### 2.1.1参考博客 + [opencv Changing Colorspaces-基础](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_colorspaces/py_colorspaces.html#converting-colorspaces) + [《python+opencv实践》一、基于颜色的物体追踪(上)](https://blog.csdn.net/sinat_31135199/article/details/51252393) + [《python+opencv实践》一、基于颜色的物体追踪(下)](https://blog.csdn.net/sinat_31135199/article/details/51255182) ### 2.1.2代码说明 + 代码位置:*get_position.py->get_ball_xy*(image, colorLower, colorUpper) + 功能:求图片中颜色小球质心的**图像坐标**和**轮廓半径** + 注意事项/场景限制:选取颜色HSV阈值时确保背景无与小球颜色相同的背景,否则改算法不满足需求 # 3 立体视觉 立体视觉的核心是获取图片的深度信息,本质是二维坐标映射三维坐标的过程(二维到三维是信息增加的过程) ## 3.1 理论知识的准备/参考博客 以下博客是该项目所需的理论知识,以opencv calibrateCamera 官方文档为主线,期间遇到不明白的点:看博客或者源码可辅助理解(前期了解理论知识时如果顺带看源码,建议确保看懂每个变量的意义) + [opencv calibrateCamera 官方文档(非常重要)](https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#cv2.calibrateCamera) 几个必须要看的函数说明: - 获取内参:calibrateCamera - 获取外参:stereoCalibrate - 根据内外参进行相机标定:stereoRectify + [世界坐标系和相机坐标系,图像坐标系的关系](https://blog.csdn.net/wgx571859177/article/details/79564522) + 相机内外参概念 - [相机标定](https://blog.csdn.net/weilixin88/article/details/91603319) - [内外参细节](https://www.jianshu.com/p/2db2b167fb90) - [相机获取内参原理的博客,含代码](https://blog.csdn.net/piaoxuezhong/article/details/75268535) - [相机获取内参后,得到可用格式外参的博客](https://blog.csdn.net/weilixin88/article/details/91603319) + [立体匹配的数学原理](https://blog.csdn.net/piaoxuezhong/article/details/75268535) + [立体匹配的步骤,配可行代码](https://blog.csdn.net/dulingwen/article/details/98071584) + [解释Q含义的博客,以及相机坐标系的计算公式](https://blog.csdn.net/Gordon_Wei/article/details/86319058) ## 3.2 代码说明 ### 3.2.1本项目与立体匹配的异同 + 区别:**立体匹配**是还原整个二维图片的三维信息,其最终输出是深度图像;而**本项目**只需求得追踪物体质心的像素坐标(x,y)对应的相机坐标系下的相机坐标(X,Y,Z). + 相同:立体匹配与本项目获取像素点三维坐标的原理是一致的 ### 3.2.2 get_position.py 函数总览 + `get_position.py` 核心函数 - 调试类 - `double_camera_video` - `twoEye_camera_video` - `draw_line` - `show_img` - `DepthColor2Cloud` - `visualize` - `hw3ToN3` - 相机标定类 - `camera_calibration` - `get_img_corners` - `get_cameras_RTMat` - `rectifyImage_img` - `rectifyImage_map` - `seperate` - 物体追踪类 - `get_ball_xy` - 计算类 - `Undistort_pixel` - `disparity_pixel` - `get_camera_XYZ` - `calculate_camera_XYZ` - `preprocess` - `capture_ball` - 轨迹预测类 - `loss_function` ### 3.2.3 子问题1(物体追踪)代码 ``` python def get_ball_xy(image, colorLower, colorUpper): # 功能:求图片中颜色小球质心的图像坐标和轮廓半径 # 参数:colorLower,colorUpper:HSV空间颜色阈值 # return:未获取:False,成功:center_质心,radius_轮廓半径 # frame = imutils.resize(frame, width=600) # 转到HSV空间 hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 根据阈值构建掩膜 mask = cv2.inRange(hsv, colorLower, colorUpper) # 腐蚀操作 mask = cv2.erode(mask, None, iterations=2) # 膨胀操作,其实先腐蚀再膨胀的效果是开运算,去除噪点 mask = cv2.dilate(mask, None, iterations=2) cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] # 如果存在轮廓 if len(cnts) > 0: # 找到面积最大的轮廓 c = max(cnts, key=cv2.contourArea) # 确定面积最大的轮廓的外接圆 ((x, y), radius) = cv2.minEnclosingCircle(c) return (x, y), radius else: return (0, 0), 0 ``` ### 3.2.4 子问题2(立体视觉)代码 + example1:获取相机内外参 ``` python i,rvecs, tvecs=camera_calibration('test/photo/','jpg',4,4) # 具体调用看函数定义处说明,其会将内参保存至'test/photo/camera_internal_parameters.npy' img=cv2.imread('test/photo/1.jpg') inteP=np.load('test\photo\camera_internal_parameters.npy') para=get_camera_RTMat(img,4,4,inteP[0],inteP[1]) ``` + example2 实时物体追踪前的相机标定工作:获取双目相机外参->并进行立体矫正和畸变矫正 ``` python # doing_arg保存所有需要用到的参数 doing_arg = {} # 加载内参 """ doing_arg['intelPara_L'] = np.load( r'test_image/set7/camera_internal_parameters.npy') doing_arg['intelPara_R'] = np.load( r'test_image/set11/camera_internal_parameters.npy') """ doing_arg['intelPara_L'] = np.load( r'test_image/set16/left/camera_internal_parameters.npy', allow_pickle=True) doing_arg['intelPara_R'] = np.load( r'test_image/set16/right/camera_internal_parameters.npy', allow_pickle=True) # 图片统一尺寸 doing_arg['imageSize'] = (1280, 720) # 用于相机标定的棋盘的内角点数 doing_arg['cbrow'] = 9 doing_arg['cbcol'] = 6 # 物体追踪色域-绿色 #doing_arg['colorLower'] = np.array([37, 100, 59]) #doing_arg['colorUpper'] = np.array([91, 255, 255]) doing_arg['colorLower'] = np.array([30, 100, 59]) doing_arg['colorUpper'] = np.array([45, 255, 255]) # -------- imgL = cv2.imread(r'test_image\set16\for_extrinsic_parameters\left.jpg') imgR = cv2.imread(r'test_image\set16\for_extrinsic_parameters\right.jpg') # 获取外参 doing_arg['R'], doing_arg['T'] = get_cameras_RTMat( imgL, imgR, doing_arg['intelPara_L'], doing_arg['intelPara_R'], doing_arg['cbrow'], doing_arg['cbcol'], doing_arg['imageSize']) # 获取经过立体+畸变矫正后的投影矩阵 # doing_arg['map_Q']=map1x, map1y,map2x, map2y doing_arg['map_Q'] = rectifyImage_map(imgL, imgR, doing_arg['intelPara_L'], doing_arg['intelPara_R'], doing_arg['imageSize'], doing_arg['R'], doing_arg['T']) ``` ## 3.2 数据集说明 + 所有数据测试集都在目录`\test_image\set*\`下 + `\test_image\set6\`:opencv 官方数据集 + set7-12:普通摄像头拍摄的照片,起初测试代码时,是用俩个普通摄像头平行放置模拟双目摄像头 + set13-15:低配双目摄像头图片集(set15带视频集) + set16-17:高帧率高清摄像头图片集(set17带视频集) # 随记 + 代码函数多了,测试集多了以后一定要做目录说明,不然很乱 + 用jupyter调试,挺好用 + 良好的测试方式,十分有助于分析.丁翀那种大致测一下,直观感受一下误差的方式其实效率很高,有助于下一次确定下一次测试的方向 + 如果摄像头内仅存在一个移动物体,可以通过俩帧之间做差值来追踪物体,神奇! + 应该多借助文献的,尤其是毕业论文 + 0919的数据分析结果: - 像素点到毫米的映射大致是维持在一个合理的区间的,模型是可行的 - X,Y,D轴像素点到毫米的映射居然**不一样**,差很多,不知道这样是否是错误 - 理论上,距离摄像头,误差越小,可是早上测试的结果和理论假设不相符,反而丁翀0918测的很符合越近越准 - 感觉现有测试还是没法找到可靠的像素点到毫米映射,但是其空间坐标系是合理的,虽然固定轴上的值仍有波动,但在容许范围内.