首页 > 编程语言 >基于OpenCV-Python实现人脸识别-----摄像头捕获人脸图像显示中文乱码问题

基于OpenCV-Python实现人脸识别-----摄像头捕获人脸图像显示中文乱码问题

时间:2024-08-27 11:50:30浏览次数:9  
标签:人脸识别 PIL img Python cv2 face 乱码 OpenCV 图像

基于OpenCV-Python实现人脸识别时,为了使图像上显示识别到人员的中文名字,做了几次尝试,使用PIL.Image和OpenCV图像格式相互转换解决:

使用OpenCV将图片灰度化,对加载的灰度化图使用分类器中的detectMultiScale()函数查找目标人脸,并使用for循环实现矩形框和圆形框框住查找到的人脸。再使用OpenCV中识别器face.LBPHFaceRecognizer()方法得到预测结果ids和置信度confidence

--------此时图像是OpenCV格式

# 加载训练数据集文件--加载识别器LBRHFaceRegnizer_create()
recogizer=cv2.face.LBPHFaceRecognizer_create() # 需要安装pip install opencv_contrib-python

def face_detect_demo(img):
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 图片灰度化---cv2.cvtColor()
    # 加载分类器--进行检测
    face_detector=cv2.CascadeClassifier('F:/Program Files/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')
    # face=face_detector.detectMultiScale(gray,1.1,5,cv2.CASCADE_SCALE_IMAGE,(100,100),(300,300))
    face=face_detector.detectMultiScale(gray) # 使用默认参数
    # face=face_datector.deteMultiScale(gray)  # 默认
    for x,y,w,h in face: # 将整张人脸框住(矩形框+圆形框)
        cv2.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2) # 绘制矩形框住识别的人脸
        cv2.circle(img,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=1) # 绘制圆框住识别的人脸
        # 人脸识别--预测和评分--recogizer.predict()输入参数是一个人脸图像,输出结果一个元组,包括预测结果ids和置信度confidence---取gray中矩形框住的部分
        ids,confidence=recogizer.predict(gray[y:y+h,x:x+w]) # 调用识别器cv2.face.LBPHFaceRecognizer中的predict()方法

--------使用PIL将OpenCV图像转成PIL.Image图像格式

# ------将OpenCV图像转成PIL图像:使用PIL解决人脸识别中文字体乱码-----------
global pilimg
pilimg=Image.fromarray(img)  # 将cv2图像转成pil
draw=ImageDraw.Draw(pilimg) # 使用ImageDraw.Draw()在pilimg图像上打印
font=ImageFont.truetype('F:/a.Machine Learn/font/SimSun.ttf',40,encoding='utf-8') # 宋体simsun-ttf size字体大小  encoding编码方式

先使用Image.fromarray()将OpenCV图像转成PIL型,再使用ImageDraw.Draw()在PIL图像上打印,font是下载的SimSun.ttf字体,需要导入源路径,40设置字体大小,编码方式‘utf-8’。

在需要使用文字的地方加上语句

draw.text((x + 10, y - 10), '李华', font=font, fill='yellow', stroke_width=2)

其中(x+10,y-10)文字开始显示的坐标,'李华'是输入的text文本,font=font表示字体类型,fill:字体颜色(有一点问题,颜色可以更改但是好像对应不上hhhh),stroke_width设置字体粗细。

--------在适当位置,将PIL.Image转成OpenCV图像类型

#-----将PIL.Image图像转成cv2图像格式------
    img=cv2.cvtColor(np.asarray(pilimg),cv2.COLOR_BGR2BGRA)
    # img=cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
    cv2.imshow('result',img) # 显示人脸检测图像

使用OpenCV中的cvtColor()函数将PIL.image类型的pilimg图像转成OpenCV图像,其中cv2.COLOR_BGR2GRAY是给BGR(RGB)格式的图片添加透明通道BGRA(RGBA)。

该部分完整代码

import cv2
import numpy as np
import os
from PIL import Image,ImageDraw,ImageFont

# 加载训练数据集文件--加载识别器LBRHFaceRegnizer_create()
recogizer=cv2.face.LBPHFaceRecognizer_create() # 需要安装pip install opencv_contrib-python

# 加载数据--训练好人脸识别得到的数据
recogizer.read('./trainer/trainer1.yml')


names=[] # 创建空列表,储存识别的名字name--图片名称第一个点和第二个点间部分

# 准备识别的图片
def face_detect_demo(img):
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 图片灰度化---cv2.cvtColor()
    # 加载分类器--进行检测
    face_detector=cv2.CascadeClassifier('F:/Program Files/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')
    # face=face_detector.detectMultiScale(gray,1.1,5,cv2.CASCADE_SCALE_IMAGE,(100,100),(300,300))
    face=face_detector.detectMultiScale(gray) # 使用默认参数
    # face=face_datector.deteMultiScale(gray)  # 默认
    for x,y,w,h in face: # 将整张人脸框住(矩形框+圆形框)
        global pilimg
        cv2.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2) # 绘制矩形框住识别的人脸
        cv2.circle(img,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=1) # 绘制圆框住识别的人脸
        # 人脸识别--预测和评分--recogizer.predict()输入参数是一个人脸图像,输出结果一个元组,包括预测结果ids和置信度confidence---取gray中矩形框住的部分
        ids,confidence=recogizer.predict(gray[y:y+h,x:x+w]) # 调用识别器cv2.face.LBPHFaceRecognizer中的predict()方法

        # ------将OpenCV图像转成PIL图像:使用PIL解决人脸识别中文字体乱码-----------
        pilimg=Image.fromarray(img)  # 将cv2图像转成pil
        draw=ImageDraw.Draw(pilimg) # 使用ImageDraw.Draw()在pilimg图像上打印
        font=ImageFont.truetype('F:/a.Machine Learn/font/SimSun.ttf',40,encoding='utf-8') # 宋体simsun-ttf size字体大小  encoding编码方式


        print('标签id:',ids,'置信评分:',confidence)
        if confidence>100: # confidence比较大时说明不可信
            draw.text((x + 10, y - 10), 'unknow', font=font, fill='yellow', stroke_width=2)
        else: # 当人是白名单人员时,将人名打印到人脸的方框上
            draw.text((x + 10, y - 10), str(names[ids-1]), font=font,fill='yellow', stroke_width=2)

    #-----将PIL.Image图像转成cv2图像格式------
    img=cv2.cvtColor(np.asarray(pilimg),cv2.COLOR_BGR2BGRA) # cv2.COLOR_BGR2BGRA
    # img=cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
    cv2.imshow('result',img) # 显示人脸检测图像


# 名字标签
def name(): # 定义name()函数---获取训练保存图片的人员名字
    path='./data/jm1/'
    # names=[]
    imagePaths=[os.path.join(path,f) for f in os.listdir(path)] # path路径 f是图片名.jpg
    for imagePath in imagePaths:
        name=str(os.path.split(imagePath)[1].split('.',2)[1])
        names.append(name)


# 加载视频、选定摄像头、加载图片
# cap=cv2.VideoCapture('1.mp4') # 参数为 0 调用本地摄像头,url连接调取网络摄像头,文件地址获取本地视频
cap=cv2.VideoCapture(0,cv2.CAP_DSHOW) # 识别电脑摄像头并打开
name()

while True:
    flag,frame=cap.read() # 读取cap 中的self和iamge;当有视频内容时self值非空,image当前帧的图像
    frame=cv2.flip(frame,1)
    if not flag: # 没有视频内容时 跳出整个while循环
        break
    face_detect_demo(frame) # 如果有视频内容,调用face_detect_demo()方法识别图片
    if ord(' ')==cv2.waitKey(10): # 按空格键(表示等待10秒?),则跳出循环
        break

# 释放内存
cv2.destroyAllWindows()
cap.release()

在最后PIL.Image图像转成OpenCV类型图像时,采用了cv2.COLOR_BGR2BGRA,可能是这里增加alpha通道造成字体颜色不匹配,如果有找到合适的颜色模式,希望可以分享在评论区。

-----------------一枚学习人脸识别的新手记录

标签:人脸识别,PIL,img,Python,cv2,face,乱码,OpenCV,图像
From: https://blog.csdn.net/t3036374036/article/details/141586586

相关文章

  • 4.Python操控Excel之格式
    1.设置字体斜体、加粗、颜色2.计算公式3.设置表格高度和宽度4.指定单元格合并5.取消指定单元格合并 ......
  • PyJWT 和 python-jose 在处理JWT令牌处理的时候的差异和具体使用
    PyJWT和python-jose是两个用于处理JSONWebTokens(JWT)的Python库。它们都有助于生成、解码、验证和管理JWT,但它们在功能范围和设计哲学上有一些重要的区别。本篇介绍它们之间的一些差异,以及在项目中使用FastAPI+ python-jose 来处理访问令牌的生成以及一些例子代码供......
  • Python - Anti-Patterns
    Thesearecommonprogrammingpractices that,whilenotnecessarilywrong,oftenleadtolessefficient,lessreadable,andlessmaintainablecode. Byunderstandingthesepitfalls,youcanwritecleaner,moreefficientcodeforyourPythonapplications. ......
  • PEP 508:为不同版本Python指定不同依赖
    问题背景有些常用的第三方包,在Python中支持的版本是不一致的。例如常用的numpy,在Python3.7中仅支持到1.21版本,其他Python版本可以支持到1.22版本以上,甚至现在的2.0版本以上。有一个问题是,在有些Cython的使用场景中,numpy==1.22的版本有可能出现报错ImportError:numpy.core.multia......
  • 10 个令人惊叹的 Python 自动化脚本!
                                                                            /01/剪贴板管理器你是否曾发现自己忙于处理多个文本片段,而忘记了自己复制了什么?有没有想过有一个工具可以记录你一天中......
  • 3.Python操控Excel之写
    1.openpyxl读取excel的格式流程2.openpyxl修改sheet标题并生成新excel保存3..create_sheet方法添加sheet,.remove方法删除sheet4.excel数据填充的四种方式5.1.更新excel内一列数据中的部分数据_代码部分5.2.更新excel内一列数据中的部分数据_执行结果......
  • python如何通过Json路径返回Json响应对应的值例子解析
    在Python中,处理JSON数据通常使用标准库中的json模块来解析和操作JSON格式的数据。如果你想要通过JSON路径来获取JSON响应中的值,你可以使用第三方库,如jsonpath-ng,它允许你使用类似XPath的语法来查询JSON对象。首先,你需要安装jsonpath-ng库,可以使用pip来安装:pipinstalljs......
  • python aiohttp创建很多线程的问题及解决例子解析
    在使用aiohttp进行异步HTTP请求时,创建大量线程可能会导致性能问题。根据搜索结果,这个问题通常与DNS查询有关,因为默认情况下,每次发送请求时aiohttp.ClientSession都会进行DNS查询,这是一个阻塞操作,会为每次查询创建一个新线程。为了解决这个问题,可以通过指定一个AsyncR......
  • 零基础学习人工智能—Python—Pytorch学习(九)
    前言本文主要介绍卷积神经网络的使用的下半部分。另外,上篇文章增加了一点代码注释,主要是解释(w-f+2p)/s+1这个公式的使用。所以,要是这篇文章的代码看不太懂,可以翻一下上篇文章。代码实现之前,我们已经学习了概念,在结合我们以前学习的知识,我们可以直接阅读下面代码了。代码里使......
  • 【python计算机视觉编程——1.基本的图像操作和处理】
    python计算机视觉编程——1.基本的图像操作和处理1.基本的图像操作和处理1.1PIL:Python图像处理类库1.1.1转换图像格式1.1.2创建缩略图1.1.3复制和粘贴图像区域1.1.4调整尺寸和旋转1.2Matplotlib1.2.1绘制图像、点和线1.2.2图像轮廓和直方图1.3Numpy1.3.1图像......