一、 前言
2021
年底,领导给了个tof
模块,要求基于此开发一个演示程序,实现3D
人脸识别的功能。当时听他说出3D
人脸识别就有点头疼,第一是想自己之前没接触这样的项目;第二是在想3D
人脸数据相比于2D
人脸数据,恐怕没后者那么多。基于快速开发出产品以及自身能力的想法,向领导建议使用2D+
技术路线,即采用rgb
图做人脸识别,采用深度图做真假脸识别,领导同意了。
rgb
图用到的就是些网上开源、成熟的模型,如retinaface
、mobileface
,这部分不是今天的主题,也没什么好说的,网上博客大把。主要说说深度图吧,简单把过程记录一下,方便自己且抛砖引玉,如果有错漏之处,还请指出,谢谢!
二、 过程
(一)图片预处理过程
先给大伙看看tof
保存的深度图,16 bit png
格式,每个像素值的实际物理意义是距离,单位是mm
。
我没有上传错,原图就是这样,看起来乌漆嘛黑的。因为它是16 bit
,像素值范围是[0, 65536)
,下面给它映射到[0, 256)
,再给它像素反转一下。
import cv2
import numpy as np
def u16_to_u8(depth_image):
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(depth_image)
alpha = 255 / (max_val - min_val)
beta = -min_val
result = ((depth_image + beta) * alpha).astype(np.uint8)
return result
depth_image = cv2.imread(r"test.png", cv2.IMREAD_ANYDEPTH)
depth_image = u16_to_u8(depth_image)
depth_image = 255 - depth_image
cv2.imshow('depth_image', depth_image)
key = cv2.waitKey(0)
显示结果如下
可以看见也没什么卵区别,都是一片糊。如果要根据深度图来做分类,区分真假脸,这样的数据恐怕不好做,所以需要再做进一步处理,比如直方图均衡。先试试opencv
自带的直方图均衡函数。
depth_image = cv2.imread(r"test.png", cv2.IMREAD_ANYDEPTH)
depth_image = u16_to_u8(depth_image)
cv_he = cv2.equalizeHist(depth_image)
cv2.imwrite(r"t1.png", cv_he)
看起来效果好了点,但还是有点不够。下面试试openni
的直方图均衡函数。
def get_his_img(img, his_size = 65536):
if len(img.shape) == 2:
img = img[np.newaxis, :]
_, h, w = img.shape
hist = cv2.calcHist(img, [0], None, [his_size - 1], [