郑重声明:文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,如果您不同意请关闭该页面!任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!

前言

距离上次的上篇已经过去了小半年时间了,真的不是我咕咕了,是因为自己挖的坑有点多,本片文章主要介绍的是如何对人脸进行检测和检测后的通讯方式,树莓派zeor w性能有点更不上所以我又买了4B(小声BB可能还有终篇

1

硬件清单

  • 读卡器以及 SD 卡
  • 树莓派官方摄像头一枚(夜视版
  • 树莓派4B
  • 电源(实际场景需要装个充电宝或者使用定制的电源)
  • 监听模块(如果想要带上声音可以装个)

安装python-opencv

更新树莓派系统

在这之前记得话pip源 、apt源、系统更新源换成国内的,并且使用树莓派4并且刷入最新版的包,刷入包的哈希值

SHA-256:c9c382b659bd96b859ccb9e2ac0c2292a91a37c286ab464f2f380d451077663d

sudo apt-get update
sudo apt-get upgrade

安装python-OpenCV

在这之前还需要把系统自带的python软连接换成python3.7

先查看系统中有那些Python版本

$ ls /usr/bin/python*

/usr/bin/python /usr/bin/python2-config /usr/bin/python3m
/usr/bin/python2 /usr/bin/python3 /usr/bin/python-config
/usr/bin/python2.7 /usr/bin/python3.5
/usr/bin/python2.7-config /usr/bin/python3.5m

先删除默认的Python软链接:

sudo rm /usr/bin/python

然后创建一个新的软链接指向需要的Python版本

sudo ln -s /usr/bin/python3.7 /usr/bin/python

安装pip3后安装3.4.6版本的opencv,因为最新版会报错,目前树莓派4最好安装这个版本

sudo apt-get install python3-pip
pip3 install opencv-python==3.4.6.27

1

测试是否安装成功

2

源码编译方式安装OpenCV

如果你不做后续开发之类的,源码编译的方式可以跳过

源码编译安装OpenCV比较繁琐,安装之后的OpenCV可以采用多种语言进行开发,是一种全面的安装,安装过程费时费力,笔者安装过程长达三到四个小时,一定要保证电源不会断,并把风扇插上,防止编译把树莓派给烧了

首先我们要安装OpenCV所依赖的各种工具和图像视频库

软件源更新
sudo apt-get update // 升级本地所有安装包,最新系统可以不升级
sudo apt-get upgrade// 升级树莓派固件
安装构建OpenCV的相关工具
#安装build-essential、cmake、git和pkg-config
sudo apt-get install build-essential cmake git pkg-config
安装常用图像工具包
// 安装jpeg格式图像工具包
sudo apt-get install libjpeg8-dev // 安装tif格式图像工具包
sudo apt-get install libtiff5-dev // 安装JPEG-2000图像工具包
sudo apt-get install libjasper-dev // 安装png图像工具包
sudo apt-get install libpng12-dev
安装视频I/O
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
安装gtk2.0

ubuntu有可能出现包版本过高的情况,需要将依赖包降级安装

#务必安装该包后再编译opencv
sudo apt-get install libgtk2.0-dev

如果需要降级可以使用下面这个工具,可以使用n来替换解决方案

sudo apt-get install aptitude
#用这个包解决冲突
sudo aptitude install libgtk2.0-dev

我使用的是这个解决方案

3

查看有没有安装成功
dpkg --listfiles libgtk2.0-dev #dpkg --listfiles package
优化函数包
sudo apt-get install libatlas-base-dev gfortran

获取OpenCV源代

// 下载OpenCV3.4.6
wget -O opencv-3.4.6.zip https://github.com/Itseez/opencv/archive/3.4.6.zip
// 解压OpenCV
unzip opencv-3.4.6.zip
// 下载OpenCV_contrib库:
wget -O opencv_contrib-3.4.6.zip https://github.com/Itseez/opencv_contrib/archive/3.4.6.zip
// 解压OpenCV_contrib库:
unzip opencv_contrib-3.4.6.zip

国内可以用这两条命令下载

wget -O opencv-3.4.6.zip https://gitee.com/asc0t6e/opencv/repository/archive/3.4.6.zip
wget -O opencv_contrib-3.4.6.zip https://gitee.com/asc0t6e/opencv_contrib/repository/archive/3.4.6.zip

编译OpenCv

#进入OpenCv目录
cd opencv
#新建release文件夹
mkdir release
#进入release文件夹
cd release

然后预编译

cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.4.6/modules \
-D WITH_FFMPEG=ON \
-D BUILD_EXAMPLES=ON ..

接着编译

#用4个核心编译他
make -j4
sudo make install
sudo ldconfig

安装VNC

首先树莓派上安装vnc服务

sudo apt-get install tightvncserver

接着输入vncpasswd来设置你的vnc密码,接着会问你Would you like to enter a view-only password (y/n)?选着n就好,然后输入vncserver来启动服务,记着这个参数后面连接需要用!!!!

4

安装操控端

在这个网站下载符合你电脑的版本

https://www.realvnc.com/en/connect/download/viewer/

点击File -> New connection,弹出Properties,在VNC Server中输入树莓派对应IP地址以及服务号,Name中可以输入也可以不进行输入,点击OK。(记得要填上服务号

5

接着就是输入你在树莓派设置的密码,连上如下

6

人脸检测

首先要了解cv2的几个需要用到的API,要捕捉视频,需要创建一个VideoCapture对象。它的参数可以是设备索引或视频文件的名称。设备索引只是指定哪个摄像头的号码。我们树莓派只有一个摄像头那这个参数就填0,如果有第二台摄像头可以通过传递1等来选择他。

接下来写一个dome,把识别的人脸保存为本地图片,如果想要他后台静默检测,可以把画矩形框显示视频这两行代码给注释了

import cv2
import time

#这个是你人脸检测训练好数据的文件目录
FaceCascadePath="haarcascade_frontalface.xml"
FaceCascade = cv2.CascadeClassifier(FaceCascadePath)

# 打开视频捕获设备
video_capture = cv2.VideoCapture(0)

while True:
if not video_capture.isOpened():#检查它是否被初始化
time.sleep(5)
pass

# 读视频帧
ret, frame = video_capture.read()#如果帧被正确读取,则为True

# 转为灰度图像
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

# 调用分类器进行检测,如果有人脸返回一个列表
faces = FaceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
# flags=cv2.cv.CV_HAAR_SCALE_IMAGE
)
if len(faces)>0:
cv2.imwrite(str(int(time.time())) + '.jpg', frame) # 存储为图像

# 画矩形框
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

# 显示视频
cv2.imshow('Video', frame)

if cv2.waitKey(1) & 0xFF == ord('q'):
break

# 关闭摄像头设备
video_capture.release()

# 关闭所有窗口
cv2.destroyAllWindows()

接下来使用树莓派测试下

7

然后查看我们捕获到的截图

8

既然检测到了人,那么接下来需要的就是让它如何告诉你了是不是

利用邮件通讯

接下来就是敲发邮件的代码了,首先需要你注册一个网易邮箱

然后点击设置->POP3/SMTP/IMAP

9

开启后会给你一串授权码,就是下面打码的那一段

10

源码如下

# !/usr/bin/python
# -*- coding: UTF-8 -*-

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText
from email.header import Header
from email.mime.image import MIMEImage
import zipfile
import cv2
import time
image_list=[]#图片列表
# 第三方 SMTP 服务
mail_host = "smtp.163.com" # 设置服务器
mail_user = "XXXXXX@163.com" # 用户名
mail_pass = "XXXXXXXXXXXXX" # 口令
receiver = 'XXXXXXXX@163.com' #接收邮件
def SendEamil(zip_file,image_file):
# 邮件内容
email_box = MIMEMultipart()#创建容器
# message = MIMEText("警戒警戒!莎莎检测到有人入侵!数据以保存喵~", 'plain', 'utf-8')#邮箱文字
# email_box.attach(message)#存入
email_box['From'] = "Salsa<"+mail_user+ ">"#发送人
email_box ['To'] = receiver#发给谁
email_box ['Subject'] = Header("入侵警报", 'utf-8')#标题

#发送压缩文件
zip_apart = MIMEApplication(open(zip_file, 'rb').read())
zip_apart.add_header('Content-Disposition', 'attachment', filename=zip_file)
email_box.attach(zip_apart)
#添加表情包图片

msgAlternative = MIMEMultipart('alternative')
email_box.attach(msgAlternative)

mail_msg = """
<p>警戒警戒!莎莎检测到有人入侵!数据以保存喵~</p>
<p><img src="cid:dns_config"></p>
"""
msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))
# 指定图片为当前目录
file = open(image_file, "rb")
img_data = file.read()
file.close()
img = MIMEImage(img_data)
img.add_header('Content-ID', 'dns_config')
email_box.attach(img)
try:
smtpObj = smtplib.SMTP()
smtpObj.connect(mail_host, 25) # 25 为 SMTP 端口号
smtpObj.login(mail_user, mail_pass)
smtpObj.sendmail(mail_user, receiver, email_box.as_string())
print("发送成功")
smtpObj.quit()
smtpObj.close()
except smtplib.SMTPException as e:
print(e)

def ZIP(time_name):
zip_file = zipfile.ZipFile(time_name+'.zip', 'w', zipfile.ZIP_DEFLATED)
# 把zfile整个目录下所有内容,压缩为new.zip文件
zip_file.write(time_name+'.jpg')
# 把c.txt文件压缩成一个压缩文件
# zip_file.write('c.txt',compress_type=zipfile.ZIP_DEFLATED)
zip_file.close()
return time_name+'.zip'


def FaceDetection():
FaceCascadePath = "haarcascade_frontalface.xml"
FaceCascade = cv2.CascadeClassifier(FaceCascadePath)
# FaceCascade = cv2.CascadeClassifier(config.FaceCascadePath)

# 打开视频捕获设备
video_capture = cv2.VideoCapture(0)

while True:
if not video_capture.isOpened(): # 检查它是否被初始化
time.sleep(5)
pass

# 读视频帧
ret, frame = video_capture.read() # 如果帧被正确读取,则为True

# 转为灰度图像
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

# 调用分类器进行检测,如果有人脸返回一个列表
faces = FaceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
# flags=cv2.cv.CV_HAAR_SCALE_IMAGE
)
if len(faces) > 0:
time_name=str(int(time.time()))
image_list.append(time_name)
time.sleep(1)
cv2.imwrite(time_name + '.jpg', frame) # 存储为图像
if len(image_list)>4:#如果容器里面图片超过4张发送邮件,防止疯狂发送
zip_file=ZIP(time_name)
SendEamil(zip_file, "test.gif")
image_list.clear()

# 画矩形框
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

# 显示视频
cv2.imshow('Video', frame)

if cv2.waitKey(1) & 0xFF == ord('q'):
break

# 关闭摄像头设备
video_capture.release()

# 关闭所有窗口
cv2.destroyAllWindows()


if __name__ == '__main__':
FaceDetection()

下图中13都改为你的网易云邮箱,2改为你的授权码,然后使用python face.py运行即可看到效果

12

注意:

  • 发邮件的话最好自己邮箱发送给自己邮箱,因为测试发现如果使用哦网易邮箱发邮件给QQ邮箱一段时间内超过一定次数会直接封禁,并且不能在文本中插入图片

  • 由于没办法在文中放入其他文件,我已把项目上传到了github上,项目中也是需要修改网易云邮箱和授权码的,还有人脸画框是被注释掉的最终版本,所以不会看到下面树莓派中人脸画框的效果,但是识别到人脸还是依旧可以发送的。

    git cloen https://github.com/Ascotbe/Hacker-program.git
    #下载下来后进入下面文件夹运行即可
    cd RaspberryPiBot

树莓派中显示效果

11

邮箱中效果如下

1585642833803

点进邮件查看内容,下面的图片是动图

13

然后我们查看压缩包内容,确实为人脸检测截图的图片

14

测试成功后注释掉这几行代码,可以减少CPU的消耗

# 画矩形框
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 显示视频
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 关闭摄像头设备
video_capture.release()

接着我们结束运行中python脚本,然后使用如下命令重启它

#后台运行
nohup python bot.py &

利用QQbot通讯

由于树莓派的是使用ARM架构的CPU导致不支持wine 技术,所以如果你是X86架构的机器来监控的话可以参考如下文档食用,这边就不在概述(浪费了我个把星期倒腾

https://www.ascotbe.com/Medusa/Documentation/#/Bot

利用短信通讯

首先需要去官网注册个账号https://pushed.co,然后在官网创建开发者模板,并且在你手机上下载他们的APP后登录,由于这个每个月限定1W条通知,超过的需要付费,感兴趣的可以自行挖掘,这边就不图文讲解了

接着使用如下脚本就能发送消息了

# !/usr/bin/python3
import requests

payload = {
"app_key": "APP_KEY",#你开发者面板里面可以找到
"app_secret": "APP_SECRET",#你开发者面板里面可以找到
"target_type": "app",#由于我们是发送到手机上所以类型为app
"content": "警戒警戒!莎莎检测到有人入侵!数据以保存喵~"
}

r = requests.post("https://api.pushed.co/1/push", data=payload)

最终效果如下图

1585647065444

后记

终于填上了自己挖的坑之一,可以去填其他的坑了23333,不过你们没发现这个只能检测人脸,而无法分辨这张脸是谁吗,这样如果自己进来也会给你发邮件是不是,如果有时间的话,就再肝一篇人脸识别的文章,可以检测检测你是谁,你的颜值,你的年龄等等,如果没有的话你就当我前面没说。

参考文章

https://www.cnblogs.com/shizhengwen/p/8719062.html
https://tunm.top/archive/
https://www.ptorch.com/docs/6/opencv_video_display