基于OpenMV视觉的智能捡乒乓球小车:机器人爱好者的创新解决方案
在机器人技术的世界中,自动化与精确度是提升性能和可用性的关键。作为一项令人兴奋的创新项目,基于OpenMV视觉的智能捡乒乓球小车通过计算机视觉和单片机技术,能够自动识别、追踪并收集乒乓球,展示了现代智能机器人应用的无限潜力。
该系统的核心组件是OpenMV摄像头,它是一款高效且价格亲民的单片机视觉传感器,能够精准识别并追踪指定颜色的乒乓球。当小车识别到目标颜色后,它会自动追踪并通过车前方的滚轮进行乒乓球收集。用户可以通过调整LAB阈值,灵活地设置不同颜色的物体识别,满足多种应用需求。
基础版本功能包括:
- OpenMV视觉系统:识别并追踪指定颜色的乒乓球。
- 自动捡球:通过前方滚轮收集乒乓球。
- 可调节颜色识别:通过LAB阈值调整,支持不同颜色物体识别。
在扩展版本中,项目进一步提升了功能性:
- 手机APP蓝牙控制:用户可以通过APP实现对小车的远程控制。
- 图传模块:可实时显示摄像头画面,增强操作体验。
- 避障模块:可加装红外或超声波传感器,避免障碍物。
- 目标地运输功能:收集完成后,小车可手动或自动将乒乓球运输到指定位置。
- 机械臂版本:可定制机械臂版本,实现其他物品(如网球)的拾取功能。
- 云台追踪:可选配云台模块,实现人脸、二维码等物体的实时追踪。
对于定制需求,用户可以选择不同的主控平台(如STM32、Arduino或OpenMV等)进行系统设计和实现,灵活应对不同应,以下是是实现的效果和主要代码。有需物或资料包的可以私聊我哦!
⭐基于OpenMV的滚轮捡乒乓球机器人/基于机器视觉的乒乓球回收机器人
import sensor, time, image,lcd,math,car
from pyb import Servo,UART,Pin,Timer
from pid import PID
sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.RGB565) # use RGB565.
sensor.set_framesize(sensor.QQVGA) # use QQVGA for speed.
sensor.skip_frames(10) # Let new settings take affect.
sensor.set_auto_whitebal(False) # turn this off.
clock = time.clock() # Tracks FPS.
#串口
uart1 = UART(1, 9600) # PA9,PA10 #蓝牙控制串口
# For color tracking to work really well you should ideally be in a very, very,
# very, controlled enviroment where the lighting is constant...
green_threshold = ((24, 38, 2, 47, 4, 24))
size_threshold = 2000
x_pid = PID(p=0.5, i=1, imax=100)
h_pid = PID(p=0.05, i=0.1, imax=50)
count=0 #x选择追踪方式
TRACKING_MODE = 0
BLUETOOTH_MODE = 1
def find_max(blobs):
max_size=0
for blob in blobs:
if blob[2]*blob[3] > max_size:
max_blob=blob
max_size = blob[2]*blob[3]
return max_blob
current_mode = TRACKING_MODE# 初始模式为追踪模式
while(True):
clock.tick() # Track elapsed milliseconds between snapshots().
if uart1.any():
rec=uart1.read(1)
if rec != None:
rec=bytes(rec)
print(rec)
if rec == b't': # 如果收到't'命令,切换到追踪模式
current_mode = TRACKING_MODE
elif rec == b'b': # 如果收到'b'命令,切换到蓝牙控制模式
current_mode = BLUETOOTH_MODE
if current_mode == TRACKING_MODE:
# 获取一帧图像
img = sensor.snapshot()
# 寻找物体
blobs = img.find_blobs([green_threshold])
# 如果找到了目标
if blobs:
max_blob = find_max(blobs)
x_error = max_blob[5]-img.width()/2
h_error = max_blob[2]*max_blob[3]-size_threshold
print("x error: ", x_error)
img.draw_rectangle(max_blob[0:4]) # rect
img.draw_cross(max_blob[5], max_blob[6]) # cx, cy
x_output=x_pid.get_pid(x_error,1)
h_output=h_pid.get_pid(h_error,1)
print("h_output",h_output)
car.run(-h_output-x_output,-h_output+x_output)
else:
car.run(0,0)
elif current_mode == BLUETOOTH_MODE:
if uart1.any():
rec=uart1.read(1)
if rec != None:
rec=bytes(rec)
print(rec)
if rec==b'0': #停车
print(000)
car.run(0,0)
elif rec==b'1': #前进
print(111111111111)
car.run(80,80)
elif rec==b'2': #后退
print(rec)
car.run(-80,-80)
elif rec==b'3': #左转
print(rec)
car.run(80,-80)
elif rec==b'4': #右转
print(rec)
car.run(80,80)