php网站开发教学,app外包公司哪家好,网站重构,黑色炫酷灯饰照明科技企业商务网站模板我们花费了四天时间打了一场21年的电赛改编题——智能送药小车。虽然结果不尽人意#xff0c;但这是我学习32以来第一次正式的打比赛#xff0c;对我来说要学习的东西#xff0c;所增长的经验真的特别多#xff08;虽然基本上都是学长在出力~#xff09;下来我就把关于这次… 我们花费了四天时间打了一场21年的电赛改编题——智能送药小车。虽然结果不尽人意但这是我学习32以来第一次正式的打比赛对我来说要学习的东西所增长的经验真的特别多虽然基本上都是学长在出力~下来我就把关于这次比赛的感悟和大家分享一下。
一、OpenMV寻迹 我们使用OpenMV进行寻迹。思路就是先对图像进行二值化处理只让OpenMV识别出红线然后通过线性回归方法检测出直线。通过计算出直线的平移偏移量和旋转偏移量然后带入pid算法中来控制小车进行巡线。
#pid巡线前进
def lookfor_line():# 使用PID算法计算控制信号rho_output rho_pid.get_pid(直线平移偏移量, 1)theta_output theta_pid.get_pid(直线旋转偏移量, 1)output rho_output theta_output#print(kkkkkkkkkkkkkk, end)#print(output)# 根据PID输出调整小车的速度output output * 2car.run(80 output, 80 - output)# 计算直线的平移偏移量直线中点到图像中心的距离
直线平移偏移量 abs(line.rho()) - img.width() / 2
# 计算直线的旋转偏移量直线与垂直方向的夹角
if line.theta() 90:直线旋转偏移量 line.theta() - 180
else:直线旋转偏移量 line.theta()
# 如果直线的强度长度足够大则认为是有效直线需要控制小车
if stats.mean() 3:lookfor_line()
二、OpenMV检测路口 识别数字的摄像头无非就发送三种数据要么目标药房在左要么目标药房在右要么没识别到直接前进。下面的摄像头只负责检测到路口然后执行上面摄像头发下来的操作即可不必区分十字路口还是T字路口。 我们检测路口的思路也很简单只要判断红色区域二值化之后是白色区域的面积突然增大即可。我们的摄像头在一般巡线的时候红色区域的面积在15左右当有路口出现的时候面积会到23左右。
stats img.get_statistics()
#遇到了路口
if stats.mean()18:#执行相关逻辑代码
三、OpenMV数字识别 我们使用的是OpenMV的多模板匹配。效果还行。 模版的采集
· 就是先将车搭好然后让车开到指定地点就最好是后面的T字路口处让T字路口的那四张照片全部落在OpenMV的正中央将这些数字的几种形态全部拍摄成模版。可以将数字分为两大类。1~2,3~8。因为1~2是固定路线所以只要拍摄正脸照用来发车前识别就行。3~8可以分为左边最左边右边最右边和正面五中情况。所以我们一共拍摄了32张模板然后将模板转化为pgm格式像素大小为35*35。因为不能超过openmv的像素大小。35*35的像素我们感觉识别速度和准确率都还行官方给的建议是不超过60*80。 我们是用电脑截图然后改像素转格式。截图时用的代码
import sensor,time,image#重置传感器
sensor.reset()sensor.set_contrast(1)#设置对比度
sensor.set_gainceiling(16)#设置增益上限
sensor.set_framesize(sensor.QQVGA)#设置图像分辨率为 QQVGA
sensor.set_pixformat(sensor.GRAYSCALE)#设置图像格式为灰度
#sensor.set_windowing(0, 40, 160, 40)#设置窗口大小,后面ROI设置也会以这个为新的基准
# 拍摄图像并保存
while (1):img sensor.snapshot()time.sleep_ms(10)
多模板匹配 多模版匹配其实就是用多个模版调用模板匹配函数 find_template 来进行模板匹配。如果进行多模板匹配时检测不到模板可以适当降低感兴趣区域面积 roi 使用EX识别减少 threshold 的值等。如果错误率太高可以增加 threshold 的值增加模板等。 import time, image,sensor,math,pyb
#引入两种匹配算法
from image import SEARCH_EX, SEARCH_DS
from pyb import Pin, Timer,LED
uart pyb.UART(3, 115200, timeout_char 1000) #定义串口3变量
#重置传感器
sensor.reset()sensor.set_contrast(1)#设置对比度
sensor.set_gainceiling(16)#设置增益上限
sensor.set_framesize(sensor.QQVGA)#设置图像分辨率为 QQVGA
sensor.set_pixformat(sensor.GRAYSCALE)#设置图像格式为灰度
#sensor.set_windowing(0, 0, 160, 160)#设置窗口大小,后面ROI设置也会以这个为新的基准#加载模板图片
template01 image.Image(/1.pgm)
template02 image.Image(/2.pgm)
template03 image.Image(/3.pgm)
template04 image.Image(/4fly.pgm)
template05 image.Image(/5.pgm)
template06 image.Image(/6.pgm)
template07 image.Image(/7.pgm)
template08 image.Image(/8fly.pgm)template3L image.Image(/3L.pgm)
template3LL image.Image(/3LL.pgm)
template3R image.Image(/3R.pgm)
template3RR image.Image(/3RR.pgm)template4L image.Image(/4L.pgm)
template4LL image.Image(/4LL.pgm)
template4R image.Image(/4R.pgm)
template4RR image.Image(/4RR.pgm)template5L image.Image(/5L.pgm)
template5LL image.Image(/5LL.pgm)
template5R image.Image(/5R.pgm)
template5RR image.Image(/5RR.pgm)template6L image.Image(/6L.pgm)
template6LL image.Image(/6LL.pgm)
template6R image.Image(/6R.pgm)
template6RR image.Image(/6RR.pgm)template7L image.Image(/7L.pgm)
template7LL image.Image(/7LL.pgm)
template7R image.Image(/7R.pgm)
template7RR image.Image(/7RR.pgm)template8L image.Image(/8L.pgm)
template8LL image.Image(/8LL.pgm)
template8R image.Image(/8R.pgm)
template8RR image.Image(/8RR.pgm)# 1.轮询1~8直至识别到。 2.根据f103给的值单纯识别那个数
Find_Task 1#第几次匹配
目标药房 0#需要到达的药房
find_flag 0 #只声明未使用#第一次模版匹配
##### FindTask 1 时使用
#开始位置匹配
def FirstFindTemplate(template):kuang (50,38,70,53)R img.find_template(template, 0.6, step1,roikuang, searchSEARCH_EX) #只检测中间的img.draw_rectangle(kuang, color(255,255,255))return R
#匹配具体值
def FirstFindedNum(R, Finded_Num): #第一个参数是模板匹配的对象第二个是它所代表的数字global Find_Taskglobal find_flagglobal 目标药房img.draw_rectangle(R, color(225, 0, 0))#本来中值是80的但返回值是框边缘所以减去15就好 小于65是在左边大于65是在右边#LoR 0find_flag 1Num Finded_Numprint(目标病房号, Num)目标药房 Num#识别到目标药房执行任务2Find_Task2if Num 1:uart.write(1)uart.write(start)print(start)#第二次模版匹配
##### FindTask 2 时使用
#模板匹配
def FindTemplate(template):kuang (0, 30, 160, 50)R img.find_template(template, 0.8, step1, roikuang, searchSEARCH_EX)img.draw_rectangle(kuang, color(255, 255, 255))return Rdef FindedNum(R, Finded_Num):#第一个参数是模板匹配的对象第二个是它所代表的数字global Find_Taskglobal find_flagLoR 0img.draw_rectangle(R, color(225, 0, 0))#本来中值是80的但返回值是框边缘所以减去15就好 小于65是在左边大于65是在右边if R[0] 65:LoR 2 #2是右elif 0 R[0] 65:LoR 1 #1是左find_flag 1Num Finded_Numprint(识别到的数字是, Num, 此数字所在方位, LoR) #打印模板名字if LoR 1:uart.write(a)print(a)elif LoR 2:uart.write(b)print(b)#主循环
clock time.clock()
# Run template matching
time.sleep(1)
while (True):clock.tick()img sensor.snapshot()#开始位置识别数字if Find_Task 1:print(正在识别病房号)#进行模板匹配成功返回模版所在一个元组否则返回Noner01 FirstFindTemplate(template01)r02 FirstFindTemplate(template02)r03 FirstFindTemplate(template03)r04 FirstFindTemplate(template04)r05 FirstFindTemplate(template05)r06 FirstFindTemplate(template06)r07 FirstFindTemplate(template07)r08 FirstFindTemplate(template08)#判断哪个模板匹配成功if r01:FirstFindedNum(r01,1)elif r02:FirstFindedNum(r02,2)elif r03:FirstFindedNum(r03,3)elif r04:FirstFindedNum(r04,4)elif r05:FirstFindedNum(r05,5)elif r06:FirstFindedNum(r06,6)elif r07:FirstFindedNum(r07,7)elif r08:FirstFindedNum(r08,8)#else:#print(没检测到目标病房)#路中识别数字elif Find_Task 2:print(正在识别地标号)#break##退出用来调试#判断需要数字3~8中断哪一个if 目标药房 3:#进行模板匹配 //这里每个数字至少给3个模板 但给五六个其实也行r3 FindTemplate(template03)r3L FindTemplate(template3L)r3LL FindTemplate(template3LL)r3R FindTemplate(template3R)r3RR FindTemplate(template3RR)#判断哪个模板匹配成功if r3L:FindedNum(r3L, 3)elif r3LL:FindedNum(r3LL, 3)elif r3R:FindedNum(r3R, 3)elif r3RR:FindedNum(r3RR, 3)elif r3:FindedNum(r3, 3)elif 目标药房 4:#进行模板匹配 //这里每个数字至少给3个模板 但给五六个其实也行#r4 FindTemplate(template04)r4L FindTemplate(template4L)r4LL FindTemplate(template4LL)r4R FindTemplate(template4R)r4RR FindTemplate(template4RR)#判断哪个模板匹配成功并将成功匹配的相应数据发送给主控if r4L:FindedNum(r4L, 4)elif r4LL:FindedNum(r4LL, 4)elif r4R:FindedNum(r4R, 4)elif r4RR:FindedNum(r4RR, 4)#elif r4:#FindedNum(r4, 4)elif 目标药房 5:#进行模板匹配 //这里每个数字至少给3个模板 但给五六个其实也行r5 FindTemplate(template05)r5L FindTemplate(template5L)r5LL FindTemplate(template5LL)r5R FindTemplate(template5R)r5RR FindTemplate(template5RR)#判断哪个模板匹配成功并将成功匹配的相应数据发送给主控if r5L:FindedNum(r5L, 5)elif r5LL:FindedNum(r5LL, 5)elif r5R:FindedNum(r5R, 5)elif r5RR:FindedNum(r5RR, 5)elif r5:FindedNum(r5, 5)elif 目标药房 6:#进行模板匹配 //这里每个数字至少给3个模板 但给五六个其实也行r6 FindTemplate(template06)r6L FindTemplate(template6L)r6LL FindTemplate(template6LL)r6R FindTemplate(template6R)r6RR FindTemplate(template6RR)#判断哪个模板匹配成功并将成功匹配的相应数据发送给主控if r6L:FindedNum(r6L, 6)elif r6LL:FindedNum(r6LL, 6)elif r6R:FindedNum(r6R, 6)elif r6RR:FindedNum(r6RR, 6)elif r6:FindedNum(r6, 6)elif 目标药房 7:#进行模板匹配 //这里每个数字至少给3个模板 但给五六个其实也行r7 FindTemplate(template07)r7L FindTemplate(template7L)r7LL FindTemplate(template7LL)r7R FindTemplate(template7R)r7RR FindTemplate(template7RR)#判断哪个模板匹配成功并将成功匹配的相应数据发送给主控if r7L:FindedNum(r7L, 7)elif r7LL:FindedNum(r7LL, 7)elif r7R:FindedNum(r7R, 7)elif r7RR:FindedNum(r7RR, 7)elif r7:FindedNum(r7, 7)elif 目标药房 8:#进行模板匹配 //这里每个数字至少给3个模板 但给五六个其实也行#r8 FindTemplate(template08)r8L FindTemplate(template8L)r8LL FindTemplate(template8LL)r8R FindTemplate(template8R)r8RR FindTemplate(template8RR)#判断哪个模板匹配成功并将成功匹配的相应数据发送给主控if r8L:FindedNum(r8L, 8)elif r8LL:FindedNum(r8LL, 8)elif r8R:FindedNum(r8R, 8)elif r8RR:FindedNum(r8RR, 8)#elif r8:#FindedNum(r8, 8)#else: time.sleep_ms(100)else: time.sleep_ms(100)print(clock.fps(),Find_Task, 目标药房)我会将模板和完整代码放到我的资源中如果大家需要的话可以自行下载。
四、有点小疑问 最后我们发现我们的小车连着电脑跑的时候数字识别的准确率很高而且小车跑的也很稳。但如果脱机跑的时候就有很大情况会识别不到数字而且小车也经常会在转弯时遇到问题。我们使用的是充电宝想着应该和供电关系不大吧~~~求解答 最后的最后请驻足欣赏一下我们的可怜的直流电机战车