- 示例工程
【免费下载链接】python-docs-samples
Code samples used on cloud.google.com
本文以 python-docs-samples 仓库中 vision/snippets/face_detection 目录下的官方示例为蓝本,系统讲解如何使用 Google Cloud Vision API 在 Python 中完成人脸检测:从环境认证、依赖安装、命令行运行,到faces.py的源码级拆解、结果可视化(绘制绿色人脸框与置信度),再到测试用例的验证逻辑。读完本文,你将能够独立跑通一个人脸检测 + 图像标注的完整流程,并掌握如何基于 Vision API 的 FaceAnnotation 结果做进一步扩展。
一、示例概览:这个目录里有什么
该示例位于仓库的 vision/snippets/face_detection/ 目录,核心目标是在给定图片中检测人脸,并用绿色方框把每张脸框出来、在方框上方标注检测置信度。目录内文件如下:
| 文件 | 作用 |
|---|---|
| faces.py | 示例主程序:检测人脸并绘制方框 |
| faces_test.py | 基于 pytest 的自动化测试,验证方框确实被绘制 |
| requirements.txt | 运行时依赖:google-cloud-vision与pillow |
| requirements-test.txt | 测试依赖:pytest |
| noxfile_config.py | nox 测试配置(声明忽略的 Python 版本) |
| README.rst | 官方说明文档(由 README.rst.in 自动生成) |
从 README.rst.in 的元数据可以看到,该示例归属于 Cloud Vision API 产品线,被官方定义为 "Face detection" 示例。README.rst提到:Cloud Vision API 允许开发者轻松地在应用中集成视觉检测能力,包括图像标注(image labeling)、人脸与地标检测、光学字符识别(OCR)以及显性内容标记等;本文聚焦其中的人脸检测(face detection)。
注意:仓库中还有更全面的 vision/snippets/detect/detect.py,它提供了不带绘图功能的"纯检测 + 打印人脸属性"版本,可作为本示例的对照与扩展素材,后文会引用其中的实现细节。
二、环境准备:认证与依赖安装
2.1 启用 API 与设置认证
调用 Cloud Vision API 前,必须完成认证设置:
- 在 Google Cloud 控制台创建(或选择一个)项目,并启用Cloud Vision API;
- 为本机环境配置应用默认凭据(Application Default Credentials),常见做法是下载服务账号 JSON 密钥,并通过环境变量
GOOGLE_APPLICATION_CREDENTIALS指向该文件; - 建议同步安装并登录 Google Cloud SDK,便于后续在本地通过
gcloud管理凭据。
完成认证后,faces.py 中的vision.ImageAnnotatorClient()才能无参数直接构造客户端——它会自动从环境凭据中读取身份信息。
2.2 克隆仓库并创建虚拟环境
从仓库检出代码后,进入示例目录。示例源码兼容 Python 2.7 与 3.4+;结合 requirements.txt 中的版本约束(pillow==12.3.0; python_version >= "3.10"),实际推荐在 Python 3.10+ 环境下运行。
# 进入仓库后切换到示例目录 cd vision/snippets/face_detection # 创建并激活虚拟环境(如尚未安装 virtualenv,先 pip install virtualenv) virtualenv env source env/bin/activate # 安装运行依赖 pip install -r requirements.txt安装的依赖版本(见 requirements.txt):
google-cloud-vision==3.8.1:Vision API 官方 Python 客户端;pillow==12.3.0(Python 3.10+):用于打开图片、绘制方框与保存输出。
三、运行示例:命令行参数详解
激活虚拟环境后,直接运行:
python faces.py程序会打印完整的命令行帮助,与仓库中 README.rst 记录的一致:
usage: faces.py [-h] [--out OUTPUT] [--max-results MAX_RESULTS] input_image Detects faces in the given image. positional arguments: input_image the image you'd like to detect faces in. optional arguments: -h, --help show this help message and exit --out OUTPUT the name of the output file. --max-results MAX_RESULTS the max results of face detection.各参数在 faces.py 的argparse定义中一一对应:
| 参数 | 含义 | 默认值 | 类型 |
|---|---|---|---|
input_image(位置参数) | 待检测人脸的本地图片路径,必填 | 无 | str |
--out | 输出图片文件名(绘制方框后保存) | out.jpg | str |
--max-results | 最多返回的人脸检测结果数量 | 4 | int |
一个完整的调用示例:
python faces.py ./my_photo.jpg --out ./annotated.jpg --max-results 10程序运行后会输出两行信息:检测到的人脸数量(如Found 3 faces)与输出文件名(Writing to file out.jpg),随后在当前目录生成带绿色方框的标注图片。
四、源码拆解:faces.py 的三层实现
faces.py 将整个流程拆成三个职责清晰的函数,彼此通过main串联。
4.1 发送检测请求:detect_face()
detect_face() 负责调用 Vision API:
def detect_face(face_file, max_results=4): client = vision.ImageAnnotatorClient() content = face_file.read() image = vision.Image(content=content) return client.face_detection(image=image, max_results=max_results).face_annotations关键点:
vision.ImageAnnotatorClient()是 Vision API 的统一入口客户端,通过face_detection()方法发起人脸检测请求;- 图片以二进制内容通过
vision.Image(content=content)传入,face_file是一个文件类对象(file-like object),因此调用方需要以二进制模式打开文件; max_results控制最多返回的人脸数,与命令行参数--max-results直接对应;- 返回的
face_annotations是FaceAnnotation对象列表,每个对象包含bounding_poly(人脸边界多边形)与detection_confidence(检测置信度)等字段。
4.2 绘制结果:highlight_faces()
highlight_faces() 使用 Pillow 完成可视化:
def highlight_faces(image, faces, output_filename): im = Image.open(image) draw = ImageDraw.Draw(im) for face in faces: box = [(vertex.x, vertex.y) for vertex in face.bounding_poly.vertices] draw.line(box + [box[0]], width=5, fill="#00ff00") draw.text( ( (face.bounding_poly.vertices)[0].x, (face.bounding_poly.vertices)[0].y - 30, ), str(format(face.detection_confidence, ".3f")) + "%", fill="#FF0000", ) im.save(output_filename)实现细节值得展开:
- 方框绘制:把
face.bounding_poly.vertices(四个角点)转换为(x, y)坐标列表,draw.line(box + [box[0]], ...)通过把首点追加到末尾,形成闭合的四边形边框;线条宽度为 5 像素,颜色为绿色#00ff00; - 置信度标注:取左上角顶点
vertices[0],在其上方 30 像素处用红色#FF0000文本绘制检测置信度,格式为保留三位小数的百分比字符串(如0.972%); - 输出保存:
im.save(output_filename)把标注后的图片写回磁盘,默认文件名即out.jpg。
4.3 主流程串联:main()
main() 负责文件管理与流程编排:
def main(input_filename, output_filename, max_results): with open(input_filename, "rb") as image: faces = detect_face(image, max_results) print("Found {} face{}".format(len(faces), "" if len(faces) == 1 else "s")) print(f"Writing to file {output_filename}") image.seek(0) highlight_faces(image, faces, output_filename)注意其中两个容易被忽略的细节:
- 文件指针重置:
detect_face读取文件后,文件指针已到末尾,因此在把同一文件对象传给highlight_faces前必须调用image.seek(0)回到文件开头,否则 Pillow 会读到空内容; - 单复数文案:
"Found {} face{}".format(len(faces), "" if len(faces) == 1 else "s")根据检测数量自动输出face或faces,保证输出语句通顺。
入口部分(faces.py)则通过argparse完成参数解析:--out的dest="output"将参数映射到main的output_filename,--max-results的type=int保证解析为整数并传给main(args.input_image, args.output, args.max_results)。
五、从源码结构看:FaceAnnotation 的更多可用信息
本示例只使用了bounding_poly与detection_confidence两个字段,但仓库内 vision/snippets/detect/detect.py 的detect_faces()展示了 FaceAnnotation 对象的更多属性,可直接作为扩展参考:
- 情感倾向概率:
face.anger_likelihood、face.joy_likelihood、face.surprise_likelihood等字段,取值来自google.cloud.vision.enums的似然度枚举(UNKNOWN、VERY_UNLIKELY、UNLIKELY、POSSIBLE、LIKELY、VERY_LIKELY); - 边界坐标:
face.bounding_poly.vertices每个顶点的(x, y),与 faces.py 中绘制方框用的是同一字段; - 错误处理范式:detect.py 在遍历结果后检查
response.error.message,若非空则抛出带错误提示的Exception——这是调用 Vision API 时推荐保留的防御性写法; - GCS/URL 图片:detect_faces_uri() 展示了另一种输入方式:不传二进制内容,而是通过
image.source.image_uri = uri指定 Google Cloud Storage 对象或公开网页图片地址,适合大图或远程资源的场景。
从源码结构看,faces.py的detect_face与detect.py的detect_faces调用的是同一个底层方法client.face_detection(...),区别仅在于对响应结果的使用方式——前者侧重空间可视化,后者侧重属性打印。开发者可以按需组合这两套字段,实现"画框 + 打印情绪标签"的增强版本。
六、测试验证:faces_test.py 如何证明功能正确
faces_test.py 用 pytest 编写了一个端到端冒烟测试,逻辑设计非常直观:
def test_main(tmpdir): out_file = os.path.join(tmpdir.dirname, "face-output.jpg") in_file = os.path.join(RESOURCES, "face-input.jpg") # 输入图片中不应存在绿色像素(纯 (0, 255, 0)) im = Image.open(in_file) greens = sum(1 for (r, g, b) in im.getdata() if r == 0 and g == 255 and b == 0) assert greens < 1 main(in_file, out_file, 10) # 输出图片中应出现足够多的绿色像素(方框已绘制) im = Image.open(out_file) greens = sum(1 for (r, g, b) in im.getdata() if r == 0 and g == 255 and b == 0) assert greens > 10测试要点:
- 前置校验:先遍历输入图片像素,断言绿色像素数小于 1,确保输入图本身不含
#00ff00绿色,从而避免误判; - 执行主流程:调用
main(in_file, out_file, 10),即用--max-results 10的语义处理resources下的face-input.jpg; - 后置断言:再统计输出图片的绿色像素数,断言大于 10——只要
highlight_faces成功画出了绿色方框(width=5 的闭合四边形),该条件必然满足。
该测试同时验证了检测链路(Vision API 请求成功、返回了人脸)与绘图链路(Pillow 正确保存标注图)。运行测试只需安装测试依赖后执行pytest(依赖版本见 requirements-test.txt)。需要注意的是,此类测试会真实调用 Cloud Vision API,因此需要有效的认证凭据;noxfile_config.py 中通过ignored_versions排除了 Python 3.8、3.9、3.11、3.12、3.13,仅保留特定版本用于 CI 测试矩阵。
七、常见问题与使用限制
结合源码与仓库配置,运行本示例时需留意以下几点:
- 认证缺失导致调用失败:
vision.ImageAnnotatorClient()在无可用凭据时会抛出异常,务必先完成 2.1 节的认证设置; - 输入图片格式:
detect_face直接读取文件二进制内容,Vision API 支持 JPEG、PNG、GIF、BMP、WEBP、RAW、ICO、PDF、TIFF 等常见格式; - 输出目录权限:
highlight_faces会把结果写入当前工作目录(默认文件名out.jpg),确保运行目录可写; - max_results 语义:该参数限制单次请求最多返回的人脸数,若图片中人脸超过该值,超出部分不会被处理,也不会出现在方框标注中;
- 网络依赖:每次运行都需要访问 Cloud Vision API 服务,离线环境无法使用;图片过大的场景可考虑先上传到 GCS,再改用
detect_faces_uri式的 URI 输入(参考 detect.py)。
八、小结
从 README.rst 的一句话示例说明出发,结合 faces.py 的实现与 faces_test.py 的验证,本示例完整覆盖了"鉴权 → 构造客户端 → 发送人脸检测请求 → 解析 FaceAnnotation → 用 Pillow 可视化 → 测试回归"的整条链路。它既是 Cloud Vision API 人脸检测功能的最小可运行范例,也是学习 Vision API 客户端编程范式(ImageAnnotatorClient+ 响应注解对象)的入门教材。在此基础上,读者完全可以参照 detect.py 中的情感似然度字段与错误处理模板,将示例扩展为带情绪分析、多图批量处理甚至人脸裁剪入库的实战工具。
- 示例工程
【免费下载链接】python-docs-samples
Code samples used on cloud.google.com
相关推荐
如何从零搭好 Source SDK 2013:一份能直接上手的完整 Mod 开发指南
如何从零搭好 Source SDK 2013:一份能直接上手的完整 Mod 开发指南 Source SDK 2013 是 Valve 开源的 Source 游戏
示例工程python-docs-samples 实战:基于 Google Cloud Endpoints 的 Python Echo API 从本地调试到生产部署全指南
python docs samples 实战:基于 Google Cloud Endpoints 的 Python Echo API 从本地调试到生产部署全指南
示例工程Google Cloud Monitoring Alerting API 实战指南:基于 python-docs-samples 的告警策略全生命周期管理
Google Cloud Monitoring Alerting API 实战指南:基于 python docs samples 的告警策略全生命周期管理 本篇
示例工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考