Labview2019+python3.6实现人脸识别(二)

上一篇主要讲了Labview可视化界面的搭建,图像实时采集、图像保存。链接:https://blog.csdn.net/weilixin88/article/details/103377779

本文主要说一下Labview调用的两个python脚本。其中我被Labview的一维图像数据如何转换为三维numpy数据卡了一天,只能说自己太水。

首先说被“特征训练”事件调用的python脚本——Feature.py

Feature.py脚本共导入了四个模块——dlib、cv2、os、numpy

dlib是比opencv自带的人脸检测更精准的人脸检测库,它能检测人脸的68个特征点,甚至更多。(当然,dlib不单单只能用于人脸检测,还有很多功能。)(dlib库在windows系统的安装,请百度)

一、Feature.py设计思路

因为本来算法就是拿别人的,也不会优化,但又不想让运行时间太长;我就想不能让已经训练过的图像再去训练了。

在比较两个列表时,可以将两个list转换为两个set,因为集合很适合计算交集。

例如:

集合A和集合B,它们的交集b=A&B;所以a=A-b;c=B-b

二、Feature.py的完整代码

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

import dlib
import cv2
import os
import numpy as np


#获得当前项目的根目录——也就是当前脚本的目录的上一级目录
object_path = os.path.dirname(os.getcwd())

#导入正脸探测器(实例化)
detector = dlib.get_frontal_face_detector()
#导入人脸关键点识别器
predictor = dlib.shape_predictor(object_path + '/.py/model/shape_predictor_68_face_landmarks.dat')
#导入人脸识别模型
model = dlib.face_recognition_model_v1(object_path + '/.py/model/dlib_face_recognition_resnet_model_v1.dat')



#读取图像文件夹中的图片,获得图片名字列表——因为图片的名字是唯一的
def read_img(dir_img_path):
    #文件夹中文件名列表
    name_list = []
    #文件夹中文件路径列表
    path_list = []
    for file_name in os.listdir(dir_img_path):
        file_d = dir_img_path + '/' + file_name
        #判断是不是文件夹
        if os.path.isdir(file_d):
            read_img(file_d)
        else:
            if file_d[-4:] == '.png':
                path_list.append(file_d)
                #查找最后一个'/'
                index = file_d.rfind('/')
                name_list.append(file_d[index+1:-4])
    return name_list,path_list
#读取已训练过的图片的名字——也是唯一的
def read_txt(dir_txt_path):
    name = []
    with open(dir_txt_path,'r') as txt:
        txt_data = txt.readlines()

        for row in txt_data:
            if row[-1] == ',':
                row = row[:-1]
            row_list = row.split(',')
            name += row_list
    return name

#获取新照片的特征函数
def Feature(dir_txt_path,dir_img_path,mode_path):
    #定义一个Flag变量
    Flag = False
    # 读取TXT文件中保存的以训练过的图片的名字,并获得名字列表
    txt_name = read_txt(dir_txt_path)
    # 读取img文件夹下的图片文件的名字,并获得名字列表
    img_name,img_path = read_img(dir_img_path)
    #将列表转换为集合
    txt_name_set = set(txt_name)
    img_name_set = set(img_name)
    #两个集合的公共部分
    set_txt_img = txt_name_set & img_name_set
    #img_name_set比txt_name_set多出的数据——也就是新添加的图片
    img_more_txt_set = img_name_set - set_txt_img
    #set转list
    img_more_txt_list = list(img_more_txt_set)

    if len(img_more_txt_list)>0:
        #循环新添加的图片名列表,找到对应路径,并生成其对应的特征向量
        #新添加图片的特征向量列表
        new_face_features = []
        for name in img_more_txt_list:

            #在所有img_name中查找name的索引
            name_index = img_name.index(name)
            #依据索引找到图片名对应的路径
            name_path = img_path[name_index]
            ##############提取人脸特征###################
            img = cv2.imread(name_path)
            gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

            # 使用探测器识别图像中的人脸,形成一个人脸列表
            face_dets = detector(gray_img, 1)
            # 索引每一个人脸区域
            for i, det in enumerate(face_dets):
                # 获取每个人脸的68个特征点
                face_predictor = predictor(img, det)
                # 获取每个人脸特征向量
                face_feature = model.compute_face_descriptor(img, face_predictor)
                # #将数据类型转换为Numpy类型
                # value = np.array(face_feature)
                new_face_features.append(face_feature)

            #############################################
        # 读取已有模型,就是为了保存新的模型
        try:
            npz_datas = np.load(mode_path)
        except:
            np.savez(mode_path, names=img_more_txt_list, face_features=new_face_features)
        else:
            npz_name = npz_datas['names']
            npz_feature = npz_datas['face_features']
            new_npz_name = np.hstack((npz_name,img_more_txt_list))
            new_npz_feature = np.vstack((npz_feature,new_face_features))
            np.savez(mode_path, names=new_npz_name, face_features=new_npz_feature)

        #新添加图片已训练后,将新图片的名字添加到txt文件中
        with open(dir_txt_path, 'a') as f:
            for i in img_more_txt_list:
                    f.write(i + ',')

        Flag = True
    return Flag



if __name__ == '__main__':
    dir_path = object_path + '/img'
    print(dir_path)
    mode_path = object_path + '/.py/model/face_model.npz'
    a = Feature('img_name_data.txt', dir_path,mode_path)
    print(a)

我保存特征向量的方式是使用numpy.savez(),保存为npz的二进制文件,但是没有找到在不覆盖原有数据的情况下,追加数据。所以,我的办法是先把npz中的数据先读到list中,然后将新数据append到list,最后重新保存到npz中。另外我尝试使用pandas保存数据,使用网上说的方法,但没有成功。

三、Face_recognition.py设计思路

因为Labview发给该脚本的是图像的一维数据,数据类型为uint8。但特征提取时需要的是三维的图像数据,所以先的把一维数据转为三维数据,因为我设置图像大小是高240,宽320的RGBA,所以转换代码如下:

#一维转三维
def Transfor(a):
    flatNumpyArray = np.array(a)
    #重排数组为240*320行,4列的二维数组,另外只要前三列
    RGBimage = flatNumpyArray.reshape((240 * 320, 4))[:, :3]
    #c数组的大小必须和图像大小一致
    c = np.zeros(shape=(240,320,3),dtype=np.uint8)
    j = 0
    for i in range(240*320):
        if i%320 == 0:
            c[j] = RGBimage[i:i+320]
            j += 1
    return c

然后就是将新图像提取人脸特征向量,接着将这个特征向量和已有特征向量分别计算欧式距离,然后将欧式距离对应的图像名和欧式距离组合成字典排序,找到最小欧式距离,也就找到了名字。最后设定一个相识度阈值,就能确定人脸是谁了。

检测代码如下:

class Test_face:
    def init(self):
        self.dist = []      #测试图像与已有图像特征的欧式距离列表
        self.face_rect = None
        self.name = None
    def test_face(self,photo,face_data):
        test_gray_img = cv2.cvtColor(photo, cv2.COLOR_BGR2GRAY)
        #使用探测器识别每张图像中的人脸,形成一个人脸列表
        self.face_rect = detector(test_gray_img, 1)
        #索引每一个人脸区域
        if len(self.face_rect) != 0:

            for i, det in enumerate(self.face_rect):
                #获取每个人脸的68个特征点
                test_face_predictor = predictor(photo, det)
                #获取每个人脸特征向量
                test_face_feature = model.compute_face_descriptor(photo, test_face_predictor)
                #将数据类型转换为Numpy类型
                test_value = np.array(test_face_feature)
                #将测试图像的人脸特征向量和已知人脸特征向量求范数(范数还是没明白)
                for i in face_data['face_features']:
                    dist_ = np.linalg.norm(i - test_value)
                    self.dist.append(dist_)
                #将名字和计算的欧式距离组合为字典
                names_dist = dict(zip(face_data['names'], self.dist))
                names_dist_sorted = sorted(names_dist.items(), key=lambda x: x[1])
                # #debug
                # print(names_dist_sorted)
                #规定相识度不得小于0.4
                if names_dist_sorted[0][1] > 0.4:
                    self.name = 'Unkonw'
                else:
                    self.name = names_dist_sorted[0][0]
        return self.name

四、完整的Face_recognition.py

#coding:utf-8
import dlib
import cv2
import os
import numpy as np


#获得当前项目的根目录——也就是当前脚本的目录的上一级目录
object_path = os.path.dirname(os.getcwd())

#导入正脸探测器(实例化)
detector = dlib.get_frontal_face_detector()
#导入人脸关键点识别器
predictor = dlib.shape_predictor(object_path + '/.py/model/shape_predictor_68_face_landmarks.dat')
#导入人脸识别模型
model = dlib.face_recognition_model_v1(object_path + '/.py/model/dlib_face_recognition_resnet_model_v1.dat')

class Test_face:
    def init(self):
        self.dist = []      #测试图像与已有图像特征的欧式距离列表
        self.face_rect = None
        self.name = None
    def test_face(self,photo,face_data):
        test_gray_img = cv2.cvtColor(photo, cv2.COLOR_BGR2GRAY)
        #使用探测器识别每张图像中的人脸,形成一个人脸列表
        self.face_rect = detector(test_gray_img, 1)
        #索引每一个人脸区域
        if len(self.face_rect) != 0:

            for i, det in enumerate(self.face_rect):
                #获取每个人脸的68个特征点
                test_face_predictor = predictor(photo, det)
                #获取每个人脸特征向量
                test_face_feature = model.compute_face_descriptor(photo, test_face_predictor)
                #将数据类型转换为Numpy类型
                test_value = np.array(test_face_feature)
                #将测试图像的人脸特征向量和已知人脸特征向量求范数(范数还是没明白)
                for i in face_data['face_features']:
                    dist_ = np.linalg.norm(i - test_value)
                    self.dist.append(dist_)
                #将名字和计算的欧式距离组合为字典
                names_dist = dict(zip(face_data['names'], self.dist))
                names_dist_sorted = sorted(names_dist.items(), key=lambda x: x[1])
                # #debug
                # print(names_dist_sorted)
                #规定相识度不得小于0.4
                if names_dist_sorted[0][1] > 0.4:
                    self.name = 'Unkonw'
                else:
                    self.name = names_dist_sorted[0][0]
        return self.name
#一维转三维
def Transfor(a):
    flatNumpyArray = np.array(a)
    #重排数组为240*320行,4列的二维数组,另外只要前三列
    RGBimage = flatNumpyArray.reshape((240 * 320, 4))[:, :3]
    #c数组的大小必须和图像大小一致
    c = np.zeros(shape=(240,320,3),dtype=np.uint8)
    j = 0
    for i in range(240*320):
        if i%320 == 0:
            c[j] = RGBimage[i:i+320]
            j += 1
    return c
#人脸识别
def CatchPICFromVideo(array,mode_path):
    #导入已有模型数据
    face_data = np.load(mode_path)
    #定义实例对象
    recognition_face = Test_face()
    recognition_face.init()
    #一维转三维
    frame = Transfor(array)
    name = recognition_face.test_face(frame,face_data)
    name = name.split('_')[0]
    return name

OK,能想到的就怎么多了。如果有什么疑问的,请在评论区留言,我们一起探讨。如果哪位大神能给小弟提点儿建议就更好了。

另外我将完整的Labview代码和python代码已上传上来。链接https://download.csdn.net/download/weilixin88/12013999

祝我和大家在这条路上能够坚持下去。

  • 15
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
Build real-world computer vision applications and develop cool demos using OpenCV for Python, About This Book, Learn how to apply complex visual effects to images using geometric transformations and image filtersExtract features from an image and use them to develop advanced applicationsBuild algorithms to help you understand the image content and perform visual searches, Who This Book Is For, This book is intended for Python developers who are new to OpenCV and want to develop computer vision applications with OpenCV-Python. This book is also useful for generic software developers who want to deploy computer vision applications on the cloud. It would be helpful to have some familiarity with basic mathematical concepts such as vectors, matrices, and so on., What You Will Learn, Apply geometric transformations to images, perform image filtering, and convert an image into a cartoon-like imageDetect and track various body parts such as the face, nose, eyes, ears, and mouthStitch multiple images of a scene together to create a panoramic imageMake an object disappear from an imageIdentify different shapes, segment an image, and track an object in a live videoRecognize an object in an image and build a visual search engineReconstruct a 3D map from imagesBuild an augmented reality application, In Detail, Computer vision is found everywhere in modern technology. OpenCV for Python enables us to run computer vision algorithms in real time. With the advent of powerful machines, we are getting more processing power to work with. Using this technology, we can seamlessly integrate our computer vision applications into the cloud. Web developers can develop complex applications without having to reinvent the wheel., This book will walk you through all the building blocks needed to build amazing computer vision applications with ease. We start off with applying geometric transformations to images. We then discuss affine and projective transformations and see how we can use them to apply cool geometric effects to photos. We will then cover techniques used for object recognition, 3D reconstruction, stereo imaging, and other computer vision applications., This book will also provide clear examples written in Python to build OpenCV applications. The book starts off with simple beginner's level tasks such as basic processing and handling images, image mapping, and detecting images. It also covers popular OpenCV libraries with the help of examples., The book is a practical tutorial that covers various examples at different levels, teaching you about the different functions of OpenCV and their actual implementation., Style and approach, This is a conversational-style book filled with hands-on examples that are really easy to understand. Each topic is explained very clearly and is followed by a programmatic implementation so that the concept is solidified. Each topic contributes to something bigger in the following chapters, which helps you understand how to piece things together to build something big and complex.

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值