我接触的第一个硬件项目是设计一个简陋的智能视觉小车,我在项目里的任务是识别一张纸上六个目标点坐标然后发送给小车。
图一 场地样式
就是将上图六个点的坐标识别然后传输给小车。
识别效果大概是这样:
图二 识别效果
因为是第一次做这样的项目,第一次使用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个像素值才能准确的显示坐标,不同设备可能不一样。
后面包括去重复数据和显示屏显示注释比较全,不一一说明这里直接上完整代码。文章来源:https://www.toymoban.com/news/detail-575306.html
完整代码:文章来源地址https://www.toymoban.com/news/detail-575306.html
import sensor,image,lcd,time
green1_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_blob
i=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<i: #防重复
if (t1[i-1]==t1[j-1] and t2[i-1]==t2[j-1]):
n=i+1
j=j+1
if (n==0 and (abs(t1[i-1])<9)):#这里是对点进行输出,重复点不输出
print(t)
m=m+1#计数,记录输出几个点
img.draw_string(x,y, "x")#标注文本x、y
img.draw_string(x+10, y, str(t))#标注坐标
img.draw_string(x,y+20, "green")#标注文本green如果是其他颜色请更改
lcd.display(img)#lcd屏幕显示
到了这里,关于K210摄像头矩形图坐标识别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!