【优秀课设】基于OpenCV-Python的树莓派人脸识别及89C52单片机控制系统设计(指定照片进行识别、遍历目录下所有照片依次识别)

基于OpenCV-Python的树莓派人脸识别及89C52单片机控制系统设计
(指定照片进行识别)

前言

参照之前的文章所改进 增加视频随时标注功能

blog.csdn.net/weixin_53403301/article/details/118005313

blog.csdn.net/weixin_53403301/article/details/117464715

资源:

download.csdn.net/download/weixin_53403301/66919590

新增功能链接

blog.csdn.net/weixin_53403301/article/details/119422635

基于OpenCV的Python人脸识别、检测、框选(遍历目录下所有照片依次识别 视频随时标注)

最新功能:(遍历目录下所有图像进行识别)

blog.csdn.net/weixin_53403301/article/details/119422635

展示

先上几个图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

直接上代码:

# -*- coding: utf-8 -*-
"""
Created on Mon May 31 23:39:19 2021

@author: ZHOU
"""

# -*- coding: utf-8 -*-

import tkinter as tk # 调用窗口tk
from tkinter import ttk
from tkinter.filedialog import *
import tkinter.messagebox
from PIL import Image, ImageTk # 调用图像处理库pillow
import api_face # 调用本地函数库 用于登入外部机器学习库并调用人脸识别函数
import cv2 # 调用OpenCV图像处理库
import threading # 调用threading多线程运行库
import time # 调用系统时间戳库
import RPi.GPIO as GPIO # 调用树梅派的Python环境GPIO口库
import matplotlib.pyplot as plt # 调用matplotlib绘图库
plt.rcParams['font.sans-serif'] = ['simhei'] # 载入字体

#print('请输入需录入的人脸图片路径/文件名:')
#pic_name=input()

#GPIO口预设 程序开始 23 24为高电平
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) # 设置BCM模式
# GPIO.setup(25, GPIO.OUT) # 设置GPIO25为输出
# GPIO.output(25, GPIO.LOW)
GPIO.setup(23, GPIO.OUT) # 设置23为输出
GPIO.output(23, GPIO.HIGH) # 设置为高电平
GPIO.setup(24, GPIO.OUT)
GPIO.output(24, GPIO.HIGH)
# GPIO.cleanup() # 清空GPIO口配置

#定义录入人脸后树梅派GPIO口的输出 全为高电平
def LED_S():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
#     GPIO.setup(25, GPIO.OUT)
#     GPIO.output(25, GPIO.HIGH)
    GPIO.setup(23, GPIO.OUT)
    GPIO.output(23, GPIO.HIGH)
    GPIO.setup(24, GPIO.OUT)
    GPIO.output(24, GPIO.HIGH)
    
#定义成功时的输出 23低电平 24高电平 [24:23]=10
def LED_T():

    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
#     GPIO.setup(25, GPIO.OUT)
    GPIO.setup(23, GPIO.OUT)
    GPIO.output(23, GPIO.LOW)
    GPIO.setup(24, GPIO.OUT)
    GPIO.output(24, GPIO.HIGH)
#    time.sleep(3)
#     for i in range(0, 3):
#         GPIO.output(25, GPIO.HIGH)
#         time.sleep(0.5)
#         GPIO.output(25, GPIO.LOW)
#         time.sleep(0.5)

    LED_S() # 重新恢复为开始状态

#定义失败时的输出 23高电平 24低电平 [24:23]=01
def LED_F():

    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
#     GPIO.setup(25, GPIO.OUT)
    GPIO.setup(23, GPIO.OUT)
    GPIO.output(23, GPIO.HIGH)
    GPIO.setup(24, GPIO.OUT)
    GPIO.output(24, GPIO.LOW)
#    time.sleep(3)
#     for i in range(0, 15):
#         GPIO.output(25, GPIO.HIGH)
#         time.sleep(0.1)
#         GPIO.output(25, GPIO.LOW)
#         time.sleep(0.1)

    LED_S() # 重新恢复为开始状态

# 利用matplotlib显示图片函数
def pshow(words,picture):
    plt.imshow(picture[:,:,::-1])   # 将读取的图片以RGB转换为BGR
    plt.title(words), plt.xticks([]), plt.yticks([])
    plt.show() # 显示图片
    
    
class Login(ttk.Frame): # 定义窗口大类
    def __init__(self, win):
        ttk.Frame.__init__(self, win)
        frame0 = ttk.Frame(self)
        frame1 = ttk.Frame(self)
        win.title("人脸识别")
        win.minsize(1020, 620)
        self.center_window()    # 执行中置窗口函数
        self.thread_run = None 	# 赋值 线程1默认关闭
        self.thread_run2 = None 	# 线程2默认关闭
        self.camera = None 	# 摄像头默认关闭
 
        #定义tk窗口属性
        
        #self.pilImage = Image.open("img/start.png")
        #self.tkImage = ImageTk.PhotoImage(image=self.pilImage)
        #self.image_ctl = tk.Label(frame0, image=self.tkImage)
        #self.image_ctl.pack()
 
        frame0.pack(side=TOP, fill=tk.Y, expand=1)
        frame1.pack(side=TOP, fill=tk.Y, expand=1)
 
        self.facer = ttk.Label(frame1, text='', font=('Times', '20')) # 字体
        self.facer.pack()
        
        def filefound(): # 定义获取图片路径的函数
            filepath= askopenfilename() # 获取文件路径
            pic_name=filepath
            self.pic_path2 = pic_name # 赋值给图像2
            pic_img=cv2.imread(self.pic_path2)
            #cv2.imshow('所选人像图片',pic_img)
            #pshow('所选人像图片',pic_img) # 显示所选图片
            pic_xz = pic_img.shape # 计算图像大小
            pic_h=pic_xz[0] # 得出图片高度
            pic_w=pic_xz[1] # 得出图片宽度
            turn_w=pic_w*500/pic_h # 限制最大高度为500 以防窗口过小不完全显示 等比例转换宽度
            turn_w=int(turn_w)
            print('人像图像大小(高 宽):',pic_h,pic_w)
            print ('路径:',filepath)
            # 在tk窗口中显示所选图片
            self.pilImage = Image.open(self.pic_path2)            
            self.photo = self.pilImage.resize((turn_w,500)) # 限制最大高度为500 等比缩放显示
            self.tkImage = ImageTk.PhotoImage(image=self.photo)
            self.image_ctl = tk.Label(frame0, image=self.tkImage)
            self.image_ctl.pack()
            LED_S() # GPIO口开始函数
            #e.delete(0, END)  # 将输入框里面的内容清空
            #e.insert(0, filepath)
        
        #button2=Button(frame1,text="button2",command=filefound).grid(row=0,column=3)
        # 按钮1 调用filefound函数 获取选择图片的路径 并赋值给self.pic_path2 输出图像
        self.face_button1 = ttk.Button(frame1, text="1. 选择人像图片", width=15, command=filefound)
        self.face_button1.pack(side=TOP)        
        # 按钮2 调用摄像头函数
        self.url_face_button = ttk.Button(frame1, text="2. 使用相机识别", width=15, command=self.cv_face)
        self.url_face_button.pack(side=TOP)
        #self.file_pic_button = ttk.Button(frame1, text="本地文件识别", width=15, command=self.file_pic)
        #self.file_pic_button.pack(side=TOP)
 
        self.pack(fill=tk.BOTH, expand=tk.YES, padx="10", pady="10")
 
    #使弹出的窗体处于屏幕的中间位置
    def center_window(self):
        screenwidth = log.winfo_screenwidth()	# 获取屏幕分辨率宽
        screenheight = log.winfo_screenheight()	# 获取屏幕分辨率高
        log.update()	# 更新窗口
        width = log.winfo_width()	# 重新赋值
        height = log.winfo_height()
        size = '+%d+%d' % ((screenwidth - width)/2, (screenheight - height)/2)
        # 重新赋值大小 大小为屏幕大小/2
        log.geometry(size) 	# 以新大小定义窗口
 
#    def file1(self):
#        self.pic_path = askopenfilename(title="选择识别图片", filetypes=[("jpg图片", "*.jpg"), ("png图片", "*.png")])
 
    def cv_face(self):   # 调用摄像头函数
        if self.thread_run:
            if self.camera.isOpened(): # 如果已经打开则关闭
                self.camera.release()
                print("关闭摄像头")
                self.camera = None
                self.thread_run = False
            return
        if self.camera is None: # 如果没有摄像头则尝试打开
            self.camera = cv2.VideoCapture(1) # 利用OpenCV调用外摄像头
            if not self.camera.isOpened(): # 如果没有打开 则调用内摄像头
                self.camera = None
                print("没有外置摄像头")
                self.camera = cv2.VideoCapture(0) # 用OpenCV调用内摄像头
                if not self.camera.isOpened(): # 如果没有打开 则打开失败
                    print("没有内置摄像头")
                    tkinter.messagebox.showinfo('警告', '摄像头打开失败!')
                    self.camera = None
                    return
                else:
                    print("打开内置摄像头")
            else:
                print("打开外置摄像头")
        self.thread = threading.Thread(target=self.video_thread) # 多线程函数执行摄像头运行函数
        self.thread.setDaemon(True)
        self.thread.start()
        self.thread_run = True
 
    def video_thread(self): # 开始摄像头运行
        self.thread_run = True # 多线程1开启
        self.thread2 = threading.Thread(target=self.video_pic)
        self.thread2.setDaemon(True)
        self.thread2.start()
        self.thread_run2 = True
        while self.thread_run: # 循环一直调用摄像头
            _, img_bgr = self.camera.read() # 以bgr格式读取摄像头内的截图
            gray = cv2.cvtColor(img_bgr,cv2.COLOR_BGR2GRAY) # 灰度转换
            # 在CV官方机器学习库内加载人脸识别分类器                
            # Python\Python38-32\Lib\site-packages\cv2\data  这个目录下也有
            classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
            color = (0,255,0) # 绿色线
            # 识别器进行识别
            faceRects = classifier.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=3,minSize=(32, 32))
            # 识别器返回一个列表, 里面是每个识别出的人脸的区域, 左上和右下定点的坐标
            # print(faceRects)  #[[113  42  60  60]]    前两个值是左上定点的xy坐标,第三个是width 宽度对应y的变化, 另一个就是x的

            # 判断识别结果集合长度
            if len(faceRects):
                for faceRect in faceRects:
                    x,y,w,h = faceRect
                    # 用矩形框选出人脸   最后一个参数2是框线宽度
                    cv2.rectangle(img_bgr,(x, y), (x + h, y + w), color, 2)  
            img = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) # 颜色转换
            im = Image.fromarray(img)
            w, h = im.size
            pil_image_resized = self.resize(w, h, im) # 调整大小函数
            self.imgtk = ImageTk.PhotoImage(image=pil_image_resized)
            self.image_ctl.configure(image=self.imgtk)
        print("结束运行")
 
    def video_pic(self): # 视频截图保存及框选函数
        self.thread_run2 = True     # 开启多线程
        predict_time = time.time() # 获得系统时间
        while self.thread_run2: # 循环读取
            if time.time() - predict_time > 2: #每2s读取一次摄像头截图
                print("正在识别中")
                _, img_bgr = self.camera.read() # 读取摄像头图像
                cv2.imwrite("tmp/test.jpg", img_bgr) #利用cv写入到tmp/test.jpg路径下
                test_pic=cv2.imread('tmp/test.jpg') # 重新读取截图
                #pshow('识别截图',test_pic) # 显示截图
                
                # 图像路径 我用的相对路径
                face_mark = 'tmp/test.jpg'
                # 读取截图
                faceImg = cv2.imread(face_mark)
                # 转换灰色
                gray = cv2.cvtColor(faceImg,cv2.COLOR_RGB2GRAY) # 由于tmp/test.jpg路径下的已经转换成RGB保存 所以不用再进行BGR转换

                # 在CV官方机器学习库内加载人脸识别分类器                
                # Python\Python38-32\Lib\site-packages\cv2\data  这个目录下也有
                classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
                color = (0,255,0) # 绿色线

                # 识别器进行识别
                faceRects = classifier.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=3,minSize=(32, 32))
                # 识别器返回一个列表, 里面是每个识别出的人脸的区域, 左上和右下定点的坐标
                # print(faceRects)  #[[113  42  60  60]]    前两个值是左上定点的xy坐标,第三个是width 宽度对应y的变化, 另一个就是x的

                # 判断识别结果集合长度
                if len(faceRects):
                    for faceRect in faceRects:
                        x,y,w,h = faceRect
                        # 用矩形框选出人脸   最后一个参数2是框线宽度
                        cv2.rectangle(faceImg,(x, y), (x + h, y + w), color, 2)
        

                #pshow('识别结果',faceImg)    # 输出框选结果图像并显示 
                cv2.imwrite("tmp/test2.jpg", faceImg)
                self.pic_path = "tmp/test.jpg" # 重新读取摄像头截图
#                self.pilImage = Image.open(self.pic_path)
#                self.tkImage = ImageTk.PhotoImage(image=self.pilImage)
#                self.image_ctl = tk.Label(frame0, image=self.tkImage)
#                self.image_ctl.pack()
                try:
                    self.file_pic() #执行识别函数
                except:
                    pass
                predict_time = time.time()      # 读取时间
                print("识别结束")
                
                # 看门狗程序(调试用)
                # 防止程序关闭时进入死循环跑飞
                #print('请输入任意值以继续,否则请关闭窗口以终止程序:')
                #a=input()
                #print(a)
        pass
 
    def file_pic(self): #识别函数
        # self.pic_path2在按钮1中被赋值  self.pic_path为调用摄像头的图像
        facestr, result = api_face.facef(self.pic_path, self.pic_path2) # 调用api_face库的人脸识别函数
        self.facer.configure(text=str(facestr))
        #self.pic() # 对摄像头图像进行尺度变换
        if result > 80: #识别结果大于80
            LED_T() # GPIO口成功函数
            tkinter.messagebox.showinfo('提示', '人脸匹配成功!') # tk窗口提示
            print('人像图片路径:'+self.pic_path2) # 输出人像文件路径
            try:
                f=open("识别记录.txt","r")
                fi=open("识别记录.txt","a")
                txt=time.ctime()
                fi.write(txt+'   人像图片路径:   '+self.pic_path2+"     人脸匹配成功! \n")
                f.close()
                fi.close() # 将识别成功的记录保存在txt文件下
            except:
                f=open("识别记录.txt","w")
                txt=time.ctime()
                f.write(txt+'   人像图片路径:   '+self.pic_path2+"     人脸匹配成功! \n")
                f.close()
                
            
            
            # close_window()
            # os.system("python3 ./main.py")
        #if result < 20:
        #    tkinter.messagebox.showinfo('提示', '未检测到人脸!')
        else: # 小于80失败
            LED_F() # GPIO口失败函数
            tkinter.messagebox.showinfo('提示', '人脸匹配失败!')
        
 
#    def pic(self): # 对摄像头图像进行尺度变换
#        self.pilImage3 = Image.open(self.pic_path) # 用pillow读取摄像头图像
#        w, h = self.pilImage3.size # 计算大小赋值给宽 高
#        pil_image_resized = self.resize(w, h, self.pilImage3) # 调整大小函数
#        self.tkImage3 = ImageTk.PhotoImage(image=pil_image_resized) 
#        self.image_ctl.configure(image=self.tkImage3) # 输出结果
 
    def resize(self, w, h, pil_image): # 调整大小函数
        w_box = 1000 # 定义最大宽度
        h_box = 500 # 最大高度
        f1 = 1.0*w_box/w # 最大值/真实值
        f2 = 1.0*h_box/h
        factor = min([f1, f2]) # 取最小值
        width = int(w*factor) # 用最小值*对应值 调整到最大定义值 等比调整另一个值
        height = int(h*factor)
        return pil_image.resize((width, height), Image.ANTIALIAS) # 输出调整

def close_window():
    print("已关闭人脸识别")
    if Login.thread_run:
        Login.thread_run = False
        Login.thread.join(2.0)
    log.destroy()
    

    
if __name__ == '__main__':
    log = tk.Tk()
 
    login = Login(log)
    # close,退出输出destroy
    log.protocol('清除窗口', close_window)
    # 进入消息循环
    log.mainloop()
    
    

若API出错 则改为

    'ID': '15050553',
    'API_KEY': 'rlRrtRL5oRdXGh71jgg1OmyN',
    'SECRET_KEY': 'dK5TpuTAZn2nw5eVpspZLmF5Qs1Uu8A1'
# -*- coding: utf-8 -*-
"""
Created on Mon May 31 23:40:16 2021

@author: ZHOU
"""

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests # 调用 requests的HTTP协议库
import os # 调用os多操作系统接口库
import base64 # 调用base64编码库
import json # 调用JavaScript Object Notation数据交换格式



 
ACCESS_TOKEN = ''
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #去掉文件名,返回目录 
 
# ID,KEY的配置信息
INFO_CONFIG = { 
    'ID': '15788358',
    'API_KEY': 'ohtGa5yYoQEZ8Try8lnL99UK',
    'SECRET_KEY': 'qaDjyuXkf5MZ28g5C8pwFngDZenhswC3'
}
 
# URL配置
URL_LIST_URL = {
    # ACCESS_TOKEN_URL用于获取ACCESS_TOKEN, POST请求,
    #  grant_type必须参数,固定为client_credentials,client_id必须参数,应用的API Key,client_secre 必须参数,应用的Secret Key.
    'ACCESS_TOKEN_URL': 'https://aip.baidubce.com/oauth/2.0/token?' + 'grant_type=client_credentials&client_id={API_KEYS}&client_secret={SECRET_KEYS}&'.format(
        API_KEYS=INFO_CONFIG['API_KEY'], SECRET_KEYS=INFO_CONFIG['SECRET_KEY']),
    # 登入人脸识别机器学习库
    'FACE_PLATE': 'https://aip.baidubce.com/rest/2.0/face/v3/match',
 
}
 
 
class AccessTokenSuper(object):
    pass
 
 
class AccessToken(AccessTokenSuper): # 定义登陆API大类
    def getToken(self):
        accessToken = requests.post(url=URL_LIST_URL['ACCESS_TOKEN_URL']) #登入网址
        accessTokenJson = accessToken.json()
        if dict(accessTokenJson).get('error') == 'invalid_client':
            return '获取accesstoken错误,请检查API_KEY,SECRET_KEY是否正确!'
        return accessTokenJson
 
 
ACCESS_TOKEN = AccessToken().getToken()['access_token']
 
LICENSE_PLATE_URL = URL_LIST_URL['FACE_PLATE'] + '?access_token={}'.format(ACCESS_TOKEN)
 
 
class faceSuper(object):
    pass
 
 
class face(faceSuper): # 定义图像输入大类
 
    def __init__(self, image=None, image2=None): # 定义初始化函数
        self.HEADER = {
            'Content-Type': 'application/json; charset=UTF-8',
        }
        if image is not None: 	# 没有图像1
            imagepath = os.path.exists(image)
            if imagepath == True:
                images = image
                with open(images, 'rb') as images:
                    img1 = base64.b64encode(images.read())
            else:
                print("图像1不存在")
                return
        if image2 is not None: 	# 没有图像2
            imagepath2 = os.path.exists(image2)
            if imagepath2 == True:
                images2 = image2
                with open(images2, 'rb') as images2:
                    img2 = base64.b64encode(images2.read())
            else:
                print("图像2不存在")
                return
        self.img = img1
        self.imgs = img2
        self.IMAGE_CONFIG1 = {"image": str(img1, 'utf-8'), "image_type": "BASE64"}
        self.IMAGE_CONFIG2 = {"image": str(img2, 'utf-8'), "image_type": "BASE64"}
        self.IMAGE_CONFIG = json.dumps([self.IMAGE_CONFIG1, self.IMAGE_CONFIG2])
 
    def postface(self):  # 定义从服务器进行数据获取函数
        if (self.img==None and self.imgs==None):
            return '图像不存在'
        face = requests.post(url=LICENSE_PLATE_URL, headers=self.HEADER, data=self.IMAGE_CONFIG)
        # 登陆服务器获取数据
        return face.json() 	# 输出结果
 
 
def facef(FA1, FA2): # 人脸识别逻辑函数
    testAccessToken = AccessToken() # 获取API配置
    testface = face(image=FA1, image2=FA2) # 赋值给图像输入大类
    result_json = testface.postface()  # 从服务器获取数据
    result = result_json['result']['score'] #输出结果
    print('人脸相似度:', result)
    if result > 80: # 识别结果大于80则成功
        
        print("人脸匹配成功!")        
#    if result < 20:
#        print("未检测到人脸!")
    else:
        
        print("人脸匹配失败!")
    return '人脸相似度:' + str(result), result # 输出字符串结果

单片机部分:

#include <reg52.h>
#define uint unsigned int 
#define uchar unsigned char

void delay(uint ms)		  //ÑÓʱ
{
 uint i,j;
 for(i=ms;i>0;i--)
 for(j=110;j>0;j--);
}
void main(void)
{
	EA=1;				//×ÜÖжϿªÆô
  EX0=1;				//ÍⲿÖжÏ1ÔÊÐí
  IT0=1;				//ÖжÏ1 ϽµÑØ´¥·¢
	EX1=1;
	IT1=1;
	P0=0xff;
	delay(50000);
}
void exter0()interrupt 0 //ÍⲿÖжÏ0
{
	P0=0x6d;  //ÏÔʾS successful
delay(3000);
	P0=0xff;
}
void exter1()interrupt 2 //ÍⲿÖжÏ1
{
	P0=0x71;  // ÏÔʾF failure
delay(3000);
	P0=0xff;
}

改进版:对目录下所有照片进行依次比对识别:

# -*- coding: utf-8 -*-
"""
Created on Mon May 31 23:39:19 2021

@author: ZHOU
"""

# -*- coding: utf-8 -*-

import tkinter as tk # 调用窗口tk
from tkinter import ttk
from tkinter.filedialog import *
import tkinter.messagebox
from PIL import Image, ImageTk # 调用图像处理库pillow
import api_face # 调用本地函数库 用于登入外部机器学习库并调用人脸识别函数
import cv2 # 调用OpenCV图像处理库
import threading # 调用threading多线程运行库
import time # 调用系统时间戳库
import RPi.GPIO as GPIO # 调用树梅派的Python环境GPIO口库
import matplotlib.pyplot as plt # 调用matplotlib绘图库
plt.rcParams['font.sans-serif'] = ['simhei'] # 载入字体

#print('请输入需录入的人脸图片路径/文件名:')
#pic_name=input()

#GPIO口预设 程序开始 23 24 25为低电平
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) # 设置BCM模式
# GPIO.setup(25, GPIO.OUT) # 设置GPIO25为输出
# GPIO.output(25, GPIO.LOW)
GPIO.setup(23, GPIO.OUT)
GPIO.output(23, GPIO.HIGH)
GPIO.setup(24, GPIO.OUT)
GPIO.output(24, GPIO.HIGH)
# GPIO.cleanup() # 清空GPIO口配置

#定义开始识别后树梅派GPIO口的输出 全为高电平
def LED_S():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
#     GPIO.setup(25, GPIO.OUT)
#     GPIO.output(25, GPIO.HIGH)
    GPIO.setup(23, GPIO.OUT)
    GPIO.output(23, GPIO.HIGH)
    GPIO.setup(24, GPIO.OUT)
    GPIO.output(24, GPIO.HIGH)
    
#定义成功时的输出 25输出周期为1的频闪 3s后结束 23高电平 24低电平 [24:23]=0x1
def LED_T():

    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
#     GPIO.setup(25, GPIO.OUT)
    GPIO.setup(23, GPIO.OUT)
    GPIO.output(23, GPIO.LOW)
    GPIO.setup(24, GPIO.OUT)
    GPIO.output(24, GPIO.HIGH)
#    time.sleep(3)
#     for i in range(0, 3):
#         GPIO.output(25, GPIO.HIGH)
#         time.sleep(0.5)
#         GPIO.output(25, GPIO.LOW)
#         time.sleep(0.5)

    LED_S()

#定义失败时的输出 25输出周期为0.2的频闪 3s后结束 23低电平 24高电平 [24:23]=0x2
def LED_F():

    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
#     GPIO.setup(25, GPIO.OUT)
    GPIO.setup(23, GPIO.OUT)
    GPIO.output(23, GPIO.HIGH)
    GPIO.setup(24, GPIO.OUT)
    GPIO.output(24, GPIO.LOW)
#    time.sleep(3)
#     for i in range(0, 15):
#         GPIO.output(25, GPIO.HIGH)
#         time.sleep(0.1)
#         GPIO.output(25, GPIO.LOW)
#         time.sleep(0.1)

    LED_S()

# 利用matplotlib显示图片函数
def pshow(words,picture):
    plt.imshow(picture[:,:,::-1])   # 将读取的图片以RGB转换为BGR
    plt.title(words), plt.xticks([]), plt.yticks([])
    plt.show() # 显示图片
    
    
class Login(ttk.Frame): # 定义窗口大类
    def __init__(self, win):
        ttk.Frame.__init__(self, win)
        frame0 = ttk.Frame(self)
        frame1 = ttk.Frame(self)
        win.title("人脸识别")
        win.minsize(1240, 620)
        self.center_window()    # 执行中置窗口函数
        self.thread_run = None 	# 赋值 线程1默认关闭
        self.thread_run2 = None 	# 线程2默认关闭
        self.camera = None 	# 摄像头默认关闭
 
        #定义tk窗口属性
        
        #self.pilImage = Image.open("img/start.png")
        #self.tkImage = ImageTk.PhotoImage(image=self.pilImage)
        #self.image_ctl = tk.Label(frame0, image=self.tkImage)
        #self.image_ctl.pack()
 
        frame0.pack(side=TOP, fill=tk.Y, expand=1)
        frame1.pack(side=TOP, fill=tk.Y, expand=1)
 
        self.facer = ttk.Label(frame1, text='', font=('Times', '20')) # 字体
        self.facer.pack()
        

#        def filefound(): # 定义获取图片路径的函数
#            filepath= askopenfilename() # 获取文件路径
#            pic_name=filepath
#            self.pic_path2 = pic_name # 赋值给图像2
#            
#            pshow('所选人像图片',pic_img) # 显示所选图片
        self.pic_path3='./star.png'
#        pic_img=cv2.imread(self.pic_path3)
#        pic_xz = pic_img.shape # 计算图像大小
#        pic_h=pic_xz[0] # 得出图片高度
#        pic_w=pic_xz[1] # 得出图片宽度
#        turn_w=pic_w*500/pic_h # 限制最大高度为580 以防窗口过小不完全显示 等比例转换宽度
#        turn_w=int(turn_w)
#            print('人像图像大小(高 宽):',pic_h,pic_w)
#            print ('路径:',filepath)
#            # 在tk窗口中显示所选图片
        
        self.pilImage = Image.open(self.pic_path3)            
        self.photo = self.pilImage.resize((500,500)) # 限制最大高度为580 等比缩放显示
        self.tkImage = ImageTk.PhotoImage(image=self.photo)
        self.image_ctl = tk.Label(frame0, image=self.tkImage)
        self.image_ctl.pack()
#            #e.delete(0, END)  # 将输入框里面的内容清空
#            #e.insert(0, filepath)
#        
#        #button2=Button(frame1,text="button2",command=filefound).grid(row=0,column=3)
#        # 按钮1 调用filefound函数 获取选择图片的路径 并赋值给self.pic_path2 输出图像
#        self.face_button1 = ttk.Button(frame1, text="1. 选择人像图片", width=15, command=filefound)
#        self.face_button1.pack(side=TOP)        
        # 按钮2 调用摄像头函数
        self.url_face_button = ttk.Button(frame1, text="使用相机识别", width=15, command=self.cv_face)
        self.url_face_button.pack(side=TOP)
        #self.file_pic_button = ttk.Button(frame1, text="本地文件识别", width=15, command=self.file_pic)
        #self.file_pic_button.pack(side=TOP)
 
        self.pack(fill=tk.BOTH, expand=tk.YES, padx="10", pady="10")
 
    #使弹出的窗体处于屏幕的中间位置
    def center_window(self):
        screenwidth = log.winfo_screenwidth()	# 获取屏幕分辨率宽
        screenheight = log.winfo_screenheight()	# 获取屏幕分辨率高
        log.update()	# 更新窗口
        width = log.winfo_width()	# 重新赋值
        height = log.winfo_height()
        size = '+%d+%d' % ((screenwidth - width)/2, (screenheight - height)/2)
        # 重新赋值大小 大小为屏幕大小/2
        log.geometry(size) 	# 以新大小定义窗口
 
#    def file1(self):
#        self.pic_path = askopenfilename(title="选择识别图片", filetypes=[("jpg图片", "*.jpg"), ("png图片", "*.png")])
 
    def cv_face(self):   # 调用摄像头函数
        LED_S()
        if self.thread_run:
            if self.camera.isOpened(): # 如果已经打开则关闭
                self.camera.release()
                print("关闭摄像头")
                self.camera = None
                self.thread_run = False
            return
        if self.camera is None: # 如果没有摄像头则尝试打开
            self.camera = cv2.VideoCapture(1) # 利用OpenCV调用外摄像头
            if not self.camera.isOpened(): # 如果没有打开 则调用内摄像头
                self.camera = None
                print("没有外置摄像头")
                self.camera = cv2.VideoCapture(0) # 用OpenCV调用内摄像头
                if not self.camera.isOpened(): # 如果没有打开 则打开失败
                    print("没有内置摄像头")
                    tkinter.messagebox.showinfo('警告', '摄像头打开失败!')
                    self.camera = None
                    return
                else:
                    print("打开内置摄像头")
            else:
                print("打开外置摄像头")
        self.thread = threading.Thread(target=self.video_thread) # 多线程函数执行摄像头运行函数
        self.thread.setDaemon(True)
        self.thread.start()
        self.thread_run = True
 
    def video_thread(self): # 开始摄像头运行
        self.thread_run = True # 多线程1开启
        self.thread2 = threading.Thread(target=self.video_pic)
        self.thread2.setDaemon(True)
        self.thread2.start()
        self.thread_run2 = True
        while self.thread_run: # 循环一直调用摄像头
            _, img_bgr = self.camera.read() # 以bgr格式读取摄像头内的截图 
            gray = cv2.cvtColor(img_bgr,cv2.COLOR_BGR2GRAY) # 灰度转换
            # 在CV官方机器学习库内加载人脸识别分类器                
            # Python\Python38-32\Lib\site-packages\cv2\data  这个目录下也有
            classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
            color = (0,255,0) # 绿色线
            # 识别器进行识别
            faceRects = classifier.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=3,minSize=(32, 32))
            # 识别器返回一个列表, 里面是每个识别出的人脸的区域, 左上和右下定点的坐标
            # print(faceRects)  #[[113  42  60  60]]    前两个值是左上定点的xy坐标,第三个是width 宽度对应y的变化, 另一个就是x的

            # 判断识别结果集合长度
            if len(faceRects):
                for faceRect in faceRects:
                    x,y,w,h = faceRect
                    # 用矩形框选出人脸   最后一个参数2是框线宽度
                    cv2.rectangle(img_bgr,(x, y), (x + h, y + w), color, 2)                 
            img = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) # 颜色转换
            im = Image.fromarray(img)
            w, h = im.size
            pil_image_resized = self.resize(w, h, im) # 调整大小函数
            self.imgtk = ImageTk.PhotoImage(image=pil_image_resized)
            self.image_ctl.configure(image=self.imgtk)
        print("结束运行")
 
    def video_pic(self): # 视频截图保存及框选函数
        dir_name='./img' # 给出图片目录路径
        fileimg_list = [] # 建立列表型图片列表
        fileimg_list=os.listdir(dir_name) # 获取目录下文件名
        file_num=len(fileimg_list) # 获取列表长度
        fileimg_num=0   # 定义文件序号初始值为0
        self.thread_run2 = True     # 开启多线程
        predict_time = time.time() # 获得系统时间
        while self.thread_run2: # 循环读取
            if time.time() - predict_time > 0.1: #每0.1s读取一次摄像头截图
                print("正在识别中")
                _, img_bgr = self.camera.read() # 重新读取摄像头图像
                cv2.imwrite("tmp/test.jpg", img_bgr) #利用cv写入到tmp/test.jpg路径下
#                test_pic=cv2.imread('tmp/test.jpg') # 重新读取截图
#                pshow('识别截图',test_pic) # 显示截图
#                
#                # 图像路径 我用的相对路径
#                face_mark = 'tmp/test.jpg'
#                # 读取截图
#                faceImg = cv2.imread(face_mark)
#                # 转换灰色
#                gray = cv2.cvtColor(faceImg,cv2.COLOR_RGB2GRAY) # 由于tmp/test.jpg路径下的已经转换成RGB保存 所以不用再进行BGR转换
#
#                # 在CV官方机器学习库内加载人脸识别分类器                
#                # Python\Python38-32\Lib\site-packages\cv2\data  这个目录下也有
#                classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
#                color = (0,255,0) # 绿色线
#
#                # 识别器进行识别
#                faceRects = classifier.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=3,minSize=(32, 32))
#                # 识别器返回一个列表, 里面是每个识别出的人脸的区域, 左上和右下定点的坐标
#                # print(faceRects)  #[[113  42  60  60]]    前两个值是左上定点的xy坐标,第三个是width 宽度对应y的变化, 另一个就是x的
#
#                # 判断识别结果集合长度
#                if len(faceRects):
#                    for faceRect in faceRects:
#                        x,y,w,h = faceRect
#                        # 用矩形框选出人脸   最后一个参数2是框线宽度
#                        cv2.rectangle(faceImg,(x, y), (x + h, y + w), color, 2)
#        
#                
#                pshow('识别结果',faceImg)    # 输出框选结果图像并显示
#                cv2.imwrite("tmp/test2.jpg", faceImg)
                self.pic_path = "tmp/test.jpg" # 重新读取摄像头截图
#                self.pilImage = Image.open(self.pic_path)
#                self.tkImage = ImageTk.PhotoImage(image=self.pilImage)
#                self.image_ctl = tk.Label(frame0, image=self.tkImage)
#                self.image_ctl.pack()
                try:

                
                    if fileimg_num<file_num: #当文件序号小于总列表长度时
                        #print(fileimg_num)
                        #img=cv2.imread(dir_name + '/' + fileimg_list[fileimg_num])    
                        #pshow(fileimg_list[fileimg_num],img)
                        self.pic_path2 = dir_name + '/' + fileimg_list[fileimg_num] # 给出pic_path2的值为目录名+/+文件名
                        #print(self.pic_path2)
#                        self.pic_path2='./img/111.jpg'
                        facestr, result = api_face.facef(self.pic_path, self.pic_path2) # 调用api_face库的人脸识别函数
                        self.facer.configure(text=str(facestr))
                                #self.pic() # 对摄像头图像进行尺度变换
                        if result > 80: #识别结果大于80
                            LED_T() # 执行LED成功函数
                            tkinter.messagebox.showinfo('提示', '人脸匹配成功!') # tk窗口提示
                            print('人像图片文件名:'+fileimg_list[fileimg_num]) # 输出人像文件文件名
                            try:
                                f=open("识别记录.txt","r")
                                fi=open("识别记录.txt","a")
                                txt=time.ctime()
                                fi.write(txt+'   人像图片路径:   '+fileimg_list[fileimg_num]+"     人脸匹配成功! \n")
                                f.close()
                                fi.close() # 将识别成功的记录保存在txt文件下
                            except:
                                f=open("识别记录.txt","w")
                                txt=time.ctime()
                                f.write(txt+'   人像图片路径:   '+fileimg_list[fileimg_num]+"     人脸匹配成功! \n")
                                f.close()
                                        
                                    
                                    
                                    # close_window()
                                    # os.system("python3 ./main.py")
                                #if result < 20:
                                #    tkinter.messagebox.showinfo('提示', '未检测到人脸!')
                            break
                        else: # 小于80失败
                            fileimg_num=fileimg_num+1 # 文件序号+1
                                
                            
                    else: # 超出文件列表长度
                        LED_F() # 执行LED失败函数
                        tkinter.messagebox.showinfo('提示', '人脸匹配失败!')
                        break
                except:
                    pass
                predict_time = time.time()      # 读取时间          
                print("识别结束")
                
                # 看门狗程序(调试用)
                # 防止程序关闭时进入死循环跑飞
                #print('请输入任意值以继续,否则请关闭窗口以终止程序:')
                #a=input()
                #print(a)
        pass
 
#    def file_pic(self): #识别函数
#        dir_name='./img'
#        fileimg_list = []
#        fileimg_list=os.listdir(dir_name)
#        file_num=len(fileimg_list)
#        fileimg_num=0   
#        while True:
#            if fileimg_num<file_num:
#                print(fileimg_num)
#                img=cv2.imread(dir_name + '/' + fileimg_list[fileimg_num])    
#                pshow(fileimg_list[fileimg_num],img)
#                self.pic_path2 = dir_name + '/' + fileimg_list[fileimg_num]
#                print(self.pic_path2)
##                self.pic_path2='./img/111.jpg'
#                facestr, result = api_face.facef(self.pic_path, self.pic_path2) # 调用api_face库的人脸识别函数
#                self.facer.configure(text=str(facestr))
#                        #self.pic() # 对摄像头图像进行尺度变换
#                if result > 80: #识别结果大于80
#                    tkinter.messagebox.showinfo('提示', '人脸匹配成功!') # tk窗口提示
#                    print('人像图片路径:'+self.pic_path2) # 输出人像文件路径
#                    try:
#                        f=open("识别记录.txt","r")
#                        fi=open("识别记录.txt","a")
#                        txt=time.ctime()
#                        fi.write(txt+'   人像图片路径:   '+self.pic_path2+"     人脸匹配成功! \n")
#                        f.close()
#                        fi.close() # 将识别成功的记录保存在txt文件下
#                    except:
#                        f=open("识别记录.txt","w")
#                        txt=time.ctime()
#                        f.write(txt+'   人像图片路径:   '+self.pic_path2+"     人脸匹配成功! \n")
#                        f.close()
#                                
#                            
#                            
#                            # close_window()
#                            # os.system("python3 ./main.py")
#                        #if result < 20:
#                        #    tkinter.messagebox.showinfo('提示', '未检测到人脸!')
#                        break
#                    else: # 小于80失败
#                        fileimg_num=fileimg_num+1
#                        
#                    
#            else:
#                tkinter.messagebox.showinfo('提示', '人脸匹配失败!')
#                break
        
        
 
#    def pic(self): # 对摄像头图像进行尺度变换
#        self.pilImage3 = Image.open(self.pic_path) # 用pillow读取摄像头图像
#        w, h = self.pilImage3.size # 计算大小赋值给宽 高
#        pil_image_resized = self.resize(w, h, self.pilImage3) # 调整大小函数
#        self.tkImage3 = ImageTk.PhotoImage(image=pil_image_resized) 
#        self.image_ctl.configure(image=self.tkImage3) # 输出结果
 
    def resize(self, w, h, pil_image): # 调整大小函数
        w_box = 1000 # 定义最大宽度
        h_box = 500 # 最大高度
        f1 = 1.0*w_box/w # 最大值/真实值
        f2 = 1.0*h_box/h
        factor = min([f1, f2]) # 取最小值
        width = int(w*factor) # 用最小值*对应值 调整到最大定义值 等比调整另一个值
        height = int(h*factor)
        return pil_image.resize((width, height), Image.ANTIALIAS) # 输出调整
 
 
def close_window():
    print("已关闭人脸识别")
    if Login.thread_run:
        Login.thread_run = False
        Login.thread.join(2.0)
    log.destroy()
    

    
if __name__ == '__main__':
    log = tk.Tk()
 
    login = Login(log)
    # close,退出输出destroy
    log.protocol('清除窗口', close_window)
    # 进入消息循环
    log.mainloop()

参考

blog.csdn.net/weixin_53403301/article/details/119422635

附录:列表的赋值类型和py打包

列表赋值

BUG复现

闲来无事写了个小程序 代码如下:

# -*- coding: utf-8 -*-
"""
Created on Fri Nov 19 19:47:01 2021

@author: 16016
"""

a_list = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
#print(len(a_list))
#b_list = ['','','','','','','','','','','','','','','','']
c_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
#for i in range(16):
if len(a_list):
    for j in range(16):
        a_list[j]=str(a_list[j])+'_'+str(j)
        print("序号:",j)
        print('a_list:\n',a_list)
        
        
        c_list[j]=a_list
        print('c_list[0]:\n',c_list[0])
        print('\n')
#        b_list[j]=a_list[7],a_list[8]
#        print(b_list[j])
        # 写入到Excel:
#print(c_list,'\n')    

我在程序中 做了一个16次的for循环 把列表a的每个值后面依次加上"_"和循环序号
比如循环第x次 就是把第x位加上_x 这一位变成x_x 我在输出测试中 列表a的每一次输出也是对的
循环16次后列表a应该变成[‘0_0’, ‘1_1’, ‘2_2’, ‘3_3’, ‘4_4’, ‘5_5’, ‘6_6’, ‘7_7’, ‘8_8’, ‘9_9’, ‘10_10’, ‘11_11’, ‘12_12’, ‘13_13’, ‘14_14’, ‘15_15’] 这也是对的

同时 我将每一次循环时列表a的值 写入到空列表c中 比如第x次循环 就是把更改以后的列表a的值 写入到列表c的第x位
第0次循环后 c[0]的值应该是[‘0_0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘10’, ‘11’, ‘12’, ‘13’, ‘14’, ‘15’] 这也是对的
但是在第1次循环以后 c[0]的值就一直在变 变成了c[x]的值
相当于把c_list[0]变成了c_list[1]…以此类推 最后得出的列表c的值也是每一项完全一样
我不明白这是怎么回事
我的c[0]只在第0次循环时被赋值了 但是后面它的值跟着在改变

如图:
在这里插入图片描述
第一次老出bug 赋值以后 每次循环都改变c[0]的值 搞了半天都没搞出来
无论是用appen函数添加 还是用二维数组定义 或者增加第三个空数组来过渡 都无法解决

代码改进

后来在我华科同学的指导下 突然想到赋值可以赋的是个地址 地址里面的值一直变化 导致赋值也一直变化 于是用第二张图的循环套循环深度复制实现了

代码如下:

# -*- coding: utf-8 -*-
"""
Created on Fri Nov 19 19:47:01 2021

@author: 16016
"""

a_list = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
#print(len(a_list))
#b_list = ['','','','','','','','','','','','','','','','']
c_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
#for i in range(16):
if len(a_list):
    for j in range(16):
        a_list[j]=str(a_list[j])+'_'+str(j)
        print("序号:",j)
        print('a_list:\n',a_list)
        
        
        for i in range(16):
            c_list[j].append(a_list[i])
        print('c_list[0]:\n',c_list[0])
        print('\n')
#        b_list[j]=a_list[7],a_list[8]
#        print(b_list[j])
        # 写入到Excel:
print(c_list,'\n')    

解决了问题

在这里插入图片描述

优化

第三次是请教了老师 用copy函数来赋真值

代码如下:

# -*- coding: utf-8 -*-
"""
Created on Fri Nov 19 19:47:01 2021

@author: 16016
"""

a_list = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
#print(len(a_list))
#b_list = ['','','','','','','','','','','','','','','','']
c_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
#for i in range(16):
if len(a_list):
    for j in range(16):
        a_list[j]=str(a_list[j])+'_'+str(j)
        print("序号:",j)
        print('a_list:\n',a_list)
        
        
        c_list[j]=a_list.copy()
        print('c_list[0]:\n',c_list[0])
        print('\n')
#        b_list[j]=a_list[7],a_list[8]
#        print(b_list[j])
        # 写入到Excel:
#print(c_list,'\n')    

同样能解决问题
在这里插入图片描述
最后得出问题 就是指针惹的祸!

a_list指向的是个地址 而不是值 a_list[i]指向的才是单个的值 copy()函数也是复制值而不是地址

如果这个用C语言来写 就直观一些了 难怪C语言是基础 光学Python不学C 遇到这样的问题就解决不了

C语言yyds Python是什么垃圾弱智语言

总结

由于Python无法单独定义一个值为指针或者独立的值 所以只能用列表来传送
只要赋值是指向一个列表整体的 那么就是指向的一个指针内存地址 解决方法只有一个 那就是将每个值深度复制赋值(子列表内的元素提取出来重新依次连接) 或者用copy函数单独赋值

如图测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
部分代码:

# -*- coding: utf-8 -*-
"""
Created on Sat Nov 20 16:45:48 2021

@author: 16016
"""

def text1():
    A=[1,2,3]
    B=[[],[],[]]
    for i in range(len(A)):
        A[i]=A[i]+i
        B[i]=A
        print(B)

def text2():
    A=[1,2,3]
    B=[[],[],[]]
    
    A[0]=A[0]+0
    B[0]=A
    print(B)
    A[1]=A[1]+1
    B[1]=A
    print(B)
    A[2]=A[2]+2
    B[2]=A
    print(B)
    
if __name__ == '__main__':
    text1()
    print('\n')
    text2()

py打包

Pyinstaller打包exe(包括打包资源文件 绝不出错版)

依赖包及其对应的版本号

PyQt5 5.10.1
PyQt5-Qt5 5.15.2
PyQt5-sip 12.9.0

pyinstaller 4.5.1
pyinstaller-hooks-contrib 2021.3

Pyinstaller -F setup.py 打包exe

Pyinstaller -F -w setup.py 不带控制台的打包

Pyinstaller -F -i xx.ico setup.py 打包指定exe图标打包

打包exe参数说明:

-F:打包后只生成单个exe格式文件;

-D:默认选项,创建一个目录,包含exe文件以及大量依赖文件;

-c:默认选项,使用控制台(就是类似cmd的黑框);

-w:不使用控制台;

-p:添加搜索路径,让其找到对应的库;

-i:改变生成程序的icon图标。

如果要打包资源文件
则需要对代码中的路径进行转换处理
另外要注意的是 如果要打包资源文件 则py程序里面的路径要从./xxx/yy换成xxx/yy 并且进行路径转换
但如果不打包资源文件的话 最好路径还是用作./xxx/yy 并且不进行路径转换

def get_resource_path(relative_path):
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, relative_path)
    return os.path.join(os.path.abspath("."), relative_path)

而后再spec文件中的datas部分加入目录
如:

a = Analysis(['cxk.py'],
             pathex=['D:\\Python Test\\cxk'],
             binaries=[],
             datas=[('root','root')],
             hiddenimports=[],
             hookspath=[],
             hooksconfig={},
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)

而后直接Pyinstaller -F setup.spec即可

如果打包的文件过大则更改spec文件中的excludes 把不需要的库写进去(但是已经在环境中安装了的)就行

这些不要了的库在上一次编译时的shell里面输出
比如:
在这里插入图片描述

在这里插入图片描述
然后用pyinstaller --clean -F 某某.spec

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
树莓派智能项目设计.pdf是一份关于利用树莓派进行智能产品开发的指南。其中介绍了如何搭建树莓派的软硬件环境,开发基于Python语言的应用程序,以及如何使用传感器、摄像头等模块实现智能控制及监测功能。 该指南主要分为三个部分: 第一部分介绍了树莓派及其相关硬件的基本知识,包括树莓派的型号、接口类型、扩展板、摄像头、传感器等等。同时介绍了如何为树莓派搭建开发环境,包括操作系统的安装,软件的配置等。 第二部分介绍了利用Python语言进行应用程序的开发。该部分包括Python语言的基础知识、GPIO编程及面向模块编程。通过学习这些知识,可以为树莓派开发出各种智能应用程序,如家庭自动化、智能监测、智能安全警报等。 第三部分则介绍了如何使用各种传感器、摄像头模块实现智能控制及监测功能。该部分详细介绍了如何使用温度传感器、湿度传感器、气体传感器、人体红外传感器、超声波传感器、智能摄像头等等模块,并且提供了相应的示例代码供读者学习。 该指南对于想要利用树莓派进行智能产品开发的爱好者和工程师来说,具有非常高的实用性和参考价值。通读该指南可以让读者深入了解树莓派的硬件架构和开发环境的搭建,同时学习到Python编程语言及各类传感器、摄像头模块的使用方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

网易独家音乐人Mike Zhou

光电帝国,光联万物!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值