正好回家带了一篇H7的板子,想着先把openmv部分配置完再来整h7的开发,这个板子支持openmv的刷写,固件刷写提供内部flash和外部flah的方式,挺方便的。
板子如下,是weact家的,淘宝搜weact就能找到:
资料下载:
https://gitee.com/WeAct-TC
步骤如下:
参考文档:
https://book.openmv.cc/
https://docs.singtown.com/micropython/zh/latest/openmvcam/index.html
使用摄像头获取图像并使用time获取帧率
import sensor,image,time sensor.reset() # 复位摄像头 sensor.set_pixformat(sensor.RGB565) # 设置颜色格式为RGB565 sensor.set_framesize(sensor.QVGA) # 设置图像大小 sensor.skip_frames(time = 2000) # 开头跳一些帧 # sensor.skip_frames(10) # 直接指定跳过的帧数 clock = time.clock() # 主要是用来记录帧率 while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 print(clock.fps())
效果如下:
上面的函数总结
图像格式:
图像大小:(每次是向下除2)
白平衡和自动增益
注意这两个都是为了使得图像更加真实,就是通过一些手段增强图像,其实没有改变了原始图像,结果是增强了视觉效果,就是给图像上增加了一些参数
sensor.set_auto_gain(True) # 自动增益 sensor.set_auto_whitebal(True) # 白平衡 sensor.set_auto_exposure(True) # 自动曝光
截取一段区域
import sensor,image,time sensor.reset() # 复位摄像头 sensor.set_pixformat(sensor.RGB565) # 设置颜色格式为RGB565 sensor.set_framesize(sensor.VGA) sensor.set_windowing((320, 240)) #取中间的320*240区域 sensor.skip_frames(time = 2000) # 开头跳一些帧 clock = time.clock() # 主要是用来记录帧率 while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 print(clock.fps())
镜头翻转
import sensor,image,time sensor.reset() # 复位摄像头 sensor.set_pixformat(sensor.RGB565) # 设置颜色格式为RGB565 sensor.set_framesize(sensor.QVGA) sensor.set_hmirror(True) # 水平翻转 sensor.set_vflip(True) # 垂直翻转 sensor.skip_frames(time = 2000) # 开头跳一些帧 clock = time.clock() # 主要是用来记录帧率 while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 print(clock.fps())
这里是针对摄像头的翻转,特别是对于有些摄像头结构设计不合理的地方而言,特别重要!!!!
获取某个点的像素值并修改某个点的像素值
import sensor,image,time sensor.reset() # 复位摄像头 sensor.set_pixformat(sensor.RGB565) # 设置颜色格式为RGB565 sensor.set_framesize(sensor.QVGA) sensor.set_hmirror(True) # 水平翻转 sensor.set_vflip(True) # 垂直翻转 sensor.skip_frames(time = 2000) # 开头跳一些帧 clock = time.clock() # 主要是用来记录帧率 img = sensor.snapshot() print(img.get_pixel(10,10)) # 获取该点像素值 img.set_pixel(10,10,(255,0,0)) # 修改 print(img.get_pixel(10,10) # 再次打印,像素值改变
获取区域像素值
ROI = (10,10,20,20) while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 print(img.get_statistics(roi=ROI)) # 打印区域平均颜色值 print(clock.fps())
可以看出这个获取的区域像素值包含了很多东西,相比某个点的丰富了很多
返回的主要是灰度的一些值,然后还有lab的一些值,这里重点关注LAB的值,因为LAB在颜色追踪等方面有很大优势,关于颜色空间的介绍可以参见我的另一篇文章:opecv答题树记录
获取ROI区域的LAB值
#设置ROI区域大小 ROI = (10,10,20,20) while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 # 获取三个区域的lab值(众数) color_l= img.get_statistics(roi=ROI) .l_mode() color_a= img.get_statistics(roi=ROI) .a_mode() color_b= img.get_statistics(roi=ROI) .b_mode() print(color_l,color_a,color_b) img.draw_rectangle(ROI) #print(clock.fps())
上面已经接触到了绘图函数,绘图函数其实在可视化中有很重要的作用,一般来说,代码的结果需要推敲下才能理清,使用绘图函数可以很好的可视化出来结果。
下面开始使用常见的绘图函数
while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 img.draw_line((100, 100, 200, 200), color=(255,0,0),thickness=3) img.draw_rectangle((200, 30, 41, 51), color=(255,0,0),fill = True) img.draw_circle(50, 200, 30,color=(0,255,0)) img.draw_cross(90,60,size=10,color=(0,0,255)) img.draw_arrow((80,100,120,50)) #img.draw_string(10,10, "hello world!",scale = 2,color=(0,0,255)) img.draw_string(10,10, "fps"+str(clock.fps()),mono_space = False,scale = 2,color=(0,0,255)) print(clock.fps())
更多的绘图函数及用法可以参考:image — 机器视觉 — MicroPython 1.9.2 文档 (singtown.com)
里面讲的非常详细,需要了解更多建议多多参考,主要是里面的一些缺省参数,很重要,可以实现很多想要的效果,特别注意:
寻找色块,openmv提供了find—blob函数来寻找色块,这个原理是基于阈值的原理实现的,就是对符合阈值区域的搜寻,找到色块
# 寻找色块阈值区域 red = (32, 43, 43, 55, 36, 51) yellow = (45, 68, -14, -1, 42, 56) blue = (18, 39, 2, 32, -58, -32) green = (18, 39, -40, -20, 8, 21) while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 blobs = img.find_blobs([red,yellow,blue,green],area_threshold = 80) # 添加了一个面积过滤,小于面积的值被过滤掉 for blob in blobs: img.draw_rectangle(blob.rect()) print(clock.fps())
下面开始对找到的色块进行标注:
# 寻找色块阈值区域 red = (32, 43, 43, 55, 36, 51) yellow = (45, 68, -14, -1, 42, 56) blue = (18, 39, 2, 32, -58, -32) green = (18, 39, -40, -20, 8, 21) while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 blobs = img.find_blobs([red,yellow,blue,green],area_threshold = 80) for blob in blobs: #print(blob.code()) #print(blob.x,blob.y) if blob.code() == 1: img.draw_string(blob.x(),blob.y(), 'red',mono_space = False,scale = 2,color=(0,0,255)) elif blob.code() == 2: img.draw_string(blob.x(),blob.y(), 'yellow',mono_space = False,scale = 2,color=(0,0,255)) elif blob.code() == 3: img.draw_string(blob.x(),blob.y(), 'blue',mono_space = False,scale = 2,color=(255,0,0)) else: img.draw_string(blob.x(),blob.y(), 'green',mono_space = False,scale = 2,color=(0,0,255)) img.draw_rectangle(blob.rect()) print(clock.fps())
就是使用遍历的方法,使用预先准备好的标识进行匹配然后使用绘图函数进行标识:
还有一些其他比较常用的比如面积,中心坐标什么的,也都还行,详情见参考文档使用
AprilTag码
下面开始AprilTag部分的追踪,这里不做介绍,直接使用
寻找AprilTag和寻找小球有点像,也是有专门的函数来寻找
import sensor,image,time sensor.reset() # 复位摄像头 sensor.set_pixformat(sensor.RGB565) # 设置颜色格式为RGB565 sensor.set_framesize(sensor.QQVGA) sensor.set_auto_gain(False) sensor.set_auto_whitebal(False) sensor.skip_frames(time = 2000) # 开头跳一些帧 clock = time.clock() # 主要是用来记录帧率 while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 # 寻找标志 for tag in img.find_apriltags(): img.draw_rectangle(tag.rect(),color = (0,0,255)) img.draw_cross(tag.cx(),tag.cy(),color = (0,0,255)) degress = 180 * tag.rotation() / math.pi # 旋转角度 print(tag.id(),degrees()) #print(clock.fps())
可以看出这里除了识别出id之外,还可以识别出旋转角度其中角度是弧度值,使用数学函数进行了转换
二维码
获取图像后使用下面的代码:
img = sensor.snapshot() for code in img.find_qrcodes(): print(code)
这里使用的是一种叫ncc模版匹配的方法,官方描述如下:
这里总结下我用的时候的感受:
框选获取模版,默认保存是bmp的无损格式
转换网站
from image import SEARCH_EX, SEARCH_DS
import sensor,image,time from image import SEARCH_EX, SEARCH_DS sensor.reset() # 复位摄像头 sensor.set_pixformat(sensor.GRAYSCALE) # 设置颜色格式为灰度 sensor.set_framesize(sensor.QQVGA) #sensor.set_auto_gain(False) #sensor.set_auto_whitebal(False) sensor.skip_frames(time = 2000) # 开头跳一些帧 template = image.Image("/1.pgm") clock = time.clock() # 主要是用来记录帧率 while(True): img = sensor.snapshot() r = img.find_template(template, 0.70, step=4, search=SEARCH_EX) if r: img.draw_rectangle(r)
效果如下:
对多个模版进行匹配,先实地选取多个模版:
对模版进行检索
import sensor,image,time from image import SEARCH_EX, SEARCH_DS sensor.reset() # 复位摄像头 sensor.set_pixformat(sensor.GRAYSCALE) # 设置颜色格式为RGB565 sensor.set_framesize(sensor.QQVGA) #sensor.set_auto_gain(False) #sensor.set_auto_whitebal(False) sensor.skip_frames(time = 2000) # 开头跳一些帧 templates = ["00.pgm","01.pgm","02.pgm","03.pgm"] clock = time.clock() # 主要是用来记录帧率 while(True): img = sensor.snapshot() for t in templates: template = image.Image(t) r = img.find_template(template, 0.70, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60)) if r: img.draw_rectangle(r) print(t)
经过我实测,效果不是很好
这个其实挺简单的,基本都知道近大远小的原理,那么大小就是区域面积了,所有根据区域面积就可以比较出物体的距离,当然这个误差很大,只能作为一个感性的认识,结果会受很多因素影响
import sensor,image,time sensor.reset() # 复位摄像头 sensor.set_pixformat(sensor.RGB565) # 设置颜色格式为RGB565 sensor.set_framesize(sensor.QVGA) #sensor.set_auto_gain(False) #sensor.set_auto_whitebal(False) sensor.skip_frames(time = 2000) # 开头跳一些帧 clock = time.clock() # 主要是用来记录帧率 #red = (32, 43, 43, 55, 36, 51) #yellow = (45, 68, -14, -1, 42, 56) blue = (18, 39, 2, 32, -58, -32) #green = (18, 39, -40, -20, 8, 21) while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 blobs = img.find_blobs([blue],area_threshold = 80) # 添加了一个面积过滤,小于面积的值被过滤掉 for blob in blobs: img.draw_rectangle(blob.rect()) print(blob.area())
可以看出打印像素值如下,这个就是最基本的比例系数了
import sensor,image,time sensor.reset() # 复位摄像头 sensor.set_pixformat(sensor.RGB565) # 设置颜色格式为RGB565 sensor.set_framesize(sensor.QVGA) #sensor.set_auto_gain(False) #sensor.set_auto_whitebal(False) sensor.skip_frames(time = 2000) # 开头跳一些帧 clock = time.clock() # 主要是用来记录帧率 #red = (32, 43, 43, 55, 36, 51) #yellow = (45, 68, -14, -1, 42, 56) blue = (18, 39, 2, 32, -58, -32) #green = (18, 39, -40, -20, 8, 21) k = 600 while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 blobs = img.find_blobs([blue],area_threshold = 80) # 添加了一个面积过滤,小于面积的值被过滤掉 if len(blobs) == 1: # 只有一个框的时候进行过寻找 b = blobs[0] # 就是获取这个框 img.draw_rectangle(b[0:4]) # 画矩形 img.draw_cross(b[5],b[6]) # 画十字中心 lm = (b[2]+b[3])/2 # 面积=宽*高 length = k/lm # 使用比例,因为最开始是10厘米,整数的原因 img.draw_string(0, 0,"length :%.2f"%(length),mono_space = False,scale = 2)
运行结果如下:
这里主要是颜色和色块组合使用,使用就是先找到圆的区域然后在圆的区域里面寻找颜色阈值符合要求的
其中的寻找圆的函数参数如下:
代码如下:
import sensor,image,time sensor.reset() # 复位摄像头 sensor.set_pixformat(sensor.RGB565) # 设置颜色格式为RGB565 sensor.set_framesize(sensor.QQVGA) #sensor.set_auto_gain(False) #sensor.set_auto_whitebal(False) sensor.skip_frames(time = 2000) # 开头跳一些帧 clock = time.clock() # 主要是用来记录帧率 #red = (32, 43, 43, 55, 36, 51) #yellow = (45, 68, -14, -1, 42, 56) blue = (18, 39, 2, 32, -58, -32) #green = (18, 39, -40, -20, 8, 21) while(True): clock.tick() # 这个可以记录帧率 img = sensor.snapshot() # 拍照+获取图像 for c in img.find_circles(r_min = 10): area = (c.x()-c.r(), c.y()-c.r(), 2*c.r(), 2*c.r()) statistics = img.get_statistics(roi=area) if 18<statistics.l_mode()<50 and 2<statistics.a_mode()<38 and -60<statistics.b_mode()<-22: img.draw_circle(c.x(), c.y(), c.r(), color = (255, 0, 0),thickness=3) else: img.draw_rectangle(area, color = (255, 255, 255)) img.draw_string(0, 0,"FPS :%.2f"%(clock.fps()),mono_space = False,scale = 2)
效果如下: