• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

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

武飞扬头像
小锋学长生活大爆炸
帮助1

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

学新通

先看效果吧:

学新通

学新通

学新通

准备材料:

    能用的树莓派、树莓派专用摄像头或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

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、运行代码!

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhhkijgh
系列文章
更多 icon
同类精品
更多 icon
继续加载