树莓派——智能推送
本教程为python实训作业的笔记,包括了从如何烧系统到最后作品成型我所踩过的坑,走过的弯路(说多都是泪啊_)
开头篇
首先,老爷保号,bug远离我。
随着科技的发展,广告行业的技术发展日新月异,网络大数据精准投送广告技术已经很成熟了。但是在现在场景中,却少有应用,所以,智能推送将应用与如商场,电梯,KTV,人脸支付等公共场景。
智能推送,类似于现在市面上的魔镜之类的产品,他可以与用户之间实现一种非常nice的交互效果。所有智能推送系统将参考魔镜的交互方式,并把她运用在电梯,商场等。就先酱了,接下来就是枯燥的教程啦!
安装树莓派
树莓派官网
1、格式化SD卡
2、把树莓派系统烧进去 工具下载
众所周知,在我大天朝,有一种叫墙的东西,so?镜像就应运而生了,在树莓派下载安装东西,我们最好都给它来个镜像。fq?dddd啊。烧完系统,在boot同一路径下建一个txt文件,命名为ssh,注意去掉".txt"。
获取树莓派IP
1、WiFi
在boot同一路径下建一个txt文件,命名为wpa_supplicant.conf里面写入
country=CN
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="WiFi-A"
psk="12345678"
key_mgmt=WPA-PSK
priority=1
}
network={
ssid="WiFi-B"
psk="12345678"
key_mgmt=WPA-PSK
priority=2
scan_ssid=1
}
ssid:网络的ssid
psk:密码
key_mgmt:加密类型
priority:连接优先级,数字越大优先级越高(不可以是负数)
scan_ssid:连接隐藏WiFi时需要指定该值为1
配置好开机后,就可在WiFi官网上看到树莓派的IP了
2、网线
直接将网线连接电脑和树莓派,树莓派网口闪绿灯,然后就直接在电脑上查看IP了
SSH远程连接
下载VNC直接用ip连接
默认用户名:pi
默认密码:raspberry
恭喜!到此为止,树莓派就算是开机成功了
(如果不幸失败,就格式化再弄一次吧!)
更新树莓派
由于树莓派的服务器是在英国,要给所有的资源下载都改成国内的镜像。网上常见的教程往往都是替换软件更新源(/etc/apt/sources.list),实际上还存在一个系统更新(/etc/apt/sources./raspi.list)。我们对这两个文件进行修改,将其中的源网址更换为国内镜像站点即可。(个人觉得nano是个不错的文本编辑器)
sudo nano/etc/apt/sources.list
修改为:
deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi
deb-src http://mirrors.ustc.edu.cn/raspbian/raspbian/ buster main contrib non-free rpi
sudo nano /etc/apt/sources.list.d/raspi.list
修改为:
deb http://mirrors.ustc.edu.cn/archive.raspberrypi.org/debian/ buster main
deb-src http://mirrors.ustc.edu.cn/archive.raspberrypi.org/debian/ buster main
接下来就可以快速更新了,执行:
sudo apt-get update
sudo apt-get upgrade
安装python3
1、安装依赖包
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev
sudo apt-get install -y libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm
sudo apt-get install -y libncurses5-dev libncursesw5-dev xz-utils tk-dev
2、解压
解压结束 进入生成的目录python-3.7.3
安装python
安装完成,创建软连接,打印版本测试。
sudo tar -zxvf Python-3.7.3.tgz
cd Python-3.7.3
sudo ./configure --prefix=/usr/local/python3
sudo make
ln -s /usr/local/python3/bin/python3 /usr/local/bin/python3
ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip3
python3 -V
pip3 -V
安装opencv-python
安装依赖库
sudo apt-get install libjpeg-dev
sudo apt-get install libatlas-base-dev
sudo apt-get install libtiff5-dev
sudo apt-get install libpng12-dev
sudo apt-get install libqtgui4 libqt4-test
sudo apt-get install libjasper-dev
没想到吧,安装就一句命令的事儿
sudo pip3 install opencv-python
如果在命令行import cv2
成功,安装就算成功啦
人脸识别算法
先在GitHub下载六个识别模型
把他们放在和py文件一个目录下
下方高能链接
代码
一、后端
后端代码分为4个模块,
1、人脸识别(识别到返回年龄段和性别)
#-*- coding: utf-8 -*-
import cv2 as cv
import time
# 检测人脸并绘制人脸bounding box
def getFaceBox(net, frame, conf_threshold=0.7):
frameOpencvDnn = frame.copy()
frameHeight = frameOpencvDnn.shape[0] # 高就是矩阵有多少行
frameWidth = frameOpencvDnn.shape[1] # 宽就是矩阵有多少列
blob = cv.dnn.blobFromImage(frameOpencvDnn, 1.0, (300, 300), [104, 117, 123], True, False)
# blobFromImage(image[, scalefactor[, size[, mean[, swapRB[, crop[, ddepth]]]]]]) -> retval 返回值 # swapRB是交换第一个和最后一个通道 返回按NCHW尺寸顺序排列的4 Mat值
net.setInput(blob)
detections = net.forward() # 网络进行前向传播,检测人脸
bboxes = []
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > conf_threshold:
x1 = int(detections[0, 0, i, 3] * frameWidth)
y1 = int(detections[0, 0, i, 4] * frameHeight)
x2 = int(detections[0, 0, i, 5] * frameWidth)
y2 = int(detections[0, 0, i, 6] * frameHeight)
bboxes.append([x1, y1, x2, y2]) # bounding box 的坐标
cv.rectangle(frameOpencvDnn, (x1, y1), (x2, y2), (0, 255, 0), int(round(frameHeight / 150)),
8) # rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> img
return frameOpencvDnn, bboxes
def getInfo():
ages=[]
genders=[]
# 网络模型 和 预训练模型
faceProto ="opencv_face_detector.pbtxt"
faceModel = "opencv_face_detector_uint8.pb"
ageProto ="age_deploy.prototxt"
ageModel ="age_net.caffemodel"
genderProto ="gender_deploy.prototxt"
genderModel = "gender_net.caffemodel"
# 模型均值
MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)
ageList = ['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(25-32)', '(38-43)', '(48-53)', '(60-100)']
genderList = ['Male', 'Female']
# 加载网络
ageNet = cv.dnn.readNet(ageModel, ageProto)
genderNet = cv.dnn.readNet(genderModel, genderProto)
# 人脸检测的网络和模型
faceNet = cv.dnn.readNet(faceModel, faceProto)
# 打开一个视频文件或一张图片或一个摄像头
cap = cv.VideoCapture(0)
padding = 20
#定义一个识别次数20,取平均数
count=10
while cv.waitKey(1) < 0:
count-=1
# Read frame
t = time.time()
hasFrame, frame = cap.read()
frame = cv.flip(frame, 1)
if not hasFrame:
cv.waitKey()
break
frameFace, bboxes = getFaceBox(faceNet, frame)
if not bboxes:
print("No face Detected, Checking next frame")
continue
for bbox in bboxes:
# print(bbox) # 取出box框住的脸部进行检测,返回的是脸部图片
face = frame[max(0, bbox[1] - padding):min(bbox[3] + padding, frame.shape[0] - 1),
max(0, bbox[0] - padding):min(bbox[2] + padding, frame.shape[1] - 1)]
print("=======", type(face), face.shape) # <class 'numpy.ndarray'> (166, 154, 3)
#
blob = cv.dnn.blobFromImage(face, 1.0, (227, 227), MODEL_MEAN_VALUES, swapRB=False)
print("======", type(blob), blob.shape) # <class 'numpy.ndarray'> (1, 3, 227, 227)
genderNet.setInput(blob) # blob输入网络进行性别的检测
genderPreds = genderNet.forward() # 性别检测进行前向传播
print("++++++", type(genderPreds), genderPreds.shape, genderPreds) # <class 'numpy.ndarray'> (1, 2) [[9.9999917e-01 8.6268375e-07]] 变化的值
gender = genderList[genderPreds[0].argmax()] # 分类 返回性别类型
# print("Gender Output : {}".format(genderPreds))
print("Gender : {}, conf = {:.3f}".format(gender, genderPreds[0].max()))
ageNet.setInput(blob)
agePreds = ageNet.forward()
age = ageList[agePreds[0].argmax()]
ages.append(age)
genders.append(gender)
print("--------------------识别到年龄:",age)
print("--------------------识别到性别:", gender)
cv.waitKey(1)
# time.sleep(1)
print(agePreds[0].argmax()) # 3
print("*********", agePreds[0]) # [4.5557402e-07 1.9009208e-06 2.8783199e-04 9.9841607e-01 1.5261240e-04 1.0924522e-03 1.3928890e-05 3.4708322e-05]
print("Age Output : {}".format(agePreds))
print("Age : {}, conf = {:.3f}".format(age, agePreds[0].max()))
label = "{},{}".format(gender, age)
cv.putText(frameFace, label, (bbox[0], bbox[1] - 10), cv.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 255), 2,#显示头像年龄性别信息
cv.LINE_AA) # putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]]) -> img
cv.imshow("Age Gender Demo", frameFace)#显示识别窗口
if count<0:
print("=================识别结束==================")
# 传入两个识别到的年龄和性别数据,取其众数
age = max(ages, key=ages.count)
gender = max(genders,key=genders.count)
return age,gender
break
print("time : {:.3f} ms".format(time.time() - t))#识别一次花费的时间
2、音乐爬取模块(根据关键字去爬取相关的音乐,歌词,海报,音乐信息)
库:requests
'''
通过咪咕音乐爬取音乐。可以以关键字去搜索,返回一个json数据,再去爬取音乐,海报,歌词,歌曲信息等,保存到特定目录下
'''
import requests
import json
import os
import time
def download(key):
head = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
'Cookie':'migu_cn_cookie_id=1bdd01cf-0863-4626-807a-dde117f8ac62; Hm_lvt_ec5a5474d9d871cb3d82b846d861979d=1604933806; WT_FPC=id=259a9a71452bc6439d71594005492106:lv=1605184011867:ss=1605184011867',
'Accept':'image/avif,image/webp,image/apng,image/*,*/*;q=0.8'}
r = requests.get(f"http://pd.musicapp.migu.cn/MIGUM3.0/v1.0/content/search_all.do?&ua=Android_migu&version=5.0.1&text={key}&pageNo=1&pageSize=30&searchSwitch="+"{%22song%22:1,%22album%22:0,%22singer%22:0,%22tagSong%22:0,%22mvSong%22:0,%22songlist%22:0,%22bestShow%22:1}",verify=False)
j=json.loads(r.text)
print(j['code'])
print(j['info'])
print(j['songResultData']['result'][0])
#歌手id
singersId = j['songResultData']['result'][0]['singers'][0]['id']
#歌手名字
singersName = j['songResultData']['result'][0]['singers'][0]['name']
#歌曲标签
tags =j['songResultData']['result'][0]['tags']
#图片url,列表类型
imgUrl = [i['img'] for i in j['songResultData']['result'][0]['imgItems']]
print(imgUrl)
print(singersId)
print(singersName)
print(tags)
print(len(j['songResultData']['result']))
print()
name = j['songResultData']['result'][0]['name']
print(name)
SongUrl = r"https://freetyst.nf.migu.cn"+j['songResultData']['result'][0]['rateFormats'][0]['url'][24:]
print(r"https://freetyst.nf.migu.cn