根据最近官方MaixPy3和M2 Dock的知识,参考官方文档和样例,在官方大牛的支持下,学习了基础的魔方色块的寻找功能,并以此分享给大家。
目录:
一、基础知识普及
图传:
图传的概念,在无人机中非常常见,简单来讲,就是把摄像头拍摄的实时视频,又快又好的传递到终端设备上呈现,既要速度,不能卡,卡了没意思,也要质量,清晰度不能低,低了没得玩。而传输速度快,质量高,又可能占用较多的设备资源,以及需要较大的带宽,所以设计一个上好的图传方案和系统,是很多该行业厂家的重大追求目标之一。
Lab:
Lab是一种用数字化的方法来描述人的视觉感应的颜色系统。它是一种设备无关的、基于生理特征的颜色系统。在机器视觉中,Lab的概念会经常提及。
可以用一张图,来详细描述Lab颜色空间:
上述图,是从人的视觉感应角度来看的。
首先是L:表示亮度,从纯黑到纯白,取值可以从 0 -> 100
然后是a:表示从红色到绿色的范围,取值可以从 -128 -> 127
最后是b:表示从蓝色到黄色的范围,取值可以从 -128 -> 127
通常,Lab会以范围的形式来表示,也就是Lab阈值,因为因为现场环境的不同,我们看到的颜色,不可能是完完全全的理论纯色,所以给出一定的容错范围;
例如:[(0, 100, 21, 127, -128, -9)],分别表示:L-min、L-max、a-min、a-max、b-min、b-max,机器视觉就根据这个范围,来进行颜色判断。
二、M2 Dock图传功能开启
了解了以上的基础概念后,我们就可以进入正题,在M2 Dock上,具体使用相关的功能。
得益于MaixPy3
的强大,不用10行代码,就能开启M2 Dock的图传功能,以下为实际的代码:
from maix import camera, mjpg, utils, display
queue = mjpg.Queue(maxsize=8)
mjpg.MjpgServerThread("0.0.0.0", 18811, mjpg.BytesImageHandlerFactory(q=queue)).start()
while True:
img = camera.capture()
jpg = utils.rgb2jpg(img.convert("RGB").tobytes(), img.width, img.height)
queue.put(mjpg.BytesImage(jpg))
display.show(img)
要运行上述代码,方法很多:
在 MaixPy3
的网页编辑界面中,运行上述代码:
可以用adb shell或者ssh连接到M2 Dock后,运行python后,再输入代码运行
也可以用adb shell或者ssh连接到M2 Dock后,用vim编辑tuchuan.py并保存后,再执行python ./tuchuan.py
运行
方式1最方便,方式2最麻烦,方式3运行效率最好。
建议一般玩家,选用方式1最合适了。
正确运行以上代码后,就能正常开启图传功能了。
二、图传功能使用
要访问M2 Dock提供的图传功能,可以有几种方式:
MaixPy3
的网页编辑界面中,运行了图传功能开启,运行界面直接就调用了图传数据并呈现出来了,如上面的图所示;
如果是通过adb shell连接到M2 Dock执行启动图传的代码,那么可以使用http://127.0.0.1:18811
直接访问,如:
如果是通过adb shell连接到M2 Dock执行启动图传的代码,且已经联网了,那么可以使用http://设备ip地址:18811
直接访问,如:
还可以写一个简单的网页,打开网页直接访问(地址请参考2、3),如:
<img src="http://127.0.0.1:188811">
M2 Dock的这个图传地址http://127.0.0.1:18811
的实际处理,使用的是在 MaixPy3 中内置的 mjpg 包来进行的。MJPG 编码是一种常见且简易的视频编码方案,只需要将每一帧压缩成 jpg 图片后不断发送给客户端就行。
三、Lab阈值获取
前面说过,机器视觉中会利用到Lab,同样的,MaixPy3也提供了很简单的方法来应用Lab阈值。
我们先想办法,来得到一组合适的阈值,这可以使用 HonestQiao/thresholding-filter-browser-html: Browser HTML opencv.js thresholding filter lab hsv binarize (github.com) 工具。这个工具由Sipeed的大牛JunhuanChen提供,我fork源码后做了一点点小修改,方便使用。
然后,开启命令行,在上述下载的代码目录中,执行如下命令,启动本地web服务:
python -m SimpleHTTPServer 8888
如果执行后提示:
No module named SimpleHTTPServer
那就换一条指令:
python -m http.server 8888
成功运行后,会出现提示信息:
Serving HTTP on :: port 8888 (http://[::]:8888/) ...
然后,通过网页访问 http://127.0.0.1:8888/即可打开在线获取Lab阈值页面:
在该界面上,提供了一个默认的色块图片;
你也可以上传已有的图片来进行处理;
如果前面开启了图传,那么可以设置图传地址:
根据使用的经验,我一般会这么进行调整,来获取需要的阈值。
例如,我想要获取橙色色块的阈值,那么,我会先调整a,达到如下的效果:
在上图中,可以看到红色色块与橙色色块接近,所以先让这两个色块在右图上,都呈现出白色区块。而其他部分,都呈现为黑色。
然后,再调整L,使得颜色暗一些的红色,被排除掉:
然后可以切换到魔方的其他面,并进行微调,确保能够较好的识别各个面的橙色块:
注意,获取Lab阈值的时候,不要像下面这样,把同一种颜色都拧到一面来:
这样确实很整齐,但是,我们不仅仅要获取这种颜色的阈值,同时,还得把其他干扰的颜色,给排除出去。
所以,把魔方打乱了去识别,效果会更好。
通过以上的方式,我们就能得到魔方六面6种颜色格子对应的Lab阈值了。
but,but,but,经过实际测试发现,我手头这个三阶魔方,是比赛用的,贴纸半光高亮的,红色和橙色,人看着挺好,但摄像头不好区分。
于是,我把家里的魔方摆出来,仔细挑了挑:
最后选择了金字塔魔方,这个魔方是黑底的,颜色为红黄蓝绿四色,颜色分明,底色也不会干扰。
而白底的魔方,通常都有白色色块,会造成干扰。
另外咱们现在还是做很基础的实验,所以也不能用纯色的魔方。
挑选出来的金字塔魔方真身如下:
在我挑选魔方的时候,孩子很好奇我在干嘛,于是凑过来。
然后,然后孩子就占了主场,不出一分钟,就理解了Lab阈值的概念,并学会了怎么获取Lab阈值:
所以下面的部分,主要由孩子完成,我提供技术支持和指导。
我们用一个手机支架,把M2 Dock支起来,摄像头对准魔方:
然后在Lab阈值获取界面,进行阈值的调整查看:
最终,获得了四组颜色对应的嗯Lab阈值:
[(0, 100, -128, -23, -128, 127)], #绿色
[(10, 100, 30, 127, -37, 127)], #红色
[(40, 100, -25, 42, 7, 127)], #黄色
[(0, 100, -128, 127, -128, -46)], #蓝色
并参考官方的例子,编写了下面的程序:
from maix import image, display, camera
color = [
[(0, 100, -128, -23, -128, 127)], #绿色
[(10, 100, 30, 127, -37, 127)], #红色
[(40, 100, -25, 42, 7, 127)], #黄色
[(0, 100, -128, 127, -128, -46)], #蓝色
] # 0.5.0 以后蓝色的 lab 阈值,0.4.9 之前为 [(13, 11, -91, 54, 48, -28)]
font_color = [ # 边框和文字颜色,暂时都用白色
(255,255,255), # 绿色
(255,255,255), # 红色
(255,255,255), # 黄色
(255,255,255) # 白色
]
name_color = ('green', 'red', 'yellow', 'blue')
while True:
img = camera.capture()
for n in range(0,4):
blobs = img.find_blobs(color[n]) #在图片中查找lab阈值内的颜色色块
if blobs:
for i in blobs:
if i["w"]>15 and i["h"]>15:
img.draw_rectangle(i["x"], i["y"], i["x"] + i["w"], i["y"] + i["h"],
color=font_color[n], thickness=1) #将找到的颜色区域画出来
img.draw_string(i["x"], i["y"], name_color[n], scale = 0.8,
color = font_color[0], thickness = 1) #在红色背景图上写下hello worl
display.show(img)
运行上述代码后,识别的效果如下:
从中可以看到,M2 Dock又快又好的识别出来了对应的魔方色块颜色。
当然,因为背景颜色和黄色接近,所以也被识别了。
可以找一张大的黑色胶片或者黑色纸,垫在下面和支在背后,这样子就能消除干扰了。
更多回帖