树莓派硬件结构
树莓派4B硬件结构

- DSI(Display serial interface)视频信号传输接口,将视频信号从处理器传输到显示器的一种高速串行接口
- POE(Power Over Ethernet)以太网供电,是一种在同一根以太网电缆上传输数据和电力的技术,这种技术使得网络设备如AP、IP摄像头等无需单独的电源线,只需要通过以太网电网缆线就能获得电力供应 以下是树莓派引脚图

- 彩色编号为BCM编号,使用的是Boardcom SOC上的编号
- 灰色为BOARD编号,是树莓派上实际的物理编号
PWM(Pulse-width modulation)
脉冲宽度调制器,简称脉宽调制,PWM技术是一种将模拟信号电平进行数字编码的技术。
不同于模拟电路,数字电路只需要通过电流/电压的通断形成的重复脉冲序列就可以进行信号表示,而模拟电路表示的模拟信号有诸多问题:难以调制、功耗大、易受噪声和环境干扰等。PWM技术则通过调制方波的占空比来实现对模拟信号的数字编码,
方波:方波是一种非正弦曲线的波形,理想方波只有高低两个值,下图第二个是方波示例
占空比(duty cycle):表示在一个周期内,工作时间和总时间的占比。这是一个宽泛的定义,以下是在不同情境中具体的定义
- 在一串理想的脉冲序列(方波)中,占空比表示正脉冲持续时间和脉冲总时间的比值
- 在周期性现象中,现象发生时间和总时间的比值
通过PWM技术对模拟信号进行数字化调制,我们可以使用数字信号进行更加准确的传输,并在最后将数字信号调制为准模拟信号,以下是PWM调制过程(有点积分的感觉,方波积分得到模拟信号bushi)

I2C通信协议(Inter-Integrated Circuit)
通信方式
I2C通信协议是一种半双工同步通信协议
- 同步:接收端和发送端时钟频率一致
- 半双工:能够双向通信,但通信双方不能同时进行数据收发,在同一时刻只有一方发送另一方接收
数据格式
I2C通信的数据包大小为8bit,分为三类
- 指令:7位从机地址 + 1位读写命令
- 数据:8位数据
- 字节地址:8位字节地址,从这个地址开始读数据
信号含义
I2C使用串行通信方式,使用数据线SDA和时钟线SCL两条线进行同步半双工通信,由SDA和ASCL两条线确定的信号状态分为以下5种
- 空闲状态:当I2C的SDA和SCL两条线都处于高电平时,规定总线为空闲状态
- 启动信号:当SCL中处于高电平,数据线SDA走向下降沿,表示一次数据传输的开始
- 停止信号:当SCL中处于高电平,数据线SDA走向上升沿,表示一次数据传输的结束
- 数据传输(按位串行):在SCL每一个高电平期间对SDA数据线中的一位数据进行采样,这要求SDA在SCL高电平期间不能改变;只有在SCL低电平期间,SDA上的数据才能改变
- 应答信号:I2C所有数据都是8bit传输,发送器(transmitter)每发送一个字节,在第9个时钟开始时释放数据线,由接收器(receiver)反馈一个接收信号。在第9个时钟脉冲之前(高电平之前),接收器改变SDA电平,当应答信号为低电平时为有效应答位(ACK),当应答信号为高电平时为无效应答位(NACK)

SDA和SCL数据线均通过上拉电阻接入VCC
上拉电阻
下拉电阻
其他通信协议
SPI(Serial Periperal Interface)串行外设接口:是一种同步、全双工、串行、主从结构的通信协议,通过四根总线通信
- CS:主机对从机的片选信号,因为SPI允许多个从机连接至主机
- SCLK:主机向从机发送的时钟信号
- MOSI:master 发送给 slave的数据信号
- MISO:salve 发送给 master 的数据信号

1-Wire单总线协议:主机和从机采用一根总线进行通信,该总线可以传输时钟和数据,却传输方向是双向的。使用该协议的传感器模块有DHT11温湿度传感器和DS18B20温度传感器
第三方库RPi.GPIO库编程
引脚用法
GPIO.setmode(mode)
@brief: 用于设置GPIO引脚编码方式@param:设置可用的引脚编码方式,可以用GPIO.BCM和GPIO.BOARD两种
GPIO.setwarnings(bool)
@brief:用于忽视GPIO端口的警告@param:可设置为True和False两种
GPIO.setup(channel, mode)
@brief:通道设置方法,可以设置一个或者多个管脚的输入输出模式@param pins: 可以使用单个引脚编号,或使用列表或者元组组合的引脚组@param mode:可设置为GPIO.IN GPIO.OUT GPIO.BOTH三种
GPIO.input(channel)
@brief:获取引脚的值@return:0/GPIO.LOW/False或1/GPIO.HIGH/True
GPIO.output(channel, val)
@brief:输出到引脚的值,参数同理GPIO.input
PWM脉冲使用
p = GPIO.PWM(channel, freq)
@brief:获取对管脚的PWM控制权,创建PWM实例@return:p = GPIO.PWM(pin, freq)
p.start(dc)
@brief:设置该管脚PWM的占空比@param:100 >= dc >= 0
p.ChangeFreqency(freq)
@brief:改变管脚的脉冲频率@param:freq单位为Hz
p.ChangeDutyCycle(dc)
@brief:改变管脚的PWM占空比
传感器模块
蜂鸣器


有源蜂鸣器 无源蜂鸣器
有源蜂鸣器发出单一的提示警报,没有频率变化。无源蜂鸣器的驱动为脉冲频率驱动,可以发出各种有频率的声音
旋转编码器

管脚介绍
- GND/VCC:接地/电源接口
- SW管脚可用于实现按键效果,当按下旋转编码器的轴时,SW的电平被拉低,表示一个按键按下事件
- CLK(A output)管脚输出方波脉冲,当旋转编码器旋转时,该引脚产生高低变化的信号,该信号可用于计数脉冲,确定旋转的步数或者角度
- DT(B output)管脚同样输出方波脉冲,但是和CLK管脚的脉冲有90度的相位差,该相位差可用于检测旋转方向
PCF8591
PCF8591是一个具有4个模拟输入、1个模拟输出的8位模数转换器(ADC)和数模转换器(DAC)

管脚介绍
- AIN0、AIN1、AIN2、AIN3:模拟电路输入接口
- AOUT:模拟信号输出接口,用于数模转换
- GND:接地
- SCL:I2C通信输出接口
PCF8591控制字

- 如上图,D7和D3恒为0,作为芯片扩展位
- D6为模拟输出使能位
- D2为自动增量模式使能位
- D4、D5为模拟输入模式选择位
- 00:四路单端输入
- 01:三路差分输入
- 10:单端和差分配合输入
- 11:两路差分输入
- D0、D1为输入引脚选择位,0~3分别对应AIN0 AIN1 AIN2 AIN3
PCF8591物理地址

已知在PCF8591物理地址的编址中,总共用7位表示物理地址,其中前4位为固定位wilidz1001,可编程位A0 A1 A2三位。注意最低位为方向位|读写位(决定数据传输方向),且该低位不算在物理地址中
PCF8591芯片引脚(它真考啊哥们儿,考完含泪记下)
VREF:基准电源端OSC:外部时钟输入端,内部时钟输出端EXT:内部外部时钟选择线,使用内部时钟时EXT接地VSS:接电源负极,即GNDAGND:模拟信号地- 其他引脚在上面介绍过
MPU6050陀螺仪加速度传感器
MPU6050是一款完整的6轴运动跟踪设备,其中6轴包括三轴陀螺仪和三轴加速度计。此外,注意MPU6050还有片上温度传感器,且具备I2C总线接口。I2C总线可以与其他传感器进行通信,如果将三轴磁力计连接到辅助I2C设备,MPU6050模块可以通过其内部的数字运动处理器DMP将不同传感器的运动数据融合,得到完整的9轴Motion Fusion输出。

管脚介绍
- VCC
- SCL:I2C通信数据线
- XCL(Auxiliary):辅助I2C数据线,用于外部连接磁力计传感器,通过该辅助I2C总线,允许MPU6050直接控制外部传感器的时钟信号
- AD0:I2C地址选择引脚,将此引脚接地时,I2C地址为0x68,当该引脚连接到VCC时,I2C地址为0x69,这允许再同一I2C总线上连接多个MPU6050设备
模块构成
- 三轴陀螺仪(Three-axis Gyroscope):测量设备在X, Y, Z三轴上的角速度
- 三轴加速度计(Three-axis Accelerometer):测量三周上的加速度
- 数字运动处理器(Digital Motion Processer):处理和融合以上两者的数据,做出姿态估计、运动检测、方向检测等
- 温度传感器:测量内部温度,提供温度补偿
- I2C通信接口:和主处理器进行通信
MPU6050可以通过陀螺仪和加速度计的测量计算出姿态角,姿态角由三个旋转角度构成
- 滚旋角(Roll):飞机绕前后轴的旋转角度,通常为-180°~180°
- 俯仰角(Pitch):飞机绕左右轴的旋转角度,通常为-90°~90°
- 偏航角(Yaw):飞机绕垂直轴的旋转角度,通常为-180°~180°
opencv应用
色彩空间
常见的HSV和HSL都是将RGB色彩模型表示在圆柱坐标系中的方法,该方法比笛卡尔坐标系中表示的RGB模型更加直观
- 色相(Hue):色彩的基本属性,即平常所说的颜色名称
- 饱和度(Saturation):色彩的纯度,越高色彩越纯,越低色彩越灰
- 明度(Value):也是亮度,取值在0~1之间
色调表示为一个圆环,范围理论上是0°~360°,在opencv中,采用一个单位表示2°,因此色调的范围是0 ~ 180,便于8位深度的存储,而饱和度和明度的范围在opencv中也都是8位存储,范围0 ~ 255

opencv常用接口
- 色彩空间转换:将RGB转化为HSV
1 | hsv = cv2.cvtColor(frame, cv2.BGR2HSV) |
- 通道分割
1 | hue, sat, val = cv2.split(hsv) |
- 图像二值化
1 | cv2.inRange(img, lowerb, upperb, dst=None) |
@brief:根据颜色或者灰度阈值进行二值化,是用于分隔特定颜色范围的对象@param:lowerbupperb表示阈值下界和阈值上界,dst输出二值化图像,原图中在范围内的像素设置为白色(255),在范围外的像素设置为黑色(0)

1 | cv2.threshold(img, thresh, maxval, type, dst=None) |
@brief:适用于按照单一阈值对图像进行二值化处理,适用于灰度图像,全局阈值处理@paramsrc: 输入图像,必须是单通道灰度图thresh: 阈值maxval: 超过或低于阈值时赋予的新值type: 阈值类型,如cv2.THRESH_BINARY,cv2.THRESH_BINARY_INV等dst: 输出图像
- 通道与运算
1 | cv2.bitwise_and(src1, src2, dst=None, mask=None) |
@brief:该函数通常用于执行**两个图像数组*之间的按位与按操作,可以用于图像掩膜、特征提取、图像融合等@param mask:该参数是一个单通道8位图像数组,其非零像素表示在相应的src1和src2对应位置上进行。当src1和src2指向同一张图片时,表示只想对图片中的特定区域进行某种操作
- 监听键盘事件
1 | cv2.waitKey(delay) |
@param:delay设置等待键盘输入的时间,当该时间段中没有检测到任何键盘输入就返回-1;当delay为0时为无限等待,直到响应键盘输入;当delay之为负数时,键盘输入任何按键都会结束
形态学处理方法
图像掩膜
图像掩膜一般是一个和原图尺寸相同的二值图像(单通道8位数组),其像素值通常是0或255,通过图像掩膜,可以对图像的特定部分进行增强、修改和分析而不影响其他部分
形态学转换
结构元:可以将二维结构元理解为二维数组,矩阵元素为0或1,1为有效元素,结构元尺寸小于待处理图像尺寸,注意结构元都以一个结构元原点
腐蚀:结构元整体不能超出待处理图像像素区域,其结构元原点能够经过的区域为腐蚀结果
1
cv2.erode(img, kernel, iteration=1)
参数含义同
cv2.dilate()膨胀:结构元只有结构元原点不能超出图像像素区域,其整体经过的像素区域为膨胀结果
1
cv2.dilate(img, kernel, iteration=1)
img:目标图片kernel:操作内核,单通道8位图像数组iteration:膨胀次数
开运算:先腐蚀后膨胀,通常用于处理灰暗背景下的高亮区域
闭运算:先膨胀后腐蚀,消除孔洞,填充闭合区域,删除亮背景下的灰暗区域
1
cv2.morphologyEx(src, cv2.MODE, kernel)
src:目标图像,要求是单通道灰度图像cv2.MODE:可使用cv2.MORPH_CLOSE闭操作或者cv2.MORPH_OPEN开操作kernel:结构元操作核
人脸识别
在opencv中,人脸识别采用Haar级联分类器算法,流程如下
face_cascade = cv2.Cascade_Classifier(filePath)加载预训练分类器中的模型,一般在opencv安装目录.\opencv\sources\data\ haarcascades路径下ret, frame = cap.read()读取视频中的一帧(一张图片),ret为获取图像是否成功,frame为获取到的图片对象gray_img = cv2.cvtColor(frame, cv2.RGB2GRAY)将彩色RGB图像转化为灰度图,提高模型识别效率faces = detectMultiScale(gray_img, scaleFactor=1.3, minNeighbors=5)@param scaleFactor:前后两次相继的扫描中,搜索窗口的比例系数,此处表示搜索窗口每次扩大30%@param minNeighbors:表示构成检测目标的相邻矩阵最小个数,当一个对象检测出的矩形数量小于该数则舍弃@return:返回数组,每个元素四个成员(x, y, width, height)
cv2.rectangle(img, (x, y), (x + width, y + height), color, thickness: int)@param:通过矩形的左上角点坐标和右下角点坐标确定矩形位置和形状,见参数列表中的两个坐标元组@param color:指定矩形框的颜色,可用RGB模式的三元组表示@param thickness:指定矩形框线条的粗细
cv2.imshow('image', img)显示人脸识别处理过的图像,字符串指定窗口名称
二维码/条码识别
使用
imutils.video库中的VideoStream()函数创建视频流1
vs = VideoStream(src=0).start()
使用
imutils.resize()方法对视频流中的每一帧进行裁剪,在该函数中单指定宽/高时,会将图像进行等比例缩放1
frame = imtuils(frame, width=400)
使用
pyzbar的核心函数decode()1
barcodes = pyzbar.decode(frame)
pyzbar.decode(frame)返回的类型包含识别结果的各种信息属性barcodes.rect属性:检测到二维码矩形的左上角点坐标和长宽信息barcodes.type属性:返回读取到条码的编码类型,如QRCODEbarcodes.data属性:返回符号数据,通常为字母/数字,可以指定编码类型1
barCodeData = barcodes.data.decode('utf-8')
框定二维码所在位置,使用
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255, 2))文本信息展示,将解析结果的
data属性和type属性展示出来,使用cv2.putText()函数1
cv2.putText(frame, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
接口定义如下
1
cv2.putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None)
org: 文本的左下角坐标(x, y)。这是一个二元组(元组),指定文本在图像上的位置fontFace:字体类型fontScale:字体大小比例因子color:字体颜色thickness:文本线条粗细


