图片中人脸提取 | 宁静致远

图片中人脸提取

正在加载一言...


最近需要写一个工具,提取图片中的人脸,并且识别出相关信息,最后按照一定的规则进行存储。

0.分析


通过上述需求,需要做的是OCR文字识别和人脸识别,语言选择Python。人脸提取使用的是OpenCV,简单介绍一下,摘自百度百科。

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

文字识别准备使用 Tesseract

Tesseract最初由惠普实验室支持,用于电子版文字识别,1996年被移植到Windows上,1998年进行了C++化,在2005年Tesseract由惠普公司宣布开源。2006年到现在,由Google公司维护开发。

1.准备工作

  1. 安装 Tesseractpytesseract

    • Windows上下载安装包,点击这里下载
    • 双击运行,一直下一步就行
    • 配置环境变量,把刚刚安装的路径配置进去就行
    • 使用 pip install pytesseract 安装pytesseract
    • 配置 pytesseract.py 路径在 Lib\site-packages\pytesseract\pytesseract.py 下修改下面变量为之前的安装路径改变命令行位置
    • 下载语言包,放在tessdata 下,点击这里下载
  2. 安装 opencv

    • 使用pip install opencv-python 安装opencv-python

后面因为文字识别的准确率实在太低了,不得不换成Excel读取相关信息,后面继续优化

  1. 使用 pip install xlrd==1.2.0 安装xlrd 解析Excel,高版本的不支持xlsx,所以得装低版本的。

2.编写程序

import cv2
import os
import xlrd
import shutil
from tkinter import *
from tkinter import scrolledtext
import numpy as np
j = 0
width = 200
height = 250
dim = (width, height)

def clicked():
    root_path = txt.get() + "\\"
    data = xlrd.open_workbook(root_path + txt1.get())
    table = data.sheets()[0]
    dcit = {}

    # 加载人员信息
    for rown in range(table.nrows):
        dcit[table.cell_value(rown, 4)] = table.cell_value(rown, 2) + "#" + table.cell_value(rown, 6)

    for i in os.listdir(root_path):
        if i.endswith(".jpg"):
            path2 = os.path.join(root_path, i).replace("\\", "\\\\")  # 拼接绝对路径

            # img = cv2.imread(path2, 1)  # 读取一张图片
            img = cv2.imdecode(np.fromfile(path2, dtype=np.uint8), -1)
            # 提取人脸图片
            stxt.insert(INSERT, r"开始提取文件[" + i + "]人脸信息\n")

            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 将图片转化成灰度
            face_cascade = cv2.CascadeClassifier(
                "config\\haarcascade_frontalface_alt2.xml")
            faces = face_cascade.detectMultiScale(gray, 1.3, 5)
            if len(faces) > 0:
                for (x, y, w, h) in faces:
                    # img = cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
                    cropped = img[y - 60: y + w + 60, x - 30:x + h + 44]  # 裁剪坐标为[y0:y1, x0:x1]
                    resized = cv2.resize(cropped, dim, interpolation=cv2.INTER_AREA)
                # cv2.imshow("image", resized)

                # 进行xjk和zp分类
                idNo = i.split(" ")[0]
                if idNo in dcit:
                    stxt.insert(INSERT, "正在分类[" + idNo + "]\n")
                    val = dcit[idNo].split("#")
                    name = val[0]
                    peopleType = val[1]
                    folder = os.path.exists(root_path + "Result\\" + peopleType + "\\zp\\")
                    if not folder:
                        os.makedirs(root_path + "Result\\" + peopleType + "\\zp\\")
                    folder = os.path.exists(root_path + "Result\\" + peopleType + "\\xjk\\")
                    if not folder:
                        os.makedirs(root_path + "Result\\" + peopleType + "\\xjk\\")
                    # cv2.imwrite(, resized)
                    cv2.imencode('.jpg', resized)[1].tofile(
                        root_path + "Result\\" + peopleType + "\\zp\\" + idNo + '.jpg')

                    shutil.move(root_path + i, root_path + "Result\\" + peopleType + "\\xjk\\" + idNo + '.jpg')
                else:
                    stxt.insert(INSERT, "表格中没有为[" + idNo + "]的人\n")

                # cv2.destroyAllWindows()
            else:
                stxt.insert(INSERT, "文件[" + i + "]未识别到人脸\n")
            stxt.insert(INSERT, "-------------------\n")
            stxt.see(END)
            stxt.update()
    stxt.insert(INSERT, "处理完成.....\n")


tk = Tk()
tk.title("图片分类器")
tk.geometry("310x320")
tk.resizable(width=False, height=False)
lbl0 = Label(tk, text="登记表和图片需要放在一个文件夹下", fg='red', bg='yellow')
lbl = Label(tk, text="图片路径:")
btn = Button(tk, text="开始分类", command=clicked)
default = StringVar(tk, value='C:\\Users\\xxx\\Desktop\\sss\\xjk')
txt = Entry(tk, textvariable=default, width=20)

lbl1 = Label(tk, text="登记表名称:")
default = StringVar(tk, value='11.xlsx')
txt1 = Entry(tk, textvariable=default, width=20)

stxt = scrolledtext.ScrolledText(tk, width=40, height=15)

lbl0.grid(column=0, row=0,columnspan=2)
lbl.grid(column=0, row=1)
txt.grid(column=1, row=1)
lbl1.grid(column=0, row=2)
txt1.grid(column=1, row=2)
btn.grid(column=0, row=3, columnspan=2, sticky=W+E+N+S, padx=5, pady=5)
stxt.grid(column=0, row=4, columnspan=2, sticky=W+E+N+S, padx=5, pady=5)
tk.mainloop()

3.总结


很多时候应该想着去偷懒,只有想着去偷懒才能够自己去写工具,去学习。虽然不是很深入,但是你知识的广度会拓宽。

20210827 更新


为了方便使用者,转成了可执行文件并且做了个简单的界面。今天想起来就更新上

使用 pip install pyinstaller 安装 pyinstaller
使用 pyinstaller -F TestForFun.py -w 生成可执行文件

简单的界面

代码在上面,已经更新过了


文章作者: 彤爸比
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 彤爸比 !
评论
  目录