import sensor, image, time,lcd,utime
from machine import UART
from fpioa_manager import fm
fm.register(10, fm.fpioa.UART1_TX, force=True)#映射串口引脚
fm.register(9, fm.fpioa.UART1_RX, force=True)#映射串口引脚
uart = UART(UART.UART1, 115200, 8, 0, 0, timeout=1000, read_buf_len=4096)
clock = time.clock()
lcd.init() #显示屏初始化
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA) #QQVGA: 160x120、QVGA: 320x240、
sensor.run(1)
sensor.skip_frames(20)#跳过刚启动开始的30帧照片
lcd.rotation(2)#LCD屏幕翻转,范围是0~3,上和下反转,左和右反转
sensor.set_hmirror(True)#摄像头镜像
sensor.set_auto_gain(False) # must be turned off for color tracking
#sensor.set_auto_whitebal(False) # must be turned off for color tracking,关闭白平衡
#sensor.set_brightness(3) #-3至+3,亮度越大,图片越亮
#sensor.set_saturation(2)#-3至+3,饱和度越大,色彩越鲜艳
#sensor.set_contrast(2)#-3至+3,对比度越大,颜色之间的反差越大
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
#存放不同的颜色阈值,依次为白色、黄色、绿色(白天光的上流:(82, 100, -3, 8, -3, 2))(晚上:(62, 100, -30, 4, -9, 31))
color = ((82, 100, -3, 8, -3, 2),(50, 96, -28, 18, 48, 90))
size_threshold = 4500 #若检测到的小球框的面积小于size_threshold表明小球距离小车太远,小车需要前进。这个参数的大小需要根据实际情况修改
target=()
flag = 0 #用于标记一个while循环中是否检测到小球,falg==1表示本轮发现了小球
count = 0
bug_open = False # True or False
previous_ball_location = 'r'
location_count=0 #用来防止误识别,保持识别结果的稳定性
def stable_output(location):
global location_count,previous_ball_location
if previous_ball_location != location:
location_count = 1
previous_ball_location = location
else:
location_count = location_count + 1
if location_count >=10:
uart.write(location) #通过串口向外发送数据,控制小车向location方向运动
clock.tick()#开始追踪运行时间。
while(True):
sensor.set_auto_whitebal(False) # must be turned off for color tracking,检测黄球时,关闭白平衡,检测白球时开启白平衡
img = sensor.snapshot().histeq(adaptive=True, clip_limit=3)
img.lens_corr(1.8) #镜头畸变矫正(lens correction),lens_corr 为了去除畸变, 1.8 是默认参数,可以根据自己实际情况调整
#专门检测黄色小球
blobs = img.find_blobs([color[1]])
if blobs:
max_blob = find_max(blobs)
x_error = max_blob[5]-img.width()/2#若x_error<0,则说明小球在左边,小车需要左转,若x_error>0,则说明小球在右边,小车需要右转
h_error = max_blob[2]*max_blob[3]-size_threshold#若h_error<0,则小车距离小球还有距离,需要前进。
img.draw_circle(max_blob.x()+int(max_blob.w()/2), max_blob.y()+int(max_blob.w()/2), int(max_blob.w()/2), color = (255, 255, 0),thickness=5)#识别到的白色圆形用白色的圆框出来
#print("blob.density(): ", max_blob.density(),"blob.w(): ", max_blob.w())
#给黄球标注框框
#for b in blobs:
#img.draw_circle(b.x()+int(b.w()/2), b.y()+int(b.w()/2), int(b.w()/2), color = (255, 255, 0),thickness=5)#识别到的白色圆形用白色的圆框出来
if(x_error<-10 and max_blob.density()>0.7 and 70>max_blob.w()>8):#设为-5是留有一定的误差空间,因为不一定小球非要在正中间才能被收集
#stable_output('l')
uart.write('l')
flag = 1 #标记本轮发现过目标
count = 0 #发现目标,count置为0,从头开始计数
lcd.draw_string(10, 10, "Left", lcd.RED, lcd.YELLOW)
if bug_open == True:
print("黄球,串口发送l,","blob.density(): ", max_blob.density(),"blob.w(): ", max_blob.w())
if(x_error>10 and max_blob.density()>0.7 and 70>max_blob.w()>8):#设为-5是留有一定的误差空间,因为不一定小球非要在正中间才能被收集
#stable_output('r')
uart.write('r')
flag = 1 #标记本轮发现过目标
count = 0 #发现目标,count置为0,从头开始计数
lcd.draw_string(10, 20, "Right", lcd.RED, lcd.WHITE)
if bug_open == True:
print("黄球,串口发送:r,","blob.density(): ", max_blob.density(),"blob.w(): ", max_blob.w())
if(-10<x_error<10 and h_error<0 and max_blob.density()>0.7 and 70>max_blob.w()>8):
#stable_output('h')
uart.write('h')
flag = 1 #标记本轮发现过目标
count = 0 #发现目标,count置为0,从头开始计数
lcd.draw_string(10, 30, "Head", lcd.RED, lcd.GREEN)
if bug_open == True:
print("黄球,串口发送:h,","blob.density(): ", max_blob.density(),"blob.w(): ", max_blob.w())
else:
stable_output('t')
if bug_open == True:
print("无黄,串口发送:t,")
#检测白球时,开启白平衡效果会更好一点
sensor.set_auto_whitebal(True) # must be turned off for color tracking,开启白平衡
img = sensor.snapshot().histeq(adaptive=True, clip_limit=3)
img.lens_corr(1.8) #镜头畸变矫正(lens correction),lens_corr 为了去除畸变, 1.8 是默认参数,可以根据自己实际情况调整
#思想:先识别出圆形,再识别圆的颜色
#img.find_circles:控制从霍夫变换中监测到的圆。
for c in img.find_circles(threshold = 3500, x_margin = 10, y_margin = 10, r_margin = 10,
r_min = 2, r_max = 100, r_step = 2):
#area为识别到的圆的区域,即圆的外接矩形框
area = (c.x()-c.r(), c.y()-c.r(), 2*c.r(), 2*c.r())
##保存检测到的其中一个圆的一些参数,用于控制小车方向的计算
#target = (c.x(), c.y(), c.r())
#像素颜色统计,roi 是感兴趣区域的矩形元组(x,y,w,h)。如果未指定,ROI即整个图像的图像矩形。操作范围仅限于 roi 区域内的像素。
statistics = img.get_statistics(roi=area)
#l_mode(),a_mode(),b_mode()是L通道,A通道,B通道的众数。
if color[0][0]<statistics.l_mode()<color[0][1] and color[0][2]<statistics.a_mode()<color[0][3] and color[0][4]<statistics.b_mode()<color[0][5]:#if the circle is red
img.draw_circle(c.x(), c.y(), c.r(), color = (255, 255, 255),thickness=5)#识别到的白色圆形用白色的圆框出来
#保存检测到的其中一个圆的一些参数,用于控制小车方向的计算
target = (c.x(), c.y(), c.r())
#elif color[1][0]<statistics.l_mode()<color[1][1] and color[1][2]<statistics.a_mode()<color[1][3] and color[1][4]<statistics.b_mode()<color[1][5]:#if the circle is red
#img.draw_circle(c.x(), c.y(), c.r(), color = (255, 255, 0))#识别到的黄色圆形用黄色的圆框出来
##保存检测到的其中一个圆的一些参数,用于控制小车方向的计算
#target = (c.x(), c.y(), c.r())
else:
img.draw_circle(c.x(), c.y(), c.r(), color = (0, 0, 0),thickness=5)#识别到的白色圆形用白色的圆框出来
target = (c.x(), c.y(), c.r())#其实这里应该不加这一句,但为了演示效果更好,让小车也追一下圆形
if target:
flag = 1 #标记本轮发现过目标
#一张图只保留一个小球的信息,只追一个小球
x_error = target[0]-img.width()/2 #若x_error<0,则说明小球在左边,小车需要左转,若x_error>0,则说明小球在右边,小车需要右转
h_error = 2*target[2]*2*target[2]-size_threshold #若h_error<0,则小车距离小球还有距离,需要前进。
if(x_error<-10):#设为-5是留有一定的误差空间,因为不一定小球非要在正中间才能被收集
#stable_output('l')
uart.write('l')
count = 0 #发现目标,count置为0,从头开始计数
if bug_open == True:
print("白球,左转,发串口:l")
lcd.draw_string(10, 10, "Left", lcd.RED, lcd.YELLOW)
if(x_error>10):#设为-5是留有一定的误差空间,因为不一定小球非要在正中间才能被收集
#stable_output('r')
uart.write('r')
count = 0 #发现目标,count置为0,从头开始计数
if bug_open == True:
print("白球,右转,发串口:r")
lcd.draw_string(10, 20, "Right", lcd.RED, lcd.WHITE)
if(10>x_error>-10 and h_error<0):
#stable_output('h')
uart.write('h')
count = 0 #发现目标,count置为0,从头开始计数
if bug_open == True:
print("白球,前进,发串口:h")
lcd.draw_string(10, 30, "Head", lcd.RED, lcd.GREEN)
else:
stable_output('t')
if bug_open == True:
print("无白色球,发串口:t")
target=()#清空target
#控制视野内无球时,自动慢速右转
if flag == 0:
count = count+1
if count%10 == 0:
uart.write('s')
utime.sleep_ms(10)
uart.write('n') #通过串口向外发送数据,没有检测到黄色或白色小球
if bug_open == True:
print("视野无球,发串口:n")
lcd.draw_string(250, 10, "FPS %f" % clock.fps(), lcd.BLACK, lcd.RED)
count = 0
flag = 0 #重置标记
if bug_open == True:
print("FPS %f" % clock.fps())#停止追踪运行时间,并返回当前FPS(每秒帧数)。在调用该函数前始终首先调用 tick
print("flag:",flag,"count:",count)
lcd.display(img) #LCD 显示图片
为什么这个代码别不了黄色的球,如果要修改,应该怎么修改
MaxiPy IDE摄像头识别小球
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
2条回答 默认 最新
关注 引自免费微信小程序:皆我百晓生
从你提供的代码来看,识别黄色小球的部分似乎已经设置得相当合理了,但是你提到代码无法识别黄色小球。这可能由几个原因造成,我们逐一排查并尝试解决:
1. 颜色阈值可能不准确
颜色阈值是识别特定颜色的关键。你已经定义了一个针对黄色的阈值
(50, 96, -28, 18, 48, 90)
。这个阈值可能不适合实际环境中的光线条件。为了调试这个问题,你可以尝试调整这些值,特别是l_min
,l_max
(亮度),a_min
,a_max
(红色成分),以及b_min
,b_max
(蓝色成分)。调整方法:
- 亮度 (
l_min
,l_max
):如果环境较暗,增加l_min
;如果环境较亮,减少l_max
。 - 红色成分 (
a_min
,a_max
) 和 蓝色成分 (b_min
,b_max
):根据实际观察到的黄色在HSV色彩空间中的位置进行微调。
2. 环境光照影响
环境光照的变化会影响颜色识别。确保在不同的光照条件下测试代码,看是否能稳定识别黄色小球。
3. 镜头校正和图像处理
你已经在代码中使用了
lens_corr()
函数进行镜头畸变校正,这是好的做法。但是,如果你的摄像头存在明显的畸变,可能需要进一步优化lens_corr()
的参数。4. 检查
find_blobs()
函数的参数find_blobs()
函数有额外的参数可以调整,比如merge
和margin
。这些参数可以帮助改善检测的准确性。修改建议
尝试修改颜色阈值,观察效果。下面是一个示例,你可以将黄色的阈值调整为
(50, 100, -30, 30, -30, 30)
或者根据你的具体环境调整:color = ((82, 100, -3, 8, -3, 2),(50, 100, -30, 30, -30, 30))
同时,检查
find_blobs()
的其他参数,比如merge=True
可以帮助合并相邻的黄色区域,提高识别率:blobs = img.find_blobs([color[1]], merge=True)
最后一步:调试与验证
- 在不同光照条件下测试。
- 使用
img.draw_rectangle()
在检测到的黄色区域周围画框,直观查看检测效果。 - 如果仍然无法识别,尝试使用彩色打印纸制作的黄色球体进行测试,以排除真实小球表面特性对识别的影响。
希望这些建议能帮助你解决问题。如果有任何疑问,欢迎继续讨论。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报 编辑记录- 亮度 (
悬赏问题
- ¥15 rt-thread线程切换的问题
- ¥20 python忆阻器数字识别
- ¥15 无法输出helloworld
- ¥15 高通uboot 打印ubi init err 22
- ¥20 PDF元数据中的XMP媒体管理属性
- ¥15 R语言中lasso回归报错
- ¥15 网站突然不能访问了,上午还好好的
- ¥15 有没有dl可以帮弄”我去图书馆”秒选道具和积分
- ¥15 semrush,SEO,内嵌网站,api
- ¥15 Stata:为什么reghdfe后的因变量没有被发现识别啊