毕业设计-基于机器视觉乒乓球分类捡球机器人的设计与实现 -OpenCV

目录


前言


    📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过和节省时间与精力投入到更重要的就业和考试中去,学长分享优质的选题经验和毕设项目与技术思路。

🚀对毕设有任何疑问都可以问学长哦!

选题指导: https://blog.csdn.net/qq_37340229/article/details/128243277

大家好,这里是海浪学长毕设专题,本次分享的课题是

🎯基于机器视觉乒乓球分类捡球机器人的设计与实现 -OpenCV 

课题背景和意义

随着人们对机器人技术智能化本质认识的加深,机器人技术开始源源不断地向人类活动的各个领域渗透。在这其中,服务机器人作为一个重要分支,在国内外研究领域已经得到普遍重视。服务机器人的应用范围很广,主要从事维护保养、修理、运输、清洗、保安、救援、监护等工作。但至目前为止,乒乓球捡拾器在国内外市场上的发展却较为滞后。文中所述的智能捡乒乓球机器人,正是一种应用于兵乓球体育赛事的自主式移动的服务机器人。乒乓球是一种风靡我国且老少皆宜的全民性运动,但对于爱好者来说,在训练完捡球并根据颜色分类既费时又费力,影响体验。智能捡乒乓球机器人可以应用在业余或专业的乒乓球训练基地或训练学校,使用智能捡乒乓球机器人可以减轻训练人员回收乒乓球的负担,能够减少训练时的无效训练时间,提高运动员的训练效率,使运动员可以更好的投入到专业的训练当中,从而取得更好的比赛成绩。智能捡乒乓球机器人利用OpenMV对乒乓球进行定位,接着机器人接收到乒乓球的位置前往捡球,到达位置时,升降台降下捡球筐,利用捡球筐底部弹簧,对乒乓球进行拾取,完成捡球。

实现技术思路

一、系统总体组成

基于 OpenCV 的乒乓球分类捡球机器人主 要由 OpenCV 图像识别系统与控制系统组成,结构如图所 示。OpenCV 是基于树莓派上布署的 Linux 系统。机器人启 动后,树莓派通过摄像头采集环境信息,识别乒乓球的位置 及颜色信息并以串口通信的方式发送给 STM32F4 主控制器 作为控制参量,控制机器人向目标乒乓球做趋近运动。运动 过程中,安装在机器人四周的人体红外传感器与超声波距离 传感器实时监测周围障碍物以及运动方向是否有人存在。如 探测到人或障碍物则结合传感器数据,根据设定算法自动 选择一条最优的无障碍通道。

  二、系统硬件设计捡球装置 捡球装置由两级并联毛刷滚轮直流减速电机减速器、编码器联轴器组成。取装置如图:

 运动控制

运动部分采用四轮驱动式结构包括直流减速电机减速器、编码器联轴器和橡胶轮胎通过驱动器控制直流减速电机实现前进、后退转弯等动作满足捡球所需要的运动方式。

驱动器采用东芝公司生产的一款直流电机驱动器件 TB6612FNG,其使用 MOSFET H 桥结构可同时驱动两电机,支持 PWM 调速方式系统驱动电路与实物如图。

分类装置 分类装置位于两储存仓之间包括 180°舵机转轴、轴承和仓门。当球到达储存仓仓口时控制器根据树莓派传回的球体颜色信息,控制舵机将与球体颜色相反的仓门向外倾斜 45°关闭使球落入对应颜色仓内达到分类目的

 避障系统

避障系统包括超声波距离传感器人体红外传感器传感器分布在底盘周围,将采集到的信息返回控制器经过控制器对数据的计算与判断,控制运动系统实现自主避障功能,达到自我保护目的。传感器分布位置如图:

三、系统软件设计

OpenCV 系统启动后自动运行乒乓球识别程序,将摄像头采集到的数据经过滤波、灰度化圆形检测颜色识别等处理方式,精确识别到乒乓球并将位置及颜色信息以串口通信的方式发送给控制器。

OpenCV 算法识别

个像素点的 RGB 值表示了该像素点的颜色为了提升霍夫圆的识别效率,减轻运算量对彩色图像中的无用的三维色彩信息进行剔除,转换成一维的表示黑色(0)到白色(255之间强度变量这个过程叫做灰度化

在平面直角坐标系中任意圆均可表示为

式中(a, b) 表示圆心的坐标r 表示半径将其映射到 abr 坐标系就是一条三维曲线。而在 xy 坐标系中所有非零点经过映射就构成了 abr 坐标系中许多条三维曲线映射到三维图像上的点被称为投票,如图所示显然在同一圆上对应的三维坐标系所得到的票数最多,即可判定能 (x, y, r) 坐标点就是圆。即可得到圆的圆心和半径

在 OpenCV 库中封装有霍夫圆检测的库函数检测成功后返回圆心坐标和半径信息,调用库函数 

识别成功的乒乓球如图:

 避障算法

机器人以避障功能达到自我保护的目的其核心为避障算法。避障算法以超声波距离传感器所测距离人体红外传感器的导通状态为输入,以控制运动系统为输出控制机器人避过障碍趋近于目标位置。在机器人运动过程中超声波距离传感器始终检测前方距离,当前方距离小于安全距离10 cm 或者人体红外检测到人即可判定前方有障碍物此时机器人停止,检测安装在机器人两侧的距离传感器的值来判定左边和右边障碍物的情况,当左边距离大于右边距离时,说明左边无障碍物向左转弯并继续前行,同时又继续检测前方距离,直到球被收集起来避障流程如图:

系统整体测试 机器人上电后系统启动树莓派通过摄像头采集环境信息,识别到乒乓球后通过串口打印出一帧信息如图:

其中包括乒乓球的位置信息,颜色信息,(RGB)值信息,通过串口发送给 STM32F4 主控机器人达到了预期的收集和分类效果,实际测试效果图如图:

 代码部分

避障代码:

const int TrigPin1 = 22;

const int EchoPin1 = 23;

const int TrigPin2 = 24;

const int EchoPin2 = 25;

const int TrigPin3 = 26;

const int EchoPin3 = 27;

const int TrigPin4 = 28;

const int EchoPin4 = 29;

const int TrigPin5 = 30;

const int EchoPin5 = 31;

const int leftMotor1 = 32;

const int leftMotor2 = 34;

const int RightMotor1 =36;

const int RightMotor2 =38;

int distance_cm1 = 0;

int distance_cm2 = 0;

int distance_cm3 = 0;

int distance_cm4 = 0;

int distance_cm5 = 0;


void setup() {

pinMode(TrigPin1,OUTPUT);

pinMode(EchoPin1,INPUT);

pinMode(TrigPin2,OUTPUT);

pinMode(EchoPin2,INPUT);

pinMode(TrigPin3,OUTPUT);

pinMode(EchoPin3,INPUT);

pinMode(TrigPin4,OUTPUT);

pinMode(EchoPin4,INPUT);

pinMode(TrigPin5,OUTPUT);

pinMode(EchoPin5,INPUT);

pinMode(leftMotor1, OUTPUT);

pinMode(leftMotor2, OUTPUT);

pinMode(RightMotor1, OUTPUT);

pinMode(RightMotor2, OUTPUT);

Serial.begin(9600);

}

void loop() {

digitalWrite(TrigPin1,LOW);

delayMicroseconds(2);

digitalWrite(TrigPin1,HIGH);

delayMicroseconds(10);

digitalWrite(TrigPin1,LOW);

distance_cm1 = pulseIn(EchoPin1,HIGH)/58;

digitalWrite(TrigPin2,LOW);

delayMicroseconds(2);

digitalWrite(TrigPin2,HIGH);

delayMicroseconds(10);

digitalWrite(TrigPin2,LOW);

distance_cm2 = pulseIn(EchoPin2,HIGH)/58;

digitalWrite(TrigPin3,LOW);

delayMicroseconds(2);

digitalWrite(TrigPin3,HIGH);

delayMicroseconds(10);

digitalWrite(TrigPin3,LOW);

distance_cm3 = pulseIn(EchoPin3,HIGH)/58;

digitalWrite(TrigPin4,LOW);

delayMicroseconds(2);

digitalWrite(TrigPin4,HIGH);

delayMicroseconds(10);

digitalWrite(TrigPin4,LOW);

distance_cm4 = pulseIn(EchoPin4,HIGH)/58;

digitalWrite(TrigPin5,LOW);

delayMicroseconds(2);

digitalWrite(TrigPin5,HIGH);

delayMicroseconds(10);

digitalWrite(TrigPin5,LOW);

distance_cm5 = pulseIn(EchoPin5,HIGH)/58;

Serial.print(distance_cm1);

Serial.print("cm");

Serial.print("   ");

Serial.print(distance_cm2);

Serial.print("cm");

Serial.print("   ");

Serial.print(distance_cm3);

Serial.print("cm");

Serial.print("   ");

Serial.print(distance_cm4);

Serial.print("cm");

Serial.println("   ");

Serial.print(distance_cm5);

Serial.print("cm\n");

delay(10);

if( distance_cm3>25)

{

if( distance_cm1<25)

{

right();

delay(250);}

if( distance_cm2<20)

{

right();

delay(200);}

if( distance_cm5<25)

{

left();

delay(250);}

if( distance_cm4<20)

{

left();

delay(200);}

}

if( distance_cm3<25)

{

back();

delay(250);

right();

delay(250);

}

else

{

forward();

delay(50);

}

}

void forward()

{

digitalWrite(leftMotor1,HIGH);

digitalWrite(leftMotor2,LOW);

digitalWrite(RightMotor1,HIGH);

digitalWrite(RightMotor2,LOW);

}

void left()

{

digitalWrite(leftMotor1,HIGH);

digitalWrite(leftMotor2,LOW);

digitalWrite(RightMotor1,LOW);

digitalWrite(RightMotor2,HIGH);

}

void right()

{

digitalWrite(leftMotor1,LOW);

digitalWrite(leftMotor2,HIGH);

digitalWrite(RightMotor1,HIGH);

digitalWrite(RightMotor2,LOW);

}

void stop()

{

digitalWrite(leftMotor1,LOW);

digitalWrite(leftMotor2,LOW);

digitalWrite(RightMotor1,LOW);

digitalWrite(RightMotor2,LOW);

}


void back()

{

digitalWrite(leftMotor1,LOW);

digitalWrite(leftMotor2,HIGH);

digitalWrite(RightMotor1,LOW);

digitalWrite(RightMotor2,HIGH);

}

图像识别代码:

import sensor, image, time

from pyb import UART

yellow_threshold   = (24, 100, 68, -24, 34, 86)

sensor.reset()

sensor.set_pixformat(sensor.RGB565)

sensor.set_framesize(sensor.QQVGA)

sensor.skip_frames(10)

sensor.set_auto_whitebal(False)

clock = time.clock()

uart = UART(3, 115200)

K=1000

while(True):

img = sensor.snapshot()

blobs = img.find_blobs([yellow_threshold])

if len(blobs) == 1:

#if blobs:

b = blobs[0]

img.draw_rectangle(b[0:4])

img.draw_cross(b[5], b[6])

Lm = (b[2]+b[3])/2

length = K/Lm

output_str ="%d" %   (length)

print('you send:',output_str)

uart.write(output_str+'\n')

else:

print('not found!')

实现效果图样例

乒乓球自动捡球机器人:

 我是海浪学长,创作不易,欢迎点赞、关注、收藏、留言。

毕设帮助,疑难解答,欢迎打扰!

最后

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2023年4月5日
下一篇 2023年4月5日

相关推荐