图像基础20 人脸辨识——人脸识别2

本文学习资源来自《机器学习实践指南》
前一章节的图像特征码提取算法是基于像素点的三元色数值的,有时候,图像少量的像素点差异可能干扰识别结果。有两种算法可以使识别效果更好:

  1. 将人脸图像大小设置为适当的数值(通常越小越好),这样更能突出人脸的特征,而略去很多干扰项。此外,提取原始特征组后,使用PCA降维技术对原始特征组进行进一步加工,生成最终的特征组,从而更好地表征人脸。
  2. 在标准欧氏距离的基础上乘以权重。有两种计算方式:每区域像素设置不同的权重;设置整体权重,使人脸图像矩阵的差分值均匀化。
    这里使用第2种方式。

变异系数

变异系数是衡量资料中各观测值变异程度的一个统计量。当进行两个或多个资料变异程度的比较时,如果度量单位与平均数相同,可以直接利用标准差来比较。如果单位和(或)平均数不同时,比较其变异程度就不能采用标准差,而需采用标准差与平均数的比值(相对值)来比较。
离散系数指标有:全距(极差)系数、平均差系数、方差系数和标准差系数等。常用的是标准差系数,用CV(Coefficient of Variance)表示。
CV(Coefficient of Variance):标准差与均值的比率。
用公式表示为: C V = σ / μ CV=σ/μ CV=σ/μ

计算公式
极差(全距)系数: V r = R / X ’ Vr=R/X’ Vr=R/X
平均差系数: V a , d = A . D / X ’ Va,d=A.D/X’ Vad=A.D/X
方差系数: V 方 差 = 方 差 / X ’ V方差=方差/X’ V=/X
标准差系数: V 标 准 差 = 标 准 差 / X ’ V标准差=标准差/X’ V=/X
其中,X’表示X的平均数。
----百度百科

变异系数可以消除因为平均数不同在变异程度比较中产生的干扰。变异系数越小,数据离平均值的偏离程度越小;反之,变异系数越大,数据离平均值的偏离程度越大。

这里对变异系数进行改进,将标准差用方差代替,然后将改进的变异系数的倒数作为计算欧氏距离的调节系数,这样做的效果是:将偏离程度较大的数据赋予较小的权重,将偏离程度越小的数据赋予较大的权重中。最后将标准欧氏距离乘以调节权重,从而实现差异平均化,让改进后的欧氏矩阵更好地表征人脸整体差异。

代码示例

#-*- coding: utf-8 -*-
#code:
#11-2.py
#标准欧氏距离实现的人脸识别

import cv2
import numpy as np
import mlpy

print('loding...')

OPCV_PATH=r"D:/Documents/face"

def get_EuclideanDistance(x,y):
    myx=np.array(x)
    myy=np.array(y)
    return np.sqrt(np.sum((myx-myy)*(myx-myy)))*np.var(myx-myy)

def get_distance(img,findimg):
    newsize=(21,21)
    fimg=cv2.resize(findimg,newsize)
    img = cv2.resize(img,newsize)
    my_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    my_fimg = cv2.cvtColor(fimg, cv2.COLOR_BGR2GRAY)
    # PCA降维
    pcaimg = mlpy.PCA()
    pcaimg.learn(my_img)
    pca_img = pcaimg.transform(my_img,k=1)
    pca_img=pcaimg.transform_inv(pca_img)
    pcafimg = mlpy.PCA()
    pcafimg.learn(my_fimg)
    pca_fimg = pcaimg.transform(my_fimg,k=1)
    pca_fimg = pcafimg.transform_inv(pca_fimg)
    # 计算基于整体权重的欧氏距离
    return get_EuclideanDistance(pca_img,pca_fimg)

color = (0, 0, 0)  # 设置人脸框的颜色
def findface(src, index):
    image = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    cv2.equalizeHist(image, image)  # 灰度图像进行直方图等距化

    # 加载OpenCv的面部特征库
    classfier = cv2.CascadeClassifier(OPCV_PATH + "/haarcascade_frontalface_alt.xml")
    # 找到人脸的位置
    # 设定最小图像的大小
    divisor = 8
    h = image.shape[1]
    w = image.shape[0]
    minSize = (int(w / divisor), int(h / divisor))  # 这里加了一个取整函数
    rect = classfier.detectMultiScale(image, 1.2, 2, cv2.CASCADE_SCALE_IMAGE, minSize)
    # if len(rect) > 0:  # 如果人脸数组长度大于0
    #     for faceRect in rect:  # 对每一个人脸画矩形框
    #         x, y, w, h = faceRect
    #         cv2.rectangle(image, (x, y), (x + w, y + h), color)
    # cv2.imshow('img'+str(index),image)

    result = []
    for r in rect:
        result.append([(r[0],r[1]),(r[0]+r[2],r[1]+r[3])])

    print(result)
    return result

fn = 'all.jpg'
fnt = 'test.jpg'
my_img=cv2.imread(fn)
face_test=cv2.imread(fnt)

#获取人脸在图像中的坐标
faceresult  = findface(my_img,1)
facet_result=findface(face_test,2)
#
myimg = cv2.imread(fn)
myimgt=cv2.imread(fnt)
#
isface1 = get_distance(myimg[faceresult[0][0][0]:faceresult[0][1][0],faceresult[0][0][1]:faceresult[0][1][1],:],myimgt[facet_result[0][0][0]:facet_result[0][1][0],facet_result[0][0][1]:facet_result[0][1][1],:])
isface2 = get_distance(myimg[faceresult[1][0][0]:faceresult[1][1][0],faceresult[1][0][1]:faceresult[1][1][1],:],myimgt[facet_result[0][0][0]:facet_result[0][1][0],facet_result[0][0][1]:facet_result[0][1][1],:])
if isface1<isface2:
    cv2.rectangle(myimg,faceresult[0][0],faceresult[0][1],(255,0,255))
    cv2.rectangle(myimgt,facet_result[0][0],facet_result[0][1],(255,0,255))
else:
    cv2.rectangle(myimg,faceresult[1][0],faceresult[1][1],(255,0,255))
    cv2.rectangle(myimgt,facet_result[0][0],facet_result[0][1],(255,0,255))

cv2.namedWindow('img')
cv2.imshow('img',myimg)
cv2.namedWindow('imgt')
cv2.imshow('imgt',myimgt)

cv2.waitKey()
cv2.destroyAllWindows()

运行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

编程圈子

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值