树莓派图像识别处理与循迹小车经验分享 Posted 2021-04-07 一更idea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树莓派图像识别处理与循迹小车经验分享相关的知识,希望对你有一定的参考价值。
计算机图像处理、人脸识别、人眼定位、视觉巡线......woooooo太高大上了!
并不!
今天就由我向大家介绍一些简单的入门 知识,在文章的后面再分享一个视觉巡线小车小车的项目,和大家一起交流学习,共同进步!
当然,不是当下的新型冠状病毒的疫情,而是1666年那场鼠疫。
剑桥大学因此而放大假,正在攻读硕士学位的牛顿不得已离校返乡。
这段时光成了牛顿科学生涯的黄金时期,他的三大成就之一——光学分析就是在那个时期诞生的。[1]
牛顿之前的人们普遍认为白光是最纯净的光,而牛顿通过三棱镜实验证实了白色光是由红、橙、黄、绿、蓝、靛、紫七种顺序固定不变的光组成的,进而在此之后进一步推理,证明了
只有红光、蓝光、绿光三种颜色无法再分解或合成 。
就像是笛卡尔坐标系的三个基极,这三种颜色正交,由它们可以组合出任意我们想要的颜色,如上图,计算机显示颜色和影像正是利用了电子光照射在屏幕上的不同发光材料,多个色彩叠加得到了多姿多彩的计算机影像。
当然,只有这些还不够,自然界中看到的物体的色彩、轮廓是连续的、变化的,在影像中不可能完全的反映真实的物体的细微之处。
我们可以简单认为计算机图像是像素画。
这是像素画,假如给你一个格子数相同的纸,你要怎么画出来一个和这个相同的像素画呢?
1.
建立一个笛卡尔坐标系 ,给每个小格格定位,这样我们可以找到眼睛、盾牌......的位置(x,y)。
2.选好颜色,我们知道了任意颜色都可以由红蓝绿三种颜色组成,定义(R,G,B)=(j,k,l),红色是(255,0,0),绿色是(0,255,0),蓝色是(0,0,255);这样任意一种颜色都可以用这
三个向量 的组合表示出来,比如(120,200,15)即可以表示一种颜色。
经过上面两步,知道了在哪个位置涂什么颜色,你就能画出来一个一模一样的像素画。
相应的,经过这两步,任意指出一个位置,你都能说出来这个点的颜色。
计算机也是如此,当我们指定某一张图片的某一个像素点(x,y),确定每一个点的红色、蓝色、绿色的“亮度”,就可以得到对应的颜色(j,k,l)。
当我们指定图片的某一行(某一列),就可以得到一个行向量(列向量),这个向量的元素就是(j,k,l)。
对图像操作的方法大同小异,这里以spyder(python3.7)为例,不同的应用场景可能只是函数不同。
from skimage import io
img=io.imread('D:python_picmygf.png')
print(img.shape)
(448, 437,4)
即图片有448行像素点,437列像素点。
这里的4表示图片的通道数 ,描述一个像素点时,如果在灰度图,只需要一个数值即可(这一点的颜色有多黑),如果是彩色图,就需要RGB三个颜色来描述,这是三通道,如果加上一个alpha通道表示透明度,就是四通道。[2]
图片读入程序后,是以数组的形式保存的,因此,对数组的一切操作,对图片一样适用。
当然,我们也可以对一个像素进行修改,举个栗子。
from skimage import io
img=io.imread('D:python_picmygf.png')
rows,cols,dims=img.shape
mygf=img
for i in range(rows):
for j in range(0, cols):
if img[i,j,2]>230:
mygf[i,j,2]=0
io.imshow(img)
io.imshow(mygf)
这里我们对B通道的矩阵中的每个数据进行筛选,将其中大于230的数值全部改成0,直观的可以简单理解为:将图片里“更蓝的”部分找出来,然后将蓝色抹除。
还没完,图片可以操作还不够,对循迹小车来说,我们需要做的是把摄像头传回来的视频当成变化很快的一张张图片,即“帧”的概念。
简单 且枯燥
Opencv是一个开源计算机视觉库,无论是大神还是小白都爱它,Opencv被广泛的应用在人脸识别、边缘检测、自动驾驶等领域。
安装和使用OPencv的方法网络上非常多,就我本人的个人体验来说,这里推荐“同济子豪兄”的Opencv安装教程。[3]
安装这个库的目的是更方便的使用树莓派摄像头,其具有强大的内置函数和活跃的开源社区,在学习过程中出现问题也能够很容易找到帮助你的人。
GPIO(Gwneral Purpose I/O Ports)即为通用输入/输出口,在树莓派上就是指那40个引脚,它们的用法和其他单片机的用法类似,都是通过控制输出高低电平或者读入高低电平来进行控制外接元器件的。
有这个库,可以保证你能够通过树莓派自带的引脚控制电机。
serial库用于和Arduino或者其他单片机进行通信。
理论上我们可以用树莓派的GPIO口直接控制,但是为了防止手不老实的同学的作死举动,比如乱往树莓派上电导致树莓派GG,建议通过Arduino控制电机,Arduino通过USB线缆或者蓝牙与树莓派进行交流,毕竟,一块树莓派几百块,一块Arduino只要十几块。
这里放一张我们很早之前参加的学院里举办的循迹小车比赛的图,当时用的是光电对管,现在用摄像头,其实核心思想并没有什么不同,都是得到当前前进方向与目标前进方向的偏差,进而进行控制。
就这样的一个赛道而言,赛道是黑色的,我们可以把其他部分看作是白色的(当然摄像头回传的画面必定不会是严格的只有黑白色面),事实上,我们不需要分析摄像头传回来的完整的画面,举个例子:
假如摄像头回传的画面类似于上图,我们只需要将上图
先二值化 (非黑即白),再
选取合适的某一行 的某些像素点(甚至全部像素点)进行分析,左边右边都是白色,只有中间是黑色,所以只要找到黑色部分的中点,让小车朝着中点方向前进即可。
即偏差决定了左右轮的速度之差,检测到当前向左偏就让左轮速度加快,向右偏就让右轮速度加快。
这过程中会有很多问题,因为这种策略是一种偷懒的方法,也因此,效果并没有想象中好,比较需要关注的问题有摄像头得到的图像如何腐蚀膨胀、转弯时速度和控制策略如何调整等等[4],这里感谢CSDN大佬@yzy_1996,我参考了很多他的思路和程序,这里就不拿自己的程序在这里班门弄斧了。
最后,感谢达尔闻通过了我的树莓派板卡申请,树莓派——>python——>视觉循迹小车,非常感谢达尔闻带给我的支持与帮助。
[1]牛顿色散实验百度百科
https://baike.baidu.com/item/%E7%89%9B%E9%A1%BF%E8%89%B2%E6%95%A3%E5%AE%9E%E9%AA%8C/2991009?fr=aladdin
https://blog.csdn.net/mao_hui_fei/article/details/78217049
https://github.com/TommyZihao/Zihao-Blog/blob/master/%E5%AD%90%E8%B1%AA%E5%85%84%E6%95%99%E4%BD%A0%E5%9C%A8%E6%A0%91%E8%8E%93%E6%B4%BE%E4%B8%8A%E5%AE%89%E8%A3%85OpenCV.md
[4]【方法】树莓派小车自动循迹(摄像头) https://blog.csdn.net/yzy_1996/article/details/85318179?utm_source=app
以上是关于树莓派图像识别处理与循迹小车经验分享的主要内容,如果未能解决你的问题,请参考以下文章
求助树莓派避障小车,遇到 python 了
树莓派小车Python控制小车
[树莓派] 轻松制作一个遥控小车(C++,Socket)
[树莓派] 轻松制作一个遥控小车(C++,Socket)
树莓派视觉小车 -- 物体跟踪(OpenCV)
树莓派+Arduino+TensorFlow:搭建图像识别小车