本篇大致探索下图像的识别。实现了颜色识别,以及利用直方图来计算图像相似度。先来个视频。
摄像头实时捕捉画面,从画面中解析出蓝色的区域,并与预设图像对比,相似度小于0.5(0为完全匹配),闪光灯闪5秒。注意流量和音量。
取一张返回到PC上的图像,分了四部分:
左上:640*480为摄像头实时图像
左下:为预设图片,以及预设图片蓝色通道的直方图,颜色空间为HSV
右上:640*480为识别出的蓝色区域,上边红色数字为直方图相似度
右下:实时图像获取的蓝色区域的直方图
如下图示:识别成功,直方图近似
识别失败,估计是光照和角度影响,直方图差异大
大致描述下实现过程,先准备预设图片,用树莓派的摄像头拍一下,准备好,省的后续环境因素影响大,难以匹配。预设图片和实时捕获的图片同样的处理方法,开始愉快的写代码:
转换颜色空间:
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
定义感兴趣的颜色区域
lower_blue = np.array([110, 50, 50])
upper_blue = np.array([130, 255, 255])
mask = cv2.inRange(hsv, lower_blue, upper_blue)
为了过滤掉其他小面积的蓝色噪点,用3*3的卷积核腐蚀2次,膨胀一次,
mask = cv2.inRange(hsv, lower_blue, upper_blue)
kernel = np.ones((3,3), np.uint8)
erosion = cv2.erode(mask, kernel, iterations = 2)
dilation = cv2.dilate(erosion, kernel, iterations = 1)
得到蓝色区域
res = cv2.bitwise_and(img, img, mask= dilation)
计算直方图
originHist = cv2.calcHist([res], [0], mask, [256], [0, 256])
比较两个直方图,用巴氏距离,其他还有卡方或是相关性比较等还没来得及对比测试。设置一个比较宽松的范围,0.5以下即认为匹配成功,最好的情况是0.16。匹配成功后让小车的灯闪5秒。
comp = cv2.compareHist(flashHist, currentHist, cv2.HISTCMP_BHATTACHARYYA)
if comp
car.flash_light_on(80)
time.sleep(5)
car.flash_light_off()
最后将拼接好的图片写到系统临时目录下,用mjpg-streamer通过http输出,浏览器可查看
output[0:480,-640:] = resImg
cv2.imwrite(('/tmp/cv/output%03d.jpg' % (i%100)), output)
启动mjpg_streamer
mjpg_streamer -i "input_file.so -f /tmp/cv/" -o "output_http.so -w /usr/local/share/mjpg-streamer/www"
如果OpenCV无法访问摄像头,执行下面命令:
sudo modprobe bcm2835-v4l2
最后执行
python3 SmartCarControlByCV.py
打开浏览器,用以下地址可查看效果,延迟比较大。mjpg-streamer的使用见历史文章。
http://ip:8080/?action=stream
当然也可以训练其他的图片,让小车做其他的行为,在树莓派之外的环境也可实现。本文写的比较稚嫩,方法也比较初级,慢慢升级,后续手势控制也有了可行性。
完整的代码见:SmartCarControlByCV.py
Git地址:
https://github.com/Cat-31/Cat31Driver.git
复制链接可在浏览器查看代码
https://github.com/Cat-31/Cat31Driver/tree/master
本文来自企鹅号 - 全球大搜罗媒体
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文来自企鹅号 - 全球大搜罗媒体
如有侵权,请联系 cloudcommunity@tencent.com 删除。