调用百度人脸识别接口进行人脸识别-2

目标:

1.学习使用百度AI开放平台进行语音识别与语音合成

       百度AI有两种开发方式:REST, SDK;    本文使用的是SDK python进行开发

        文档地址:https://ai.baidu.com/docs#/Face-Detect-V3/top

2.将学到的内容:异常捕获,tkinter显示图像

  异常捕获十分方便程序开发时,当未每一个函数添加抛出异常时,可以方便判定错误出现的函数

3.生成exe格式可执行文件

  pyinstaller -F xxx.py 参考文档 https://blog.csdn.net/qq_35203425/article/details/78568141

解决pyinstaller打包发布后的exe文件打开控制台闪退的问题

       1)先打开一个cmd

       2)cd到你的exe文件目录

       3)输入    .\***.exe

4.python-Tkinter图形界面开发

  1.按钮Button   2.文本框 Text

5.cv2读取/写入 图像的中文路径问题

问题点:

1.文本框显示图像位置,无法进行调整

2.未使用多线程进行开发

3.开发界面后,文件保存路径要使用os创建路径,不能使用相对路径,也不能使用+路径+文件名(路径不存在时)(注意pycharm开发时可以使用)

界面:

代码:

from tkinter import *
from tkinter.filedialog import askopenfilename,askdirectory  #加载文件路径
import base64
import time,os
import numpy as np
from PIL import Image, ImageTk
import cv2
import math
import threading
import matplotlib.pyplot as plt
from aip import AipFace  #导入百度人脸识别SDK接口
class Face_Recognition():
    """
    开发人脸识别,SDK开发
    """
    def __init__(self):
        """ 你的 APPID AK SK """
        self.APP_ID = '17790554'
        self.API_KEY = 'OHa7m2I8i9sEzjAO7GTxr2p8'
        self.SECRET_KEY = 'cPkNxo5O0tOND97LjuDTAjRdHm0FCFRx'
        self.client = AipFace(self.APP_ID, self.API_KEY, self.SECRET_KEY)
        self.myWindow = Tk()

        self.expression={"none":"不笑","smile":"微笑","laugh":"大笑"}
        self.faceshape={"square": "正方形", "triangle":"三角形", "oval": "椭圆", "heart": "心形", "round": "圆形"}
        self.gender={	"male":"男性", "female":"女性"}
        self.race={	'yellow': '黄种人', 'white': '白种人', 'black':'黑种人', 'arabs': '阿拉伯人'}
        self.tag_l=0
        self.tag_r=0
        # self.threadlock=threading.Lock()
    def get_img(self):
        "加载图像"
        image=""
        path_name=""
        try:
            # 路径搜索
            self.path_name = askopenfilename(title="查找文件的路径", filetypes=[("图片格式", "*.jpg;*.jpeg;*.png;*.bmp")])
            with open(self.path_name, mode="rb") as f:
                img = f.read()
            self.image = str(base64.b64encode(img), encoding="utf-8")
        except:
            print("文件打开错误-1")
        else:
            print("图像打开成功")
        finally:
            print("加载图片程序结束")

    def result_analysis(self,result):
        "分析结果"
        my_string=[]
        position=[]
        if result['error_code']==0:
            for i in range(result['result']['face_num']):
                img_infor=result['result']['face_list'][i]
                string="估算年龄:{}\n样貌评分:{}\n表情:{},置信度:{}\n脸型:{},置信度:{}\n性别:{},置信度:{}\n人种:{},置信度:{}\n".format(
                    img_infor['age'],img_infor['beauty'],self.expression[img_infor['expression']['type']],img_infor['expression']['probability'],
                    self.faceshape[img_infor['face_shape']['type']],img_infor['face_shape']['probability'],
                    self.gender[img_infor['gender']['type']],img_infor['gender']['probability'],
                    self.race[img_infor['race']['type']],img_infor['race']['probability'])
                my_string.append(string)
                position.append([img_infor['location']])
            return my_string,position
    def img_show(self,path_name,imgname,analy_result,*position):
        #img=cv2.imread(path_name,0)  #无法读取中文路径的图像
        img = cv2.imdecode(np.fromfile(path_name, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
        # print(img)
        #print(position[0][0])
        if analy_result=='TRUE':
            position=position[0]
            x0, y0, w, h, r = position[0][0]['left'], position[0][0]['top'], position[0][0]['width'], position[0][0][
                'height'], position[0][0]['rotation'] * math.pi / 180
            x0, y0 = int(x0), int(y0)
            x1, y1 = int(x0 - h * math.sin(r)), int(y0 + h * math.cos(r))
            x2, y2 = int(x1 + w * math.cos(r)), int(y1 + w * math.sin(r))
            x3, y3 = int(x0 + w * math.cos(r)), int(y0 + w * math.sin(r))
            rect = [[x0, y0, x1, y1], [x1, y1, x2, y2], [x2, y2, x3, y3], [x0, y0, x3, y3]]
            #print(rect)
            for x_1, y_1, x_2, y_2 in rect:
                cv2.line(img, (x_1, y_1), (x_2, y_2), (0, 255, 0), 3)
        h,w=img.shape[:2]
        #print(h,w)
        if w<h:
            img=cv2.resize(img,(int(w*310/h),320))
        else:
            img = cv2.resize(img, ( 350,int(h * 350 / w)))
        path=os.path.join(os.getcwd(),'{}.png'.format(imgname))
        #cv2.imwrite(path, img)
        # cv2.imencode(".png", img)返回的是(True/False,图像数组)
        cv2.imencode(".png",img)[1].tofile(path)

    def face_detect(self,img):
        # 调用接口实现人脸识别
        imageType = "BASE64"
        options = {}
        options["face_field"] = "age,beauty,expression,face_shape,gender,race"
        options["max_face_num"] = 1
        options["face_type"] = "LIVE"
        options["liveness_control"] = "LOW"
        """ 带参数调用人脸检测 """
        # self.threadlock.acquire()
        self.result = self.client.detect(img, imageType, options)
        # self.threadlock.release()

    def face_reg(self):
        "人脸识别"
        self.get_img()
        try:
            # 线程调用导致线程中的变量不能直接访问
            # thread_1 = threading.Thread(target=self.face_detect, args=[self.image])
            # thread_1.start()
            self.face_detect(self.image)
        except:
            print("人脸识别错误")
        else:
            print("人脸识别调用成功")
            #print(self.result)
            if self.result['error_code']!=0:
                raise Exception(self.result['error_msg'])



    def face_inf_display1(self):
        "显示左侧人脸识别结果"
        self.tag_l = 0
        path = os.getcwd() + '/img_1.png'
        if os.path.exists(path):
            os.remove(path)
        self.text_lh.delete(1.0,END)
        self.text_ld.delete(1.0, END)
        #print("显示左侧人脸识别结果")
        try:
            self.face_reg()

            result_analysis, position = self.result_analysis(self.result)
            # 显示识别信息
            self.img_show(self.path_name, "img_1", "TRUE", position)
            img = Image.open(path)
            img = ImageTk.PhotoImage(img)
            # 显示图像时必须同时指定两个属性
            self.text_lh.image = img
            self.text_lh.image_create(END, image=img)
            self.tag_l = 1
        except Exception as errors:
            print("错误",errors)
            self.img_show(self.path_name, "img_1", "FALSE")
            img = Image.open(path)
            img = ImageTk.PhotoImage(img)
            # 显示图像时必须同时指定两个属性
            self.text_lh.image = img
            self.text_lh.image_create(END, image=img)
            self.tag_l = 0
            self.text_ld.insert('insert', "未检测到人脸!")
        else:
            print("左侧图像识别成功")
            self.text_ld.insert('insert', result_analysis[0])

    def face_inf_display2(self):
        "显示右侧人脸识别结果"
        #print("显示右侧人脸识别结果")
        path = os.getcwd() + '/img_2.png'
        if os.path.exists(path):
            os.remove(path)
        self.text_rh.delete(1.0, END)
        self.text_rd.delete(1.0, END)
        self.tag_r = 0
        try:
            self.face_reg()
            result_analysis, position = self.result_analysis(self.result)
            # 显示识别信息
            self.img_show(self.path_name, "img_2","TRUE", position)
            img = Image.open(path)
            img = ImageTk.PhotoImage(img)
            # 显示图像时必须同时指定两个属性
            self.text_rh.image = img
            self.text_rh.image_create(END, image=img)
            self.tag_r = 1
        except Exception as errors:
            print("错误",errors)
            self.img_show(self.path_name, "img_2","FALSE")
            img = Image.open(path)
            img = ImageTk.PhotoImage(img)
            # 显示图像时必须同时指定两个属性
            self.text_rh.image = img
            self.text_rh.image_create(END, image=img)
            self.tag_r = 0
            self.text_rd.insert('insert', "未检测到人脸!")
        else:
            print("右侧图像识别成功")
            self.text_rd.insert('insert', result_analysis[0])


    def result_comparison(self):
        "进行图像相似度对比"
        #print("进行图像相似度对比")
        self.text_m.delete(1.0, END)
        path1=os.getcwd() + '/img_1.png'
        path2 = os.getcwd() + '/img_2.png'
        if self.tag_r==1 and self.tag_l==1:
            result = self.client.match([
                {
                    'image': str(base64.b64encode(open(path1, 'rb').read()),encoding='utf-8'),
                    'image_type': 'BASE64',
                },
                {
                    'image': str(base64.b64encode(open(path2, 'rb').read()),encoding='utf-8'),
                    'image_type': 'BASE64',
                }
            ])
            if result['error_code']==0:
                score=result['result']['score']
                if score>80:
                    string="同一个人\n得分:{}".format(score)
                elif score<20:
                    string = "不是同一个人\n得分:{}".format(score)
                else:
                    string = "两个人相似\n得分:{}".format(score)
            #print(result)
            self.text_m.insert('insert',string)
        elif self.tag_r==0:
            print("右侧图像识别错误")
        elif self.tag_l==0:
            print("左侧图像识别错误")
    def interfacce(self):
        "绘制图像界面"
        "1.修改主界面标题,大小"
        self.myWindow.title('人脸识别演示程序')  # 修改窗口标题
        self.myWindow.geometry("950x600+350+100")  # 修改窗口大小 width*height+xoffset+yoffset

        "1.1左侧界面"

        self.text_lh = Text(self.myWindow, width=50, height=25)
        self.text_lh.anchor=CENTER
        self.text_lh.grid(row=0, column=0, rowspan=6, columnspan=6, sticky='EW', pady=5, padx=5)

        button1 = Button(self.myWindow, text='载入图像', command=self.face_inf_display1, width=10, height=1)
        button1.grid(row=6, column=5,sticky='EW', pady=5, padx=5)
        self.text_ld = Text(self.myWindow, width=50, height=10)
        self.text_ld.grid(row=7, column=0, rowspan=6, columnspan=6, sticky='EW', pady=5, padx=5)

        "1.2中间界面"
        button2 = Button(self.myWindow, text='人脸比对', command=self.result_comparison, width=8, height=1)
        button2.grid(row=0, column=6, sticky='EW', pady=1, padx=1)
        Label(self.myWindow, text='对比结果').grid(row=1, column=6, sticky='EW', pady=1, padx=1)
        self.text_m = Text(self.myWindow, width=30, height=4)
        self.text_m.grid(row=2, column=6, rowspan=1, columnspan=3, sticky='EW', pady=1, padx=1)
        "1.3右侧界面"
        self.text_rh = Text(self.myWindow, width=50, height=25)
        self.text_rh.grid(row=0, column=10, rowspan=6, columnspan=6, sticky='EW', pady=5, padx=5)
        button3 = Button(self.myWindow, text='载入图像', command=self.face_inf_display2, width=10, height=1)
        button3.grid(row=6, column=15, sticky='EW', pady=5, padx=5)
        self.text_rd = Text(self.myWindow, width=50, height=10)
        self.text_rd.grid(row=7, column=10, rowspan=6, columnspan=6, sticky='EW', pady=5, padx=5, ipady=15)


        # 启动主窗口的消息循环
        self.myWindow.mainloop()

if __name__ == '__main__':
    face=Face_Recognition()
    face.interfacce()
发布了109 篇原创文章 · 获赞 22 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_42233538/article/details/103192586