前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >4步实现树莓派人脸识别、拍照与推送、舵机旋转

4步实现树莓派人脸识别、拍照与推送、舵机旋转

作者头像
小锋学长生活大爆炸
发布2022-03-29 13:39:17
6750
发布2022-03-29 13:39:17
举报
文章被收录于专栏:小锋学长生活大爆炸

大部分童鞋的树莓派是不是一直在吃灰呢?一直闲置着,倒不如用它做一个简易监控,如果检测到人脸后,就拍照上传到指定地方,或发消息提醒。

本内容来源于“基于树莓派的魔镜”,感兴趣的童鞋可以点击观看:演示视频和教程

先看效果吧:

准备材料:

能用的树莓派、树莓派专用摄像头或USB摄像头、网线(稳定点)、LED灯可选

实现步骤:

1、安装OpenCV。可参考视频:教程(三) 第三方库的安装

2、推送消息部分。我用的是免费的企业微信推送,需要注册一个企业微信(https://work.weixin.qq.com)。童鞋们也可以使用免费的Qmsg酱推送到QQServer酱推送到微信(免费的QQ微信消息推送机器人,想要不?)。

或者使用自己的服务器搭建一个图片上传和浏览网页,可参考视频:教程(五) 服务端部署

3、下载haarcascade_frontalface_alt.xml文件,编写主体代码。

下载链接:http://xfxuezhang.cn/WEB/SHARE/haarcascade_frontalface_alt.zip

代码语言:javascript
复制
import requests
import base64
import time
import cv2
#from matplotlib import pyplot as plt
import os
import random
import json
import RPi.GPIO as GPIO
import time

def carDetect(rootPath):
    cap = cv2.VideoCapture(0)  # 0为默认,1为第二个
    width = 512  #定义摄像头获取图像宽度
    height = 512   #定义摄像头获取图像长度
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)  #设置宽度
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)  #设置长度
    print(">> 摄像头打开:", cap.isOpened())
    while True:
        ret, frame = cap.read()  # 窗口名frame
        cv2.imshow('image', frame)
        cv2.waitKey(1)
        continue

    cap.release()  # 释放摄像头
    cv2.destroyWindow('frame')  # 删除窗口
    

# 向服务器上传图片
def uploadImg(filepath):
    url = 'http://xfxuezhang.cn/WEB/MagicMirror/upload_file.php'
    filename = filepath.split('/')[-1]
    if filename:
        files = {"file": (filename, open(filepath, "rb"), "image/png")}
        html = requests.post(url, files=files)
        print(">> 上传完成!")


def sendImgByCoolPush(imgName):
    msgUrl = 'https://qmsg.zendee.cn/send/d05e1f7acded6f948f3a61da9d9f7708?msg='
    imgUrl = 'http://xfxuezhang.cn/WEB/MagicMirror/images/'+imgName
    url = msgUrl + imgUrl
    requests.get(url)
    

# 人脸识别并截图(这里是主要入口函数)
def faces_video():
    """人脸识别并截图(这里是主要入口函数)"""
    haarcascade_path = r'data/haarcascades/haarcascade_frontalface_alt.xml'
    face_cascade = cv2.CascadeClassifier(haarcascade_path)  # 获取训练好的人脸的参数数据
    load_succeed = face_cascade.load(haarcascade_path)
    print('load haarcascade: ', load_succeed)               # 训练数据文件是否导入成功
    cap = cv2.VideoCapture(0)                # 0为默认,1为第二个
    width = 256  #定义摄像头获取图像宽度
    height = 256   #定义摄像头获取图像长度
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)  #设置宽度
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)  #设置长度
    print(">> 摄像头打开:", cap.isOpened())
    # last_time = ''
    last_time = int(time.time()) # s
    while True:
        ret, frame = cap.read()                             # 读取1帧摄像头图像
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)      # 图像矩阵
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1,
                                              minNeighbors=10,
                                              flags=cv2.CASCADE_DO_CANNY_PRUNING,  # cv2.CASCADE_SCALE_IMAGE,
                                              minSize=(20, 20)
                                              )
        if len(faces) > 0:
            print('faces: ', len(faces))
            for x, y, w, h in faces:
                cv2.rectangle(frame, (x, y), (x + w, y + w), (0, 255, 0), 2)  # 画矩形
            curr_time = int(time.time())  # s
            if curr_time-last_time > 2:
                # GPIO.output(26, GPIO.HIGH)
                # GPIO.output(12, GPIO.HIGH)
                # time.sleep(0.1)           # 100ms
                # GPIO.output(12, GPIO.LOW)
                last_time = curr_time
                imgName = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime())
                imgPath = os.getcwd() + '/img/'+imgName+'.jpg'
                cv2.imwrite(imgPath, frame)             # 保存图像
                print(imgName+" => 捕获到人脸,已保存照片")
                uploadImg(imgPath)
                sendImgByCoolPush(imgName+'.jpg') # send by coolpush
                # GPIO.output(26, GPIO.LOW)
            
        cv2.imshow('frame', frame)      # 显示图像
        key = cv2.waitKey(1) & 0xFF     # 等待键盘输入,延时为毫秒级
        if key == ord('q'):             # 按q退出
            break
    cap.release()                       # 释放摄像头
    cv2.destroyWindow('frame')          # 删除窗口


def GpioInit():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(26, GPIO.OUT) # LED
    GPIO.output(26, GPIO.LOW)
    GPIO.setup(12, GPIO.OUT) # BEEP
    GPIO.output(12, GPIO.LOW)


def setupSERVO():
    global pwm
    P_SERVO = 18 # GPIO端口号,根据实际修改
    fPWM = 50    # Hz (软件PWM方式,频率不能设置过高)
    GPIO.setup(P_SERVO, GPIO.OUT)
    pwm = GPIO.PWM(P_SERVO, fPWM)
    pwm.start(0)


def setDirection(direction):
    global pwm
    duty = 10 / 180 * direction + 2
    pwm.ChangeDutyCycle(duty)
    print("direction =", direction, "-> duty =", duty)
    time.sleep(1) #等待控制周期结束
    pwm.ChangeDutyCycle(0)   #清空占空比,这句是防抖关键句,如果没有这句,舵机会狂抖不止


def waitForInput():
    while True:
        try:
            val = input("输入数值来改变舵机的转向(0~180): ").strip()
            if val:
                val = int(val)
                if 0 <= val <= 180:
                    setDirection(val)
        except Exception as e:
            print("waitForInput: ", e)
    
from threading import Thread

if __name__ == '__main__':
    GpioInit()
    setupSERVO()
    setDirection(90)
    try:
        th = Thread(target=waitForInput)
        th.setDaemon(True)
        th.start()
        faces_video()
    except Exception as e:
        print("main: ", e)
        GPIO.output(26, GPIO.LOW) #LED
        GPIO.output(12, GPIO.LOW) # BEEP
        setDirection(90)
    GPIO.cleanup() 

4、运行代码!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/01/01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档