风力摆设计-坤罗海.doc

风力摆设计(比赛)

收藏

压缩包内文档预览:(预览前20页/共23页)
预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图 预览图
编号:36008458    类型:共享资源    大小:7.41MB    格式:ZIP    上传时间:2019-12-31 上传人:遗**** IP属地:湖北
30
积分
关 键 词:
风力 设计 比赛
资源描述:
风力摆设计(比赛),风力,设计,比赛
内容简介:
第十二届智能控制设计大赛第十二届智能控制设计大赛 设计报告设计报告 基于摄像头的目标跟随系统基于摄像头的目标跟随系统 学学 院院 自动化科学与工程学院 专专 业业 智能科学与技术 学生姓名学生姓名 毛适 牛雅儒 施翔宇 队队 名名 MSN 提交日期提交日期 2017 年 5 月 20 日 目录目录 一、一、 题目介绍题目介绍 . 1 二、二、 功能介绍功能介绍 . 2 三、三、 方案比较方案比较 . 3 四、四、 设计与论证设计与论证 . 5 五、五、 作品所用模块电路原理及原理图作品所用模块电路原理及原理图 . 9 六、六、 作品展示作品展示 . 13 七、七、 程序代码程序代码 . 16 1 一、一、题目介绍题目介绍 (一)基本要求: 1.通过摄像头寻找三维空间内的目标物体,并标记在图像上(背景、 目标物体可根据需求自定义,限制条件少者,分数相对较高) ; 2.控制摄像头支架跟随目标物体移动,使目标物体保持在摄像头视野正中央位置(考察指标:稳、快、准) ; 3.设计良好的人机界面,用于展示原始图像以及处理结果等信息; (二)扩展要求: 1.摄像头支架自由度冗余情况下, 实现目标物体的跟随; 2.跟随目标物体的任意化; 3.对跟随目标进行定位(测距或展示在以跟随系统为坐标原点的坐标系中的坐标) ; 4.能够实现对目标物体的三维立体重建; 5.其他拓展功能。 (三)补充说明: 1.目标跟随控制, 要考察完成时间及准确性; 2.禁止使用上电后自动稳定的云台; 3.只允许使用摄像头提供的 RGB 图像信息,禁止使用摄像头提供的深度信息; 4.图像的正中心必须在图像上标出; 5.摄像头支架总长度小于 50cm,总体积小于 50cm*20cm*20cm。 2 二、功能介绍功能介绍 (一)作品基础功能 1.通过摄像头寻找三维空间内的目标物体,并标记在图像上。 2.控制摄像头支架跟随目标物体移动,使目标物体保持在摄像头视野正中央位置。 3.有良好的人机界面,用于展示原始图像以及处理结果等信息。 (二)作品拓展功能 1.实现目标物体的跟随。 2.跟随目标物体的多样化(人脸、字母、乒乓球等) 3.对跟随目标进行定位(展示以跟随系统为坐标原点的坐标系中的坐标) 4.通过机械臂,对目标物体的抓取。 (三)各项功能完成统计表 各项功能完成情况如下表 项目要求 完成情况 基础功能 设计与总结报告 完成。 通过摄像头寻找目标物体并标记 完成,能够准确寻找三维空间内的目标物体,并标记在图像上。 跟随目标物体移动 完成,能够快速、准确、稳定控制摄像头支架跟随目标物体移动,使目标物体保持在摄像头视野正中央位置 良好的人机界面 完成, 利用 MFC 设计良好的人机界面, 用于展示原始图像以及处理结果等信息。 拓展功能 自 由 度 冗 余 情 况下, 实现目标物体的跟随 完成。 跟随目标物体的任意化 完成,能够跟随人脸、字母、乒乓球等物体。 定位跟随目标 完成,在以跟随系统为坐标原点的坐标系中展示坐3 标。 抓取目标 完成,利用机械臂抓取跟随目标。 三、三、方案比较方案比较 (一)字母识别方案比较 1.方案一:利用随机森林法(RF)进行识别 优点:它能够处理很高维度的数据,并且不用做特征选择;在训练完后,它能够给出哪些特征比较重要;模型泛化能力强;训练速度快,容易做成并行化方法;实现比较简单;对于不平衡的数据集来说,它可以平衡误差;如果有很大一部分的特征遗失,仍可以维持准确度。 缺点:在某些噪音较大的分类或回归问题上会过拟; 2.方案二:利用支持向量机(SVM)进行识别 优点: 可以解决小样本情况下的机器学习问题。可以提高泛化性能。可以解决高维问题。可以解决非线性问题。可以避免神经网络结构选择和局部极小点问题。 缺点:对缺失数据敏感。对非线性问题没有通用解决方案,必须谨慎选择 Kernelfunction 来处理 3.总结:通过对比方案一与方案二优缺点,最后决定利用随机森林法进行识别. (二)颜色识别方案比较 1.方案一:选择彩色模型(RGB) 三维坐标: 4 原点到白色顶点的中轴线是灰度线,r、g、b 三分量相等,强度可以由三分量的向量表示。 用 RGB 来理解色彩、深浅、明暗变化: 色彩变化: 三个坐标轴 RGB 最大分量顶点与黄紫青 YMC 色顶点的连线 深浅变化:RGB 顶点和 CMY 顶点到原点和白色顶点的中轴线的距离 明暗变化:中轴线的点的位置,到原点,就偏暗,到白色顶点就偏亮, 2.方案二:选择 HSV 模型 倒锥形模型: 这个模型就是按色彩、深浅、明暗来描述的。 H 是色彩 S 是深浅, S = 0 时,只有灰度 V 是明暗,表示色彩的明亮程度,但与光强无直接联系 3.方案三:选择 RGB 转 HSV 模型 从上面的直观的理解,把 RGB 三维坐标的中轴线立起来,并扁化,就能形成 HSV 的锥形模型了。 但 V 与强度无直接关系,因为它只选取了 RGB 的一个最大分量。而 RGB 则能反映光照强度(或灰度)的变化。 有方便设置阈值、方便分离颜色的优点 4.总结:通过对比方案一、方案二与方案三优缺点,最后决定选择 RGB转 HSV 模型进行颜色识别 5 四、四、设计设计与论证与论证 (一)图像识别 1.字母识别:随机森林法(RF) 1)学习分类器 根据训练样本, 选取模型训练产生数字分类器。 这里的样本我们采用的是使用多种字体进行多种程度的放射变换作为训练的原始图像。 另外这里由于模式并不复杂, 计算量也不大, 所以不对样本进行特征提取, 对原始样本作简单二值化和防锁变换变换后直接作为 8*8的训练样本。 具体地, 首先是生成训练样本矩阵, 一般样本是以二维矩阵的方式存在文件当中,现在要将它们读出来,进行适当的预处理,然后生成 OpenCV 能理解的数据结构。并训练随机森林的分类器,作为.xml 文件存储。 2)图像分割 接下来, 就可以对图像进行分割了。 由于我们的分类器只能对数字一个一个地识别, 所以首先要把每个数字分割出来。 基本思想是先用 findContours()函数把基本轮廓找出来,然后通过简单验证以确认是否为数字的轮廓。对于那些通过验证的轮廓,接下去会用boundingRect()找出它们的包围盒。 3)应用分类器 分割完后就可以应用我们前面训练好的分类器对分割结果进行识别了。 当然, 如果感觉结果不满意, 可以将分类错误的样本加上正确的标签后放入训练样本重新生成分类器,使得分类器能够有更好的识别率。上一步中的调用生成的 xml 文件的函数就是利用先前训练好的分类器识别单个数字。注意训练样本进行过怎么样的预处理,这里也一样要做。 2.颜色识别(RGB 转 HSV) 把 RGB 三维坐标的中轴线立起来,并扁化,就能形成 HSV 的锥形模型了。 6 但 V 与强度无直接关系,因为它只选取了 RGB 的一个最大分量。而 RGB 则能反映光照强度(或灰度)的变化。 v = max(r, g, b) 由 RGB 到 HSV 的转换: 3.图像识别 霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果。 霍夫变换于 1962 年由 PaulHough 首次提出,最初的 Hough 变换是设计用来检测直线和曲线,起初的方法要求知道物体边界线的解析方程,但不需要有关区域位置的先验知识。这种方法的一个突出优点是分割结果的 Robustness,即对数据的不完全或噪声不是非常敏感。然而,要获得描述边界的解析表达常常是不可能的。 后于 1972 年由 Richard Duda & Peter Hart 推广使用, 经典霍夫变换用来检测图像中的直线, 后来霍夫变换扩展到任意形状物体的识别,多为圆和椭圆。霍夫变换运用两个坐标空间之间的变换将在一个空间中具有相同形状的曲线或直线映射到另一个坐标空间的一个点上形成峰值,从而把检测任意形状的问题转化为统计峰值问题。 在 OpenCV 中,我们一般通过一个叫做“霍夫梯度法”的方法来解决圆变换的问题。 霍夫梯度法的原理: 首先对图像应用边缘检测,比如用 canny 边缘检测。 7 然后, 对边缘图像中的每一个非零点, 考虑其局部梯度, 即用 Sobel()函数计算 x 和 y 方向的 Sobel 一阶导数得到梯度。 利用得到的梯度,由斜率指定的直线上的每一个点都在累加器中被累加,这里的斜率是从一个指定的最小值到指定的最大值的距离。 同时,标记边缘图像中每一个非 0 像素的位置。 然后从二维累加器中这些点中选择候选的中心,这些中心都大于给定阈值并且大于其所有近邻。这些候选的中心按照累加值降序排列,以便于最支持像素的中心首先出现。 接下来对每一个中心,考虑所有的非 0 像素。 这些像素按照其与中心的距离排序。从到最大半径的最小距离算起,选择非 0 像素最支持的一条半径。 如果一个中心收到边缘图像非 0 像素最充分的支持,并且到前期被选择的中心有足够的距离,那么它就会被保留下来。 这个实现可以使算法执行起来更高效,或许更加重要的是,能够帮助解决三维累加器中 会产生许多噪声并且使得结果不稳定的 稀疏分布问题。 4.人脸识别 通过调用 OpenCV 库中的 haarcascade_frontalface_alt2.xml 文件, 实现人脸识别。 (二)目标定位 机器人正运动学 工业机器人的正向运动学是指已知各关节的类型、相邻关节之间的尺寸和相邻关节相对运动量的大小时,如何确定工业机器人末端操作器在固定坐标系中的位姿。 主要包括以下内容:相对杆件的坐标系的确定;建立各连杆的模型矩阵A;正运动学算法。 总体思想:首先给每个关节指定坐标系,然后确定从一个关节到下一个关节进行变化的步骤,这体现在两个相邻参考坐标系之间的变化,将所有变8 化结合起来, 就确定了末端关节与基座之间的总变化, 从而建立运动学方程,进一步对其求解。 第一个自由度的旋转矩阵 A1 = c1, 0, s1, l1*s1 0, 1, 0, 0 -s1, 0, c1, c1*l1 0, 0, 0, 1 第二个自由度的旋转矩阵 A2 = c2, 0, s2, l2*s2 0, 1, 0, 0 -s2, 0, c2, c2*l2 0, 0, 0, 1 第三个自由度的旋转矩阵 A3 = c3, 0, s3, c3*h + l3*s3 0, 1, 0, 0 -s3, 0, c3, c3*l3 - h*s3 0, 0, 0, 1 摄像头自由度的旋转矩阵 A4 = c4, 0, s4, d*s4 0, 1, 0, 0 -s4, 0, c4, c4*d 0, 0, 0, 1 9 各个旋转矩阵相乘得到矩阵 A=A1*A2*A3*A4,矩阵 A 的1434AA和分别是目标物体在世界坐标系的 X 轴坐标和 Z 轴坐标, 这样, 目标的位置就确定了。其中,11cosc,11sins,以此类推 ,l1、l2、l3 分别代表各旋转轴之间的距离,d 代表目标物体在摄像头坐标系中的深度。h 代表摄像头的偏移量。 (三)目标抓取 机器人逆运动学 给定机器人终端位姿,求各关节变量,称求机器人运动学逆解。 对目标物体的抓取使用了五个自由度,分别对应 1、2、3、4、6 号舵机, 上一步已经得到了目标物体在世界坐标系中的位置,下面计算 A=A1*A2*A3,机械臂末端位置的 X 坐标可以表示为14A ,Z 坐标可表示为34A,联立方程组14A=14A,34A=34A,由此可以解得机械臂三个关节 的关节角度,使得机械臂末端可以到达目标物体所在的值 五、五、作品所用模块电路原理及原理图作品所用模块电路原理及原理图 (一)51 控制板(STC15W4K60S4 芯片) 10 部分原理图: 11 (二)TBS2701 数字舵机 1.产品尺寸 2.产品特点 1)高精度:采用进口电位器,精度和线性度远超市面上的同类数字舵机。 2)270 度转动:可控角度 270,线性度好,断电可 360转动。 3)15kg 大扭力:噪音小、精度高。 4)全金属齿轮:全金属齿轮、寿命长。 3.产品原理 舵机 PWM 脉冲调节角度,周期 20ms,占空比 0.5ms2.5ms 的脉冲点平对应舵机 0270角度范围, 且成线性关系。 控制精度是 3us, 在 2000个脉宽范围内最小控制精度能达 0.2 (三)TBSN-K15 耐烧数字舵机 1.产品尺寸 12 2.产品特点 1)耐烧:内部过载保护,尽可能避免舵机因过载而烧坏 2)180 度转动:可控角度 180,线性度好,断电可 360转动。 3)15kg 大扭力:噪音小、精度高。 4)全金属齿轮:全金属齿轮、寿命长。 3.产品原理 舵机 PWM 脉冲调节角度,周期 20ms,占空比 0.5ms2.5ms 的脉冲点平对应舵机 0180角度范围,且成线性关系。 (四)罗技 C270 高清摄像头 产品特点:视频拍摄分辨率高达 1280*720 像素,高清 720p。 13 六、六、作品展示作品展示 (一)正视图 (二)侧视图 14 (三)俯视图 (四)人脸识别 15 (五)字母识别 (六)目标跟随与抓取 16 七、七、程序代码程序代码 /人脸跟踪 void CMFC_COMDlg:OnBnClickedButton2() / TODO: Add your control notification handler code here VideoCapture cap(1); Mat frame; CascadeClassifier face_cascade; Point objcenter,framecenter; /该文件存在于 OpenCV 安装目录下的sourcesdatahaarcascades 内,需要将该 xml 文件复制到当前工程目录下 if (!face_cascade.load(haarcascade_frontalface_alt2.xml) printf(级联分类器错误,可能未找到文件,拷贝该文件到工程目录下!n); int dx = 0, dy = 0; /初始化差值,表示 objCenter-frameCenter int threshold = 10;/中央圆大小 /伺服电机控制程序 /初始化电极 for (int i = 0; i 6; i+) servoAnglesi = 1500; servoAngles5 = 1200; servoAngles3 = 2200; servoAngles2 = 1300; sendCommands(servoAngles, 1000); while (1) for (int i = 0; i frame; framecenter = Point(frame.cols / 2, frame.rows / 2); objcenter = framecenter; detectAndDisplay(frame, face_cascade, objcenter); /调用人脸检测函数 /绘制差值线 line(frame, objcenter, framecenter, Scalar(0, 255, 0), 1); dy = objcenter.y - framecenter.y; dx = objcenter.x - framecenter.x; 17 if (dy threshold | dy threshold*15 | dy threshold | dx threshold*15 | dx -threshold*15) servoAdd0 = -dx / 5; /绘制中央十字交叉线 line(frame, Point(frame.cols / 2, 0), Point(frame.cols / 2, frame.rows),Scalar(0,0,255),1); line(frame, Point(0, frame.rows/2), Point(frame.cols , frame.rows/2), Scalar(0, 0, 255),1); cv:imshow(view, frame); sendCommandsAdd(servoAdd, 200); /乒乓球抓取 void CMFC_COMDlg:OnBnClickedButton4() / TODO: Add your control notification handler code here VideoCapture cap(1); Mat frame; Point objcenter, framecenter; int dx = 0, dy = 0; /初始化差值,表示 objCenter-frameCenter int threshold = 20;/中央圆大小 /伺服电机控制程序 /初始化电极 for (int i = 0; i 6; i+) 18 servoAnglesi = 1500; servoAngles5 = 1200; servoAngles3 = 2400; servoAngles2 = 1250; sendCommands(servoAngles, 1000); namedWindow(Control, CV_WINDOW_AUTOSIZE); /create a window called Control int iLowH = 0; int iHighH = 70; int iLowS = 0; int iHighS = 255; int iLowV = 220; int iHighV = 255; /Create trackbars in Control window cvCreateTrackbar(LowH, Control, &iLowH, 179); /Hue (0 - 179) cvCreateTrackbar(HighH, Control, &iHighH, 179); cvCreateTrackbar(LowS, Control, &iLowS, 255); /Saturation (0 - 255) cvCreateTrackbar(HighS, Control, &iHighS, 255); cvCreateTrackbar(LowV, Control, &iLowV, 255); /Value (0 - 255) cvCreateTrackbar(HighV, Control, &iHighV, 255); /【4】进行霍夫圆变换 vector circles; sendCommands(servoAngles, 1000); while (1) cap frame; /角度递增值初始化为 0 for (int i = 0; i 6; i+) servoAddi = 0; /objcenter = Point(frame.cols / 2, frame.rows / 2); framecenter = Point(frame.cols / 2, frame.rows / 2); 19 objcenter = framecenter; /-开始处理乒乓球识别-/ Mat imgHSV; vector hsvSplit; cvtColor(frame, imgHSV, COLOR_BGR2HSV); /Convert the captured frame from BGR to HSV /因为我们读取的是彩色图,直方图均衡化需要在 HSV 空间做 split(imgHSV, hsvSplit); equalizeHist(hsvSplit2, hsvSplit2); merge(hsvSplit, imgHSV); Mat imgThresholded; inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); /Threshold the image /开操作 (去除一些噪点) Mat element = getStructuringElement(MORPH_RECT, Size(3, 3); morphologyEx(imgThresholded, imgThresholded, MORPH_OPEN, element); /闭操作 (连接一些连通域) morphologyEx(imgThresholded, imgThresholded, MORPH_CLOSE, element); Mat srcImage(2, imgThresholded.size, CV_8UC3, Scalar:all(80); /-轮廓最小包围圆方法-/ /imshow(【threshold】, imgThresholded); /边界存储 /vectorvectorcontours; /vector hierarchy; /Mat imgThresholdedSave; /imgThresholded.copyTo(imgThresholdedSave); /findContours(imgThresholdedSave, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);/寻找边界 /Point2f c; /float r; /for (unsigned int i = 0; i SetWindowText(XYZ); XYZ.Format(Y:%f, Y); GetDlgItem(IDC_STATICY)-SetWindowText(XYZ); XYZ.Format(Z:%f, Z); GetDlgItem(IDC_STATICZ)-SetWindowText(XYZ); /dis.Format(%d, radius); GetDlgItem(IDC_DIS)-SetWindowText(dis); /-结束乒乓球识别-/ /【6】退出检测 char key = (char)waitKey(300); if (key = 27) break; /绘制差值线 line(frame, objcenter, framecenter, Scalar(0, 255, 0), 1); dy = objcenter.y - framecenter.y; dx = objcenter.x - framecenter.x; if (dy threshold | dy threshold * 15 | dy threshold | dx threshold * 15 | dx -threshold & dx -threshold & dy threshold &circles.size()=1)/大致在范围内了 cv:imshow(view, frame); waitKey(20); double a = 0, b = 0, theta1=0; double s1 = 0, c1 = 1; bool valid = true; theta1 = -(servoAngles1 - 1500) / 1000.0 * 135; theta1=theta1/180.0*3.1415926535; s1 = sin(theta1); c1 = cos(theta1); calWorldframe(objDist,s1,c1, servoAngles, a, b); b -= 2.0; valid = calcAngles(a, b, s1,c1); if (valid)/可以达到 sendCommands(servoAngles, 1500); waitKey(1500); servoAngles5 = 1700;/抓取 sendCommands(servoAngles, 1500); waitKey(500); /初始化电极,即抓取回到初始角度 for (int i = 0; i 6; i+) servoAnglesi = 1500; servoAngles5 = 1700; servoAngles3 = 2200; servoAngles2 = 1300; sendCommands(servoAngles, 3000); sendCommands(servoAngles, 3000); break;/跳出循环 else/不可达到 23 servoAdd1 = -50; servoAdd2 = -40; /绘制中央十字交叉线 line(frame, Point(frame.cols / 2, 0), Point(frame.cols / 2, frame.rows), Scalar(0, 0, 255), 1); line(frame, Point(0, frame.rows / 2), Point(frame.cols, frame.rows / 2), Scalar(0, 0, 255), 1); cv:imshow(view, frame); /sendCommand(4, servoAngles3, 80); /sendCommand(1, servoAngles0, 80); sendCommandsAdd(servoAdd, 300); waitKey(50); /字母识别抓取 void CMFC_COMDlg:OnBnClickedButton5() / TODO: Add your control notification handler code here CvRTrees forest; forest.load(classifier3.xml); /输入识别的砖块 UpdateData(TRUE); int brick8 = 0 ; int len = CharToRec.GetLength(); string chara; for (int i = 0; i CharToRec.GetLength(); i+) chara = CharToRec.GetAt(i); if (chara = A)brick0 = 1; if (chara = B)brick1 = 1; if (chara = C)brick2 = 1; if (chara = D)brick3 = 1; if (chara = E)brick4 = 1; if (chara = F)brick5 = 1; if (chara = G)brick6 = 1; if (chara = H)brick7 = 1; VideoCapture cap(1); Mat mat; Point objcenter, framecenter; int dx = 0, dy = 0; /初始化差值,表示 objCenter-frameCenter 24 int centerThresholdRadius = 20;/中央圆大小 /伺服电机控制程序 /初始化电极 for (int i = 0; i mat; framecenter = Point(mat.cols / 2, mat.rows / 2); objcenter = framecenter; /角度递增值初始化为 0 for (int i = 0; i 6; i+) servoAddi = 0; Mat grayMat, BinaryMat; cvtColor(mat, grayMat, COLOR_RGB2GRAY); /!注意这里的二值化条件 threshold(grayMat, BinaryMat, thresholdval, 255, THRESH_BINARY_INV);/二值化, /dilate(BinaryMat, BinaryMat, NULL);/膨胀 /erode(BinaryMat, BinaryMat, NULL); /腐蚀 /模板文件读取 Mat tmplt = imread(tmplt_8_16p_B.png, CV_LOAD_IMAGE_GRAYSCALE); threshold(tmplt, tmplt, 100, 255, CV_THRESH_BINARY); /0-255 转成 0-1 /threshold(BinaryMat, BinaryMat, 100, 1, CV_THRESH_BINARY); 25 /threshold(Btmplt, Btmplt, 100, 1, CV_THRESH_BINARY); /边界存储 vectorvectorcontours; vector hierarchy; Mat BianaryMatSave; BinaryMat.copyTo(BianaryMatSave); findContours(BianaryMatSave, contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);/寻找边界 /在 RGB 图像上填充式绘制包围圈,检测用 /for (int index = 0; index = 0; index = hierarchyindex0) / /Scalar color(rand() & 255, rand() & 255, rand() & 255); /drawContours(mat, contours, index, color, CV_FILLED, 8, hierarchy); / /找垂直框矩形 vector boundRect(contours.size(); int size;/字母的大小 int validCount = 0; for (unsigned int i = 0; i 1.0 & hVSw 1.5)judge = 2;/出千的方法,B 字母的长宽比最大 if (brickjudge - 1 = 1 & size 1000)/关键判断语句,当砖块需要被运走并且大小大致符合距离要求时 switch (judge) case 1:rectangle(mat, boundRecti.tl(), boundRecti.br(), Scalar(0, 0, 0), 2, 8, 0); break; case 2:rectangle(mat, boundRecti.tl(), boundRecti.br(), Scalar(255, 0, 0), 2, 8, 0); break; case 3:rectangle(mat, boundRecti.tl(), boundRecti.br(), Scalar(0, 255, 0), 26 2, 8, 0); break; case 4:rectangle(mat, boundRecti.tl(), boundRecti.br(), Scalar(0, 0, 255), 2, 8, 0); break; case 5:rectangle(mat, boundRecti.tl(), boundRecti.br(), Scalar(128, 128, 128), 2, 8, 0); break; case 6:rectangle(mat, boundRecti.tl(), boundRecti.br(), Scalar(255, 255, 0), 2, 8, 0); break; case 7:rectangle(mat, boundRecti.tl(), boundRecti.br(), Scalar(255, 0, 255), 2, 8, 0); break; case 8:rectangle(mat, boundRecti.tl(), boundRecti.br(), Scalar(0, 255, 255), 2, 8, 0); break; /default:rectangle(mat, boundRecti.tl(), boundRecti.br(), Scalar(255, 255, 255), 2, 8, 0); break; default: break; objcenter = Point(boundRecti.x + boundRecti.width / 2, boundRecti.y + boundRecti.height / 2); circle(mat, objcenter, 5, Scalar(0, 0, 255), 3); validCount+; /待填写 if (size != 0) /objDist = 1596.5*pow(sqrt(size), -0.94); objDist = 2261.7*pow(sqrt(size), -0.989); /CString dis; /dis.Format(%d, size); /GetDlgItem(IDC_DIS)-SetWindowText(dis); if (validCount = 1)/判断是否只有一个有效的识别 objDist -= 4; CString dis; dis.Format(_T(%f), objDist); GetDlgItem(IDC_DIS)-SetWindowText(dis); CString XYZ; XYZ.Format(X:%f, X); GetDlgItem(IDC_STATICX)-SetWindowText(XYZ); XYZ.Format(Y:%f, Y); GetDlgItem(IDC_STATICY)-SetWindowText(XYZ); XYZ.Format(Z:%f, Z); 27 GetDlgItem(IDC_STATICZ)-SetWindowText(XYZ); double a = 0, b = 0, theta1 = 0, theta0 = 0; double s1 = 0, c1 = 1; bool valid = true; theta1 = -(servoAngles1 - 1500) / 1000.0 * 135; theta1 = theta1 / 180.0*3.1415926535; theta0 = (servoAngles0 - 1500) / 1000.0 * 135; theta0 = theta0 / 180.0*3.1415926535; s1 = sin(theta1); c1 = cos(theta1); calWorldframe(objDist, s1, c1, servoAngles, a, b); X = a*cos(theta0); Y = a*sin(theta0); Z = b; /绘制差值线 line(mat, objcenter, framecenter, Scalar(0, 255, 0), 1); dy = objcenter.y - framecenter.y; dx = objcenter.x - framecenter.x; if (dy centerThresholdRadius | dy centerThresholdRadius * 15 | dy centerThresholdRadius | dx centerThresholdRadius*15 | dx -centerThresholdRadius & dx -centerThresholdRadius & dy centerThresholdRadius &validCount = 1)/大致在范围内了 28 cv:imshow(view, mat); waitKey(20); double a = 0, b = 0, theta1 = 0; double s1 = 0, c1 = 1; bool valid = true; theta1 = -(servoAngles1 - 1500) / 1000.0 * 135; theta1 = theta1 / 180.0*3.1415926535; s1 = sin(theta1); c1 = cos(theta1); calWorldframe(objDist, s1, c1, servoAngles, a, b); b += 1.0; valid = calcAngles(a, b, s1, c1); if (valid)/可以达到 sendCommands(servoAngles, 1500); waitKey(1500); servoAngles5 = 1700;/抓取 sendCommands(servoAngles, 1500); waitKey(500); /初始化电极,即抓取回到初始角度 for (int i = 0; i 6; i+) servoAnglesi = 1500; servoAngles5 = 1700; servoAngles3 = 2200; servoAngles2 = 1300; sendCommands(servoAngles, 2500); break;/跳出循环 else/不可达到 servoAdd1 = -50; servoAdd2 = -40; /sendCommands(servoAngles, 200); sendCommandsAdd(servoAdd, 300); /绘制中央十字叉线 line(mat, Point(mat.cols / 2, 0), Point(mat.cols / 2, mat.rows), Scalar(0, 0, 255), 1); line(mat, Point(0, mat.rows / 2), Point(mat.cols, mat.rows / 2), Scalar(0, 0, 255), 1); /显示 29 /imshow(Binary, BinaryMat); /imshow(BianaryMatSave, BianaryMatSave); imshow(view, mat); waitKey(3); /【6】退出检测 char key = (char)waitKey(300); if (key = 27) break; /发送伺服电机控制指令 void CMFC_COMDlg:sendCommand(int servoIndex, int degree, int delayTime) CString command; command.Format(_T(#%dP%dT%drn), servoIndex, degree, delayTime); m_ctrlComm.put_Output(COleVariant(command); /发送数据 waitKey(delayTime); /发送伺服电机控制指令集(强制模式) void CMFC_COMDlg:sendCommands(int degree6, int delayTime) CString command = _T(); command.AppendFormat(_T(rn); m_ctrlComm.put_Output(COleVariant(command); for (int j = 0; j 6; j+) if (degreej 2500 )degreej = 2400; command=; for (int i = 0; i 6; i+) command.AppendFormat(_T(#%dP%d), i + 1, degreei); command.AppendFormat(_T(T%drn), delayTime); 30 m_ctrlComm.put_Output(COleVariant(command); /发送数据 waitKey(50); m_ctrlComm.put_Output(COleVariant(command); /发送数据 waitKey(delayTime); /发送伺服电机控制指令集(增量模式) void CMFC_COMDlg:sendCommandsAdd(int AddDegree6, int delayTime) int count = 0; CString command = _T(); for (int i = 0; i 6; i+) if (AddDegreei != 0) servoAnglesi += AddDegreei; if (servoAnglesi 2500)servoAnglesi = 2400; command.AppendFormat(_T(#%dP%d), i + 1, servoAnglesi); count+; if (count != 0) command.AppendFormat(_T(T%drn), delayTime); m_ctrlComm.put_Output(COleVariant(command); /发送数据 waitKey(delayTime); waitKey(20); /打开串口 void CMFC_COMDlg:OnBnClickedButton3() / TODO: Add your control notification handler code here UpdateData(TRUE); int port = _ttoi(ComSerNum); /串口 m_ctrlComm.put_CommPort(port); /选择串口号 5(笔记本没有串口,用的虚拟串口,可以使用软件 vspd 创建) m_ctrlComm.put_PortOpen(TRUE); /打开串口 31 m_ctrlComm.put_RThreshold(2); /收到两个字节引发 OnComm 事件 m_ctrlComm.put_InputMode(1); /输入模式选为二进制 m_ctrlComm.put_Settings(_T(115200,n,8,1); /设置串口参数,波特率,无奇偶校验,位停止位,位数据位 m_ctrlComm.put_InputMode(1); / 以二进制方式检取数据 m_ctrlComm.put_RThreshold(1); /参数 1 表示每当串口接收缓冲区中有多于或等于 1 个字符时将引发一个接收数据的 OnComm 事件 m_ctrlComm.put_InputLen(0); /设置当前接收区数据长度为 0 m_ctrlComm.get_Input();/先预读缓冲区以清除残留数据 MessageBox(_T(串口已连接), _T(yeah); /绘制图片 void CMFC_COMDlg:DrawPicToHDC(IplImage *img, UINT ID) CDC *pDC = GetDlgItem(ID)-GetDC(); HDC hDC = pDC-GetSafeHdc(); CRect rect; GetDlgItem(ID)-GetClientRect(&rect); CvvImage cimg; cimg.CopyOf(img); / 复制图片 cimg.DrawToHDC(hDC, &rect ); / 将图片绘制到显示控件的指定区域内 ReleaseDC(pDC ); /人脸识别 void CMFC_COMDlg:detectAndDisplay(Mat& face, CascadeClassifier face_cascade,Point& center) std:vector faces; Mat face_gray; cvtColor(face, face_gray, CV_BGR2GRAY); /rgb 类型转换为灰度类型 equalizeHist(face_gray, face_gray); /直方图均衡化 face_cascade.detectMultiScale(face_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30); int maxSize = 0,temp=0,maxIndex=0; if (faces.size() != 0) /找最大的脸 for (int i = 0; i maxSize) maxSize = temp; maxIndex = i; center=Point(int(facesmaxIndex.x + facesmaxIndex.width*0.5), int(facesmaxIndex.y + facesmaxIndex.height*0.5); circle(face, center, 4, Scalar(0, 0, 255), 3); ellipse(face, center, Size(int(facesmaxIndex.width*0.5), int(facesmaxIndex.height*0.5), 0, 0, 360, Scalar(255, 0, 0), 4, 8, 0); /imshow(人脸识别, face); / 随机森林验证 int CMFC_COMDlg:ms_rForestMatch(Mat inputMat, CvRTrees& forest) if (forest.get_tree_count() = 0) printf(Could not read the classifier %sn, a.xml); return -1; Mat mat; inputMat.copyTo(mat); resize(mat, mat, Size(8, 8); uchar* sdata = mat.ptr(0); CvMat* data = 0; data = cvCreateMat(1, 64, CV_32F); float* ddata = data0.data.fl; for (int j = 0; j 64; j+) ddataj = sdataj / 256.0; int r = forest.predict(data); return r; void CMFC_COMDlg:calWorldframe(int d, int servoAng6, double &a, double &b) 33 double degree6 = 0 ; transformangles(servoAngles, degree, 0); for (int i = 0; i 6; i+) degreei = degreei / 180 * 3.141592653; double l1 = 10.4; double l2 = 9.9; double l3 = 12; double h = -6; double s1 = 0; double c1 = 1; double s2 = sin(degree2); double c2 = cos(degree2); double s3 = sin(degree3); double c3 = cos(degree3); double c4 = cos(32 * 3.141592653 / 180.0); double s4 = sin(32 * 3.141592653 / 180.0); a = l1*s1 + (c3*h + l3*s3)*(c1*c2 - s1*s2) + (c3*l3 - h*s3)*(c1*s2 + c2*s1) + c1*l2*s2 + c2*l2*s1 + c4*d*(c3*(c1*s2 + c2*s1) + s3*(c1*c2 - s1*s2) + d*s4*(c3*(c1*c2 - s1*s2) - s3*(c1*s2 + c2*s1); b = c1*l1 - (c3*h + l3*s3)*(c1*s2 + c2*s1) + (c3*l3 -
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
提示  人人文库网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
关于本文
本文标题:风力摆设计(比赛)
链接地址:https://www.renrendoc.com/p-36008458.html

官方联系方式

2:不支持迅雷下载,请使用浏览器下载   
3:不支持QQ浏览器下载,请用其他浏览器   
4:下载后的文档和图纸-无水印   
5:文档经过压缩,下载后原文更清晰   
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

网站客服QQ:2881952447     

copyright@ 2020-2025  renrendoc.com 人人文库版权所有   联系电话:400-852-1180

备案号:蜀ICP备2022000484号-2       经营许可证: 川B2-20220663       公网安备川公网安备: 51019002004831号

本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知人人文库网,我们立即给予删除!