K210摄像头矩形图坐标识别
我接触的第一个硬件项目是设计一个简陋的智能视觉小车,我在项目里的任务是识别一张纸上六个目标点坐标然后发送给小车。
图一 场地样式
就是将上图六个点的坐标识别然后传输给小车。
识别效果大概是这样:
图二 识别效果
因为是第一次做这样的项目,第一次使用maixpy不熟练之处还望大佬见谅,项目完成符合预期。
K210摄像头使用专门的maixpyIDE进行编辑。 它是用python语言进行编写但感觉缩进要求更加严格,不是四格缩进就会运行错误。
首先是导入:
import sensor,image,lcd,time
导入没有什么说法,设备、图像、显示屏、时间,没有其他特别的导入。
然后是初始化,因为之前没接触过硬件项目,初始化是直接拿的常用初始化:
lcd.init()sensor.reset()sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.QVGA)sensor.set_vflip(1) #后置拍摄模式sensor.skip_frames(10) # Let new settings take affect.sensor.set_auto_whitebal(False) # 白平衡关闭sensor.snapshot(1.8)#去鱼眼化
然后是一个找最大色块的函数:
def find_max(blobs): #找最大色块函数。这里是比较像素面积的方式,只返回最大面积色块 max_size=0 for blob in blobs: if blob[4] > max_size: max_blob=blob max_size = blob[4] return max_blob
因为坐标函数只是标注像素位置,所以我们要根据整个场地标注相对位置,这里是找黑线的方式找到整个场地,因为场地黑线过多所以要标注最大的黑色色块,就需要写一个只输出最大色块的函数。这里是通过比较所含像素点个数找到最大色块。blob[4]是像素个数。
要准确识别颜色就要准确的找到颜色阈值,可以通过工具——机器视觉——阈值编辑器找到颜色阈值。
图三 阈值获取
导入图片文件调节阈值,当只有想要的颜色程白色时复制阈值,这个阈值摄像头识别的可能跟真实值有差距,调试的时候要在一定范围内稍微更改使摄像头识别更准确。
图三 阈值编辑器
该项目阈值为:
green1_threshold = (0, 55, -128, -18, 127, -18)black_threshold =(0, 46, -128, 15, -2, 44)
然后使用find-blobs进行颜色识别:
blobs = img.find_blobs([black_threshold])#黑色边框定义识别 blobs1 = img.find_blobs([green1_threshold])#绿色目标点定义
之后是识别黑色边框然后进行计算,算出一个单位长度的像素长度。
if blobs: #寻找黑色边框 max_blob = find_max(blobs) x1=max_blob[0] y1=max_blob[1] w1=max_blob[2] h1=max_blob[3] a1=(int((w1/2)+x1)-max_blob[0])/4 a2=(int((h1/2)+y1)-max_blob[1])/4#计算单位坐标像素长度 if a1==0: a1=1 if a2==0: a2=1 #a1、a2之后要做分母,摄像镜头一开始找目标可能会出现0这里去零 img.draw_rectangle(max_blob[0:4], color=(0,0,0))#对找到的目标进行黑框标注 img.draw_cross(int((w1/2)+x1), int((h1/2)+y1))#使用十字标注目标中心点位置 img.draw_string(max_blob[0],max_blob[1], (str(max_blob[0])+','+str(max_blob[1])), color = (0,0,0))#在显示屏标注目标最左和最下的坐标
这里的计算单位长度是按照该项目8*8的场地计算的,如果要计算其他规格的场地,上面代码写的复杂了,大致是黑框长度max-blob除以场地x格数,这里是除以八。
然后是寻找绿色目标,并计算目标坐标。
if (blobs and blobs1):#寻找绿色目标点 for b in blobs1: i=i+1 x = b[0] y = b[1] width = b[2] height = b[3] if (x>=x1 and x<=x1+w1 and y>=y1 and y<=h1): c1=int(((b[5]-x1)+10)/a1) c2=int(((b[6]-y1)+10)/a2)#计算目标点坐标这里加10是摄像头有误差,我的加10最准确 img.draw_rectangle([x,y,width,height])#用矩形标记出目标颜色区域 t1[i-1]=8-abs(c1) t2[i-1]=8-abs(c2)#因为显示屏上图像是反转的,所以这里要用8减去。这里要看初始化跟不跟我的一样 t=[t1[i-1],t2[i-1]]#形成数组,这就是目标点的坐标 img.draw_cross(b[5], b[6]) #用十字标注目标中心点
要注意的是计算坐标时要不断调试,加减像素值防止较大误差,这里就在坐标上加了10个像素值才能准确的显示坐标,不同设备可能不一样。
后面包括去重复数据和显示屏显示注释比较全,不一一说明这里直接上完整代码。
完整代码:
import sensor,image,lcd,timegreen1_threshold = (0, 55, -128, -18, 127, -18)black_threshold =(0, 46, -128, 15, -2, 44)#常用初始化lcd.init()sensor.reset()sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.QVGA)sensor.set_vflip(1) #后置拍摄模式sensor.skip_frames(10) # Let new settings take affect.sensor.set_auto_whitebal(False) # 白平衡关闭sensor.snapshot(1.8)#去鱼眼化def find_max(blobs): #找最大色块函数。这里是比较像素面积的方式,只返回最大面积色块 max_size=0 for blob in blobs: if blob[4] > max_size: max_blob=blob max_size = blob[4] return max_blobi=0#循环计数m=0#去除重复计数t1=[0 for n in range(10000)]t2=[0 for n in range(10000)] #将t1和t2进行数组化,便于之后去重复数据while True: img=sensor.snapshot() img = sensor.snapshot().lens_corr(strength = 1.2, zoom = 1.0) #调整显示屏使其更“平整”便于识别,里面参数可更改 blobs = img.find_blobs([black_threshold])#黑色边框定义识别 blobs1 = img.find_blobs([green1_threshold])#绿色目标点定义 if blobs: #寻找黑色边框 max_blob = find_max(blobs) x1=max_blob[0] y1=max_blob[1] w1=max_blob[2] h1=max_blob[3] a1=(int((w1/2)+x1)-max_blob[0])/4 a2=(int((h1/2)+y1)-max_blob[1])/4#计算单位坐标像素长度 if a1==0: a1=1 if a2==0: a2=1 #a1、a2之后要做分母,摄像镜头一开始找目标可能会出现0这里去零 img.draw_rectangle(max_blob[0:4], color=(0,0,0))#对找到的目标进行黑框标注 img.draw_cross(int((w1/2)+x1), int((h1/2)+y1))#使用十字标注目标中心点位置 img.draw_string(max_blob[0],max_blob[1], (str(max_blob[0])+','+str(max_blob[1])), color = (0,0,0)) #在显示屏标注目标最左和最下的坐标 if (max_blob[1]==0):#因为周围环境黑色较多,这里设置当黑色边框顶格时卡顿一下,调整摄像头恢复 continue if (blobs and blobs1):#寻找绿色目标点 for b in blobs1: i=i+1 x = b[0] y = b[1] width = b[2] height = b[3] if (x>=x1 and x<=x1+w1 and y>=y1 and y<=h1): c1=int(((b[5]-x1)+10)/a1) c2=int(((b[6]-y1)+10)/a2)#计算目标点坐标这里加10是摄像头有误差,我的加10最准确 img.draw_rectangle([x,y,width,height])#用矩形标记出目标颜色区域 t1[i-1]=8-abs(c1) t2[i-1]=8-abs(c2)#因为显示屏上图像是反转的,所以这里要用8减去。这里要看初始化跟不跟我的一样 t=[t1[i-1],t2[i-1]]#形成数组,这就是目标点的坐标 img.draw_cross(b[5], b[6]) #用十字标注目标中心点n=0 j=0 while j
来源地址:https://blog.csdn.net/qq_54034196/article/details/128509164
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341