1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| import cv2 import numpy as np from skimage.feature import local_binary_pattern
class TextureBasedAntiSpoofing: """基于纹理的活体检测 原理: - 真实人脸:纹理细腻、自然 - 攻击样本:纹理异常(屏幕摩尔纹、打印网点) 方法: - LBP(Local Binary Pattern) - 傅里叶频谱分析 """ def __init__(self): self.radius = 3 self.n_points = 24 * self.radius**2 def extract_lbp_features(self, face_img): """提取 LBP 特征 Args: face_img: 面部图像(灰度), shape=(H, W) Returns: hist: LBP 直方图, shape=(256,) """ lbp = local_binary_pattern(face_img, self.n_points, self.radius, method='uniform') hist, _ = np.histogram(lbp.ravel(), bins=np.arange(0, self.n_points + 3), range=(0, self.n_points + 2)) hist = hist.astype(np.float32) hist /= hist.sum() + 1e-7 return hist def analyze_frequency(self, face_img): """傅里叶频谱分析 检测: - 屏幕刷新率特征(60/120 Hz) - 打印网点频率 """ f = np.fft.fft2(face_img) fshift = np.fft.fftshift(f) magnitude = np.abs(fshift) magnitude_log = np.log(magnitude + 1) h, w = magnitude_log.shape center_h, center_w = h // 2, w // 2 high_freq_mask = np.ones((h, w), dtype=np.uint8) high_freq_mask[center_h-50:center_h+50, center_w-50:center_w+50] = 0 high_freq_energy = np.sum(magnitude_log * high_freq_mask) total_energy = np.sum(magnitude_log) high_freq_ratio = high_freq_energy / (total_energy + 1e-7) return high_freq_ratio def detect_spoof(self, face_img, threshold=0.3): """检测是否为攻击 Args: face_img: 面部图像 threshold: 高频比例阈值 Returns: is_live: bool, 是否为真人 confidence: float, 置信度 """ if len(face_img.shape) == 3: gray = cv2.cvtColor(face_img, cv2.COLOR_RGB2GRAY) else: gray = face_img high_freq_ratio = self.analyze_frequency(gray) is_live = high_freq_ratio > threshold confidence = min(high_freq_ratio / threshold, 1.0) return is_live, confidence
if __name__ == "__main__": detector = TextureBasedAntiSpoofing() real_face = np.random.randint(50, 200, (112, 112), dtype=np.uint8) is_live, conf = detector.detect_spoof(real_face) print(f"真实人脸检测: {is_live}, 置信度: {conf:.2f}") attack_face = real_face.copy() x = np.arange(112) attack_face += np.sin(x * 0.5) * 30 attack_face = np.clip(attack_face, 0, 255).astype(np.uint8) is_live, conf = detector.detect_spoof(attack_face) print(f"攻击样本检测: {is_live}, 置信度: {conf:.2f}")
|