活体检测

活体检测-,他们是人脸识别中最重要的一部分,为了防止照片攻击。下面介绍自己应用的两种方案。

下面的眨眼和张嘴,摇头和点头,都是通过连续的图片,计算变化距离与不变距离的比,进行上一帧图像与下一帧图像的比,来判断是否为活体。这里用的是dlib,速度很快,可以做到实施检测,每秒20帧是可以做到的。

活体检测_第1张图片

眨眼和张嘴

这个是根据相关论文来的,可以延伸到张嘴检测。

首先说眨眼检测

活体检测_第2张图片

公式为\Gamma =|\frac{(P_{2}-P_{6})+(P_{3}-P_{5})}{2 \times (P_{1}-P_{4}) }|

下面介绍张嘴检测,见下图。模仿眨眼,取点的时候需要注意,内圈的点变化更加明显。变化距离建议取内圈,固定距离选用外圈

活体检测_第3张图片

 

公式为\Gamma =|\frac{(P_{62}-P_{68})+(P_{64}-P_{66})}{2 \times (P_{49}-P_{55}) }|

摇头与点头

摇头和点头的方法近视,用到一和上面的想法几乎一样。

首先说摇头,当摇头的时候,你的脸颊会变窄,而你的鼻子长度几乎是不变的。

活体检测_第4张图片

公式为\Gamma =|\frac{(P_{4}-P_{14})}{(P_{28}-P_{31}) }|

点头的时候,鼻子的距离会变短,而脸颊的会几乎不会边窄。

公式为\Gamma =|\frac{(P_{28}-P_{31})}{(P_{4}-P_{14}) }|

防止照片攻击

用到的技术很简单,就是图像哈希算法。

过程是这样的。

1、通过摄像头检测常见,如果没有人脸,保存当前的背景图片。

2、如果5分钟内没有检测到人脸,用现在时间的场景图像代替内存中的图像。看作5分钟内场景内的光线变化不大。

3、如果检测人脸目标,随机截取背景图片,同时截取内存中对应位置的图像。两者进行哈希图像运算,比较两者的汗名距离。

4、关于随机截取多少个图像,和多大。这个要根据本地服务性能来决定。我设计的用了7个截图。

其他--关于哈系图像的比较

平均哈希

1.图片缩放,一般为8*8,或者32*32

2.将图片灰度化

3.求平均值,并根据平均值将每一个像素二值化

4.将8*8=64位bit,每8个比特为一个十六进制值,转换成字符串,生成哈希值(指纹)

感知哈希

1.图片缩放 为32*32大小

2.将图片灰度化

3.对图片进行离散余弦变换(DCT),转换的频域

4.取频域左上角8*8大小(图片的能量都集中在低频部分,低频位于左上角)

5.计算平均值,并根据平均值二值化(同平均哈希)

6.生成哈希值

差异值哈希

1.图片缩放为9*8大小

2.将图片灰度化

3.差异值计算(每行相邻像素的差值,这样会生成8*8的差值,前一个像素大于后一个像素则为1,否则为0)

4.生成哈希值

计算距离

生成每一个图片的哈希值后,需要计算哈希值的距离,来判断两张图片的相似度。一般使用汉明距离,也就是逐位计算两张图片的哈希值是否相同。
 

import cv2
import numpy as np
import time
#均值哈希算法
def aHash(img):
    #缩放为8*8
    img=cv2.resize(img,(8,8),interpolation=cv2.INTER_CUBIC)
    #转换为灰度图
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #s为像素和初值为0,hash_str为hash值初值为''
    #求平均灰度
    #遍历累加求像素和
    gray_mean=np.mean(gray)
    #灰度大于平均值为1相反为0生成图片的hash值
    hash_value = np.where(gray => gray_mean,1,0).flatten()
    return hash_value.tolist()
 
#差值算法
def dHash(img):
    #缩放8*8
    img=cv2.resize(img,(9,8),interpolation=cv2.INTER_CUBIC)
    #转换灰度图
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    hash_value=[]
    #每行前一个像素大于后一个像素为1,相反为0,生成哈希
    for i in range(8):
        tmp = np.where(gray[:,i]=>gray[:,i+1],1,0)
        hash_value.extend(tmp)
    return hash_value
 
# 感知哈希 
def pHash(imgfile):
    img_list=[]
    #加载并调整图片为32x32灰度图片
    img=cv2.imread(imgfile, 0)
    img=cv2.resize(img,(64,64),interpolation=cv2.INTER_CUBIC)
    img = np.float32(img)
    #二维Dct变换
    vis1 = cv2.dct(vis0)[:8,:8]
    img_mean = np.mean(vis1)
    #计算均值
    hash_Value = np.where(vis1 >= img_neam,1,0).flatten()
    return hash_value
 
 
def hammingDist(v1, v2):
    assert len(v1) == len(v2)
    return 1 - np.sum(v1==v2)/64
 
if __name__ == '__main__':
    img1 = cv2.imread("F:\\Humpback Whale\\phash\\4.jpg")
    img2 = cv2.imread("F:\\Humpback Whale\\phash\\2d6610b9.jpg")
    time1 = time.time()
    hash1 = aHash(img1)
    hash2 = aHash(img2)
    n = cmpHash(hash1, hash2)
    print('均值哈希算法相似度:', n, "-----time=", (time.time() - time1))
    time1 = time.time()
    hash1 = dHash(img1)
    hash2 = dHash(img2)
    n = cmpHash(hash1, hash2)
    print('差值哈希算法相似度:', n, "-----time=", (time.time() - time1))
 
    time1 = time.time()
    HASH1=pHash("F:\\Humpback Whale\\phash\\4.jpg")
    HASH2=pHash("F:\\Humpback Whale\\phash\\2d6610b9.jpg")
    out_score = hammingDist(HASH1,HASH2)
    print('感知哈希算法相似度:', out_score, "-----time=", (time.time() - time1)) 

 

并做了一些实验,来比较三种哈希的特点:

1.同一张图片

均值哈希算法相似度: 1.0 -----time= 0.0
差值哈希算法相似度: 1.0 -----time= 0.0
感知哈希算法相似度: 1.0 -----time= 0.031249523162841797

2.图片resize成其他大小

活体检测_第5张图片
均值哈希算法相似度: 0.890625 -----time= 0.0
差值哈希算法相似度: 0.859375 -----time= 0.0
感知哈希算法相似度: 0.921875 -----time= 0.03124713897705078

3.改变图片亮度

活体检测_第6张图片

均值哈希算法相似度: 0.984375 -----time= 0.0
差值哈希算法相似度: 0.9375 -----time= 0.0
感知哈希算法相似度: 0.95703125 -----time= 0.0312497615814209

4. 改变图片对比度

活体检测_第7张图片

均值哈希算法相似度: 1.0 -----time= 0.0
差值哈希算法相似度: 1.0 -----time= 0.0
感知哈希算法相似度: 0.8828125 -----time= 0.04687380790710449

5.改变图片锐度

活体检测_第8张图片

均值哈希算法相似度: 0.984375 -----time= 0.0
差值哈希算法相似度: 0.890625 -----time= 0.0
感知哈希算法相似度: 0.94921875 -----time= 0.031252145767211914

6.色度增强

活体检测_第9张图片

均值哈希算法相似度: 1.0 -----time= 0.015625715255737305
差值哈希算法相似度: 0.984375 -----time= 0.0
感知哈希算法相似度: 0.99609375 -----time= 0.0312497615814209

7.图片旋转

活体检测_第10张图片

均值哈希算法相似度: 0.484375 -----time= 0.0
差值哈希算法相似度: 0.46875 -----time= 0.0
感知哈希算法相似度: 0.4609375 -----time= 0.031249046325683594

活体检测_第11张图片

均值哈希算法相似度: 0.375 -----time= 0.0
差值哈希算法相似度: 0.515625 -----time= 0.0
感知哈希算法相似度: 0.62890625 -----time= 0.03132271766662598


从上面的实验结果可以得出一下结论:

1.均值哈希和差值哈希算法的时间都比感知哈希少,因为感知哈希resize为32*32,并且要进行DCT离散余弦变换,这个计算比较耗时

2.改变图片的亮度,色度,对比度,锐度,均值哈希的效果都是最好的,几乎不受影响,其次是差值哈希,最差是感知哈希

3.但是感知哈希在图片旋转以及resize后,效果比前两者要好
 

你可能感兴趣的:(案例:人脸)