第十章

人脸识别与 OCR:认人 + 认字

第九层 + 第十层 · 刷脸/PaddleOCR 会员刷脸进店 + 快递单自动录入

一、人脸识别的"三步流程"

"王姐的需求:黑卡会员刷脸进店,自动识别身份。"老周说,"人脸识别不是'一步到位',是三步流水线:"

人脸识别三步:
  ① 人脸检测(Face Detection):人脸在哪?
     → 框出人脸位置(这就是第八章的目标检测,类=face)
  ② 人脸对齐(Face Alignment):人脸正不正?
     → 用关键点(眼睛/鼻子/嘴)把人脸矫正到正面
  ③ 人脸识别(Face Recognition):这是谁?
     → 提取"人脸特征向量" → 和数据库比对
     → 特征相似 → 是同一个人

  类比:
    检测 = 找到脸
    对齐 = 转正(拍照角度歪没关系)
    识别 = 比对"面部指纹"

  关键:人脸识别不是"分类"是"比对"
    数据库里是每个会员的"特征向量"
    新来的人 → 提取特征 → 比对最像的会员
    → 相似度 > 阈值 = 命中;< 阈值 = 陌生人

"人脸识别 = 检测 + 对齐 + 比对。核心思想(第七章讲过):把人脸变成'特征向量',用向量相似度判断'是不是同一人'。"


二、人脸识别实战:Face Recognition 库

"工程上用现成库最快——face_recognition(dlib 封装,简单好用)。"老周演示:

# pip install face_recognition
import face_recognition

# 1. 录入会员:算出每个会员的脸部特征(入库一次)
def enroll_member(name, image_path):
    img = face_recognition.load_image_file(image_path)
    encodings = face_recognition.face_encodings(img)
    if encodings:
        member_db[name] = encodings[0]   # 存特征向量
        print(f"{name} 已录入")
    else:
        print(f"{name}:没检测到人脸!")

member_db = {}
enroll_member("张三", "zhangsan.jpg")
enroll_member("李四", "lisi.jpg")

# 2. 门口刷脸:检测 + 比对
def recognize(photo_path):
    img = face_recognition.load_image_file(photo_path)
    locations = face_recognition.face_locations(img)    # 检测
    encodings = face_recognition.face_encodings(img, locations)  # 特征

    for enc in encodings:
        # 和所有会员比对(欧氏距离,越小越像)
        name, distance = "陌生人", float("inf")
        for n, known in member_db.items():
            d = face_recognition.face_distance([known], enc)[0]
            if d < distance:
                distance, name = d, n
        # 阈值判断(如 < 0.45 = 同一人)
        if distance < 0.45:
            print(f"识别成功:{name}(相似度 {1-distance:.2%})")
        else:
            print(f"陌生人(最近匹配 {name},距离 {distance:.2f})")

# 3. 云间书店使用:黑卡会员自动开门 + 推送专属推荐
face_recognition 要点:
  face_locations:检测人脸位置
  face_encodings:提取 128 维特征向量("面部指纹")
  face_distance:比对距离(< 0.45 判同一人)
  距离 vs 相似度:距离越小越像(可转 1-距离)

  进阶(生产级):
    用更快的检测(YOLO face / SCRFD)
    用更准的特征模型(ArcFace/InsightFace)
    加活体检测(防照片/视频冒充)
    关键点对齐(双眼连线摆正)

"生产级人脸识别 = 检测(YOLO)+ 特征(ArcFace)+ 活体 + 数据库比对——face_recognition 是入门,ArcFace 系是工业标准。"


三、人脸关键点与活体检测:防"照片骗过人脸"

"刷脸最大的安全风险:照片/视频冒充。所以要关键点和活体检测。"老周说:

人脸关键点(Face Landmark):
  68 个点标出脸的关键部位:
    眼睛轮廓、眉毛、鼻子、嘴巴、下巴
  用途:
    人脸对齐(转正)、表情识别、妆容效果

  活体检测(Liveness Detection):
    防止"拿照片/视频冒充真脸"
    方案:
      动作活体:提示"眨眨眼/摇摇头"(交互式)
      静默活体:分析纹理/反光/深度(无感式)
      红外/深度:3D 结构(手机人脸解锁)

  云间书店方案:
    黑卡会员刷脸:静默活体(摄像头分析)
    配合人工:高危操作(大额退款)再加密码

"没有活体检测的人脸识别 = 一张照片就能进门——这是安防场景的生死线。'刷脸'产品的专业度,一半体现在活体上。"


四、OCR:让机器"认字"

"第二个需求:快递单自动录入。这就是 OCR(光学字符识别)。"老周说:

OCR(Optical Character Recognition):
  从图片里"读出文字"

  流程:
    ① 文字检测(Detection):文字在哪?(区域/行框)
    ② 文字识别(Recognition):这些文字是什么?

  类比:
    检测文字位置 = 第八章目标检测(类=text)
    识别文字内容 = 序列识别(读成字符串)

  两类 OCR 方案:
    传统:模板匹配 + 字符切分(对印刷体有效,但脆)
    深度学习(现代):
      检测:DBNet / EAST(找文字框)
      识别:CRNN / SVTR(把文字图变字符串)
      端到端:PaddleOCR 一条龙(工业最常用)

"OCR = 找字(检测)+ 认字(识别)。现代方案用深度学习端到端解决,PaddleOCR 是中文场景的事实标准。"


五、PaddleOCR 实战:快递单自动录入

"云间书店用 PaddleOCR(百度开源,中文识别最强)。"老周演示:

pip install paddlepaddle paddleocr
from paddleocr import PaddleOCR
import re

# 1. 初始化 OCR(中文模型)
ocr = PaddleOCR(use_angle_cls=True, lang="ch")   # 中文

# 2. 识别快递单
result = ocr.ocr("express_bill.jpg", cls=True)

# 3. 解析结果
texts = []
for line in result[0]:
    box, (text, confidence) = line
    texts.append(text)
    print(f"{text} ({confidence:.2f})")

# 4. 业务解析:提取关键字段
bill_text = "\n".join(texts)
def extract_field(text, pattern):
    m = re.search(pattern, text)
    return m.group(1) if m else "未找到"

name = extract_field(bill_text, r"(收件人[::]\s*)(\S+)")
phone = extract_field(bill_text, r"(1[3-9]\d{9})")
address = extract_field(bill_text, r"(地址[::]\s*)(\S+)")

print(f"收件人: {name}")
print(f"电话: {phone}")
print(f"地址: {address}")
# → 自动录入系统,不用人工敲键盘!
PaddleOCR 流程:
  初始化 → ocr.ocr(图) → 解析(框, 文字, 置信度)
  关键技巧:
    ① 预处理(第三章)提升识别率
    ② 后处理:正则提取字段(电话/地址/姓名)
    ③ 置信度过滤(< 0.7 的标记人工复核)

  常见问题:
    图片歪 → 透视矫正(第四章的单应性)
    光线差 → 预处理均衡化
    手写体 → 换手写模型/人工兜底

  云间书店落地:
    快递单 → OCR → 自动录入系统 → 人工抽查
    图书版权页 → OCR → 自动建档(书名/ISBN/定价)

"OCR 落地 = OCR 识别 + 正则后处理——识别出来是'一串字',业务提取靠正则。这套组合拳,快递单、发票、证件都能打。"


六、OCR 技术深入:CRNN 怎么"读"一行字

"好奇的可以了解一下识别网络 CRNN 的原理。"老周说:

CRNN(Convolutional Recurrent Neural Network):
  文字识别的经典结构

  处理一行文字图:
    ① 卷积层(CNN):提取特征序列
       (把图按"列"切成特征序列)
    ② 循环层(RNN/LSTM):按序列"从左到右读"
       (利用上下文:前一个字帮助认后一个字)
    ③ 转录层(CTC):输出最终文字序列
       (处理变长输出,无需逐字切分)

  为什么 RNN 对文字有用:
    文字是"序列"(从左到右有顺序)
    "云"后面通常是"间"——上下文帮助识别
    复杂场景(连笔/遮挡)表现更好

  新趋势:
    Transformer 类(SVTR/PARSeq):并行读字,更快
    端到端场景:检测+识别融合

"CRNN = '看列特征 + 序列记忆 + 输出文字'——理解它,你就懂为什么现代 OCR 能'读'复杂的文字了。工程上用 PaddleOCR 即可,原理知道个大概。"


七、合规提醒:人脸数据不能随便用

"最后,刷脸这件事有合规红线。"老周严肃地强调:

人脸数据合规(中国《个人信息保护法》):
  人脸信息 = 敏感个人信息(最高级别保护)

  必须做到:
    ① 单独同意:不能"打包勾选",要单独弹窗征求同意
    ② 告知用途:明确告诉用户"收集人脸用于会员识别"
    ③ 最小必要:只收集必要信息(不能顺便做别的)
    ④ 安全保障:加密存储、访问留痕、防泄漏
    ⑤ 提供删除:用户有权删除自己的人脸信息
    ⑥ 合规评估:涉及人脸识别要做事前评估

  违规后果:
    最高罚 5000 万或上年营收 5%
    新闻案例:多地因"未单独同意采集人脸"被罚

  云间书店方案:
    刷脸仅限"主动办理"的黑卡会员(单独同意+协议)
    人脸特征向量加密存储(不可逆还原原图)
    提供"取消刷脸"入口(删除特征)
    摄像头贴告示(进入监控区域告知)

"技术能做到的,法律未必允许——人脸识别先过'合规关'再谈'技术关'。这套合规意识,也是高级工程师和初级工程师的分水岭。"


八、章末:老周的第十章总结

第九层 + 第十层:人脸识别与 OCR
├── 人脸识别三步:检测 → 对齐(关键点)→ 比对(特征向量)
├── face_recognition:入门(face_distance < 0.45 判同人)
├── 生产级:YOLO检测 + ArcFace特征 + 活体检测
├── 活体检测:防照片/视频冒充(静默/动作/深度)
├── OCR 流程:文字检测 + 文字识别(PaddleOCR 一条龙)
├── 实战:快递单 OCR + 正则提取字段(自动录入)
├── CRNN:CNN特征 + RNN序列 + CTC转录(识别原理)
└── 合规:人脸 = 敏感信息(单独同意/加密/可删除)
第十一层(预告):视频理解与目标跟踪 —— 客流动线分析

"小陈,刷脸进店、快递单自动录入,都上线了!"老周说,"但王姐看完客流数据又说了:'光知道一天进多少人不够,我想知道客人从哪个门进、在哪个书架停留最久、最后从哪走——动线分析!'——这就轮到最后一章技术:视频理解与目标跟踪。从'每帧数人'升级到'追踪每一个人的轨迹'。"

✌ 语言