我用 UniApp + 腾讯云 IAI 做了一个“明星脸比对“小程序,零后台延迟

最近花了些时间做了一个微信小程序------明星脸比对。用户上传一张照片,AI 就能找出和你最像的明星。

这个项目有点意思,因为它采用了一个不太常见的架构:前端直调腾讯云 IAI,云函数只存密钥,API 签名在前端完成。没有后台中转,零额外延迟。

今天就来聊聊这个项目的开发过程和一些技术取舍。

为什么做这个项目

想法其实很简单:大家都好奇自己长得像哪个明星。市面上类似的小程序不少,但大多需要把图片传到自己的服务器,经过后台处理后再调用 AI 服务。这样不仅慢,还增加了服务器成本。

我就在想,能不能让前端直接调用腾讯云的人脸识别服务?这样既快又省钱。

技术栈选择

前端用了 UniApp + Vue.js,目标是微信小程序。选择 UniApp 是因为一套代码可以跑多端,虽然这次只做小程序,但以后扩展方便。

人脸识别用的是腾讯云 IAI(人脸搜索 3.0)。这个服务支持在指定人员库中搜索相似人脸,返回 Top K 结果和相似度分数,正好符合需求。

后台用 Flask (Python) ,但注意,这个后台不是小程序运行必需的。它只用于批量管理人员库数据------添加明星、删除明星、初始化人员库等。小程序本身不经过这个后台。

核心架构:前端直调

这是整个项目最关键的设计决策。

传统做法是:用户上传图片 → 传到自己的服务器 → 服务器调用腾讯云 API → 返回结果。多了一跳,延迟增加,服务器还要承担转发成本。

我的做法是:用户上传图片 → 前端完成 TC3-HMAC-SHA256 签名 → 直接调用腾讯云 IAI SearchFaces 接口 → 返回结果。

云函数在这里只做一件事:安全地存储腾讯云密钥。前端通过云函数获取临时密钥,然后在前端完成 API 签名。这样既保证了密钥安全,又实现了零中转延迟。

图片处理流程

前端处理图片的流程需要仔细设计:

  1. 用户选择图片 :支持拍照和相册选择,优先使用 uni.chooseMedia,兼容降级到 uni.chooseImage

  2. 图片压缩 :这是关键一步。人脸图片不需要太高分辨率,压缩到 800px 以内可以大幅减少传输时间。先用 uni.compressImage 做质量压缩,如果图片过大再用 canvas 做尺寸压缩。

  3. 上传到云存储:压缩后的图片上传到 uniCloud 云存储,获取永久 URL。这个 URL 用于结果页展示和分享功能。

  4. 转 base64:读取压缩后的图片文件,转换为 base64 编码,用于调用人脸搜索接口。

  5. 调用云函数:通过 uniCloud 云函数进行人脸检测和搜索。云函数内部完成签名和 API 调用。

人员库管理

腾讯云 IAI 的人脸搜索需要在指定的人员库中进行。所以第一步是建立一个明星人员库。

后台提供了完整的 CRUD 接口:

  • 创建人员库
  • 批量添加明星(从 JSON 文件导入)
  • 搜索人脸
  • 删除明星/人员库

初始化脚本 add_stars.py 会读取 data/new_cloud/ 目录下的所有 JSON 文件,批量导入到腾讯云人员库。每个明星数据包含 person_id、name、gender、url(照片 URL)等信息。

还有一个爬虫脚本 scrape_category.py,可以从网站抓取明星数据,自动生成 JSON 文件。

积分系统设计

小程序做了一个简单的积分系统:

  • 每次比对消耗 5 积分
  • 分享给好友可获得 5 积分
  • 观看视频广告可获得 5 积分

这个设计有两个目的:一是控制 API 调用频率(腾讯云按次计费),二是通过分享实现自然增长。

积分查询和扣除通过后端 API 完成,前端只负责展示和触发。

结果展示

结果页的设计花了些心思:

  • 对比展示:左边是用户上传的照片,右边是最匹配的明星,中间用 VS 图标连接,视觉冲击力强。
  • 相似度进度条:把腾讯云返回的分数转换成百分比,用渐变色进度条展示,直观易懂。
  • 其他相似明星:除了最匹配的一个,还展示 Top 2-5 的其他候选,增加趣味性。
  • 分享优化:分享时带上用户照片作为封面,标题显示"我和 XX 相似度 XX%",吸引点击。

踩过的坑

开发过程中遇到几个值得注意的问题:

1. 图片压缩比例问题

一开始用 canvas 压缩图片时,没有保持原始宽高比,导致人脸变形,识别率大幅下降。后来改为先获取图片信息,计算缩放比例,再用 canvas 等比例绘制。

2. 云函数调用失败

前端直接调用腾讯云 API 时,签名算法容易出错。TC3-HMAC-SHA256 签名需要严格按照腾讯云文档的步骤来,包括 CanonicalRequest、StringToSign 等。建议先用官方 SDK 测试,确认签名逻辑正确后再移植到前端。

3. 人员库初始化

批量导入明星数据时,API 有频率限制。一开始没有加延迟,导致部分请求被限流。后来在每次请求后加了 0.3-0.5 秒的间隔,问题解决。

项目结构

复制代码
mingxing_face/
├── admin/                              # 后台管理(仅用于初始化/管理人员库)
│   ├── app.py                          # Flask 管理服务
│   ├── config.py                       # 腾讯云 API 配置
│   ├── tencent_iai.py                  # 腾讯云 IAI SDK 封装
│   ├── add_stars.py                    # 一键初始化 IAI 人员库
│   ├── scrape_category.py              # 明星数据爬取脚本
│   └── data/                           # 明星数据与图片
│
├── star_face_uniapp/                   # UniApp 前端(微信小程序)
│   ├── pages/index/index.vue           # 首页:拍照/选图 → 人脸搜索
│   └── pages/result/result.vue         # 结果页:展示 Top5 相似明星
│   └── uniCloud/                       # 云函数(仅存储密钥)

总结

这个项目的核心价值在于架构简化。通过前端直调云服务,省去了中间服务器层,降低了延迟和成本。

当然,这种架构也有局限:

  • 前端签名逻辑暴露了部分实现细节(虽然密钥是安全的)
  • 不适合需要复杂业务逻辑的场景
  • 云函数的冷启动时间仍然会影响首次调用速度

但对于这种"上传-处理-返回"的简单场景,前端直调是一个值得考虑的方案。

项目代码已经开源,如果你也感兴趣,可以看看完整实现。欢迎提 issue 或 PR。

https://github.com/liandyao/ai_star_face.git


技术栈:UniApp + Vue.js | 腾讯云 IAI | uniCloud | Flask | Python

适用场景:人脸识别、图片比对、AI 趣味应用

相关推荐
l1t1 小时前
DeepSeek总结的Python 3.14.5 发布候选版本
开发语言·python
Cyber4K2 小时前
【Python专项】进阶语法-日志分类与分析(2)
开发语言·前端·python
lbb 小魔仙2 小时前
Python + LangChain 环境搭建完全指南:从零构建本地 RAG 知识库(附 Ollama 本地模型集成)
开发语言·python·langchain
风落无尘2 小时前
Python 包发布全流程:从项目结构到 PyPI 上线,以及我踩过的那些坑
开发语言·python·pip
Lenyiin2 小时前
《LeetCode 顺序刷题》61 - 70
java·c++·python·算法·leetcode·lenyiin
岁岁的O泡奶2 小时前
NSSCTF_crypto_[LitCTF 2023]babyLCG
经验分享·python·算法·密码学·crypto·流密码
风落无尘2 小时前
我用 LangChain 写了一个带“定速巡航”的向量化工具,发布到 PyPI 了!
人工智能·python·langchain
AI技术控2 小时前
RAG 效果差不是模型问题:10 个检索增强失败原因总结
人工智能·python·自然语言处理
Hesionberger2 小时前
LeetCode 78:子集生成全攻略
java·开发语言·数据结构·python·算法·leetcode·职场和发展