You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用谷歌Vision API做人脸检测时如何在Python中通过GUI展示图像

完整可运行修改代码

import tkinter as tk
from PIL import Image, ImageTk
from tkinter.filedialog import askopenfile
import io
import os
from google.cloud import vision

root = tk.Tk()
root.title("人脸情绪识别")
canvas = tk.Canvas(root, width=600, height=300)
canvas.grid(columnspan=3, rowspan=3)

os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = r'crack-producer-313920-5e16fbab8c24.json'

client = vision.ImageAnnotatorClient()
file_name = os.path.abspath('picture.jpg')

with io.open(file_name, 'rb') as image_file:
    content = image_file.read()
    
image = vision.Image(content=content)
response = client.face_detection(image=image)
faces = response.face_annotations

likelihood_name = ('UNKNOWN', 'VERY_UNLIKELY', 'UNLIKELY', 'POSSIBLE',
                'LIKELY', 'VERY_LIKELY')
print('Faces:')

for face in faces:
    print('anger: {}'.format(likelihood_name[face.anger_likelihood]))
    print('joy: {}'.format(likelihood_name[face.joy_likelihood]))
    print('surprise: {}'.format(likelihood_name[face.surprise_likelihood]))

    vertices = (['({},{})'.format(vertex.x, vertex.y)
                for vertex in face.bounding_poly.vertices])

    print('face bounds: {}'.format(','.join(vertices)))

if response.error.message:
    raise Exception(
        '{}\nFor more info on error messages, check: '
        'https://cloud.google.com/apis/design/errors'.format(
            response.error.message))

# ------------------- 新增GUI图片渲染逻辑 -------------------
# 加载原始图片
pil_img_raw = Image.open(file_name)
orig_w, orig_h = pil_img_raw.size
# 缩放图片适配画布尺寸,保持原始比例
pil_img = pil_img_raw.copy()
pil_img.thumbnail((600, 300))
new_w, new_h = pil_img.size
# 计算坐标缩放比例
x_ratio = new_w / orig_w
y_ratio = new_h / orig_h

# 转换为Tkinter支持的图片格式
tk_img = ImageTk.PhotoImage(pil_img)
# 绑定到canvas属性,避免图片被Python垃圾回收导致不显示
canvas.tk_img = tk_img
# 绘制图片到画布左上角
canvas.create_image(0, 0, anchor=tk.NW, image=tk_img)

# 可选:绘制人脸框和情绪结果到GUI
for idx, face in enumerate(faces):
    v = face.bounding_poly.vertices
    # 转换原始坐标为适配缩放后图片的坐标
    x1, y1 = int(v[0].x * x_ratio), int(v[0].y * y_ratio)
    x2, y2 = int(v[2].x * x_ratio), int(v[2].y * y_ratio)
    # 画红色人脸边框
    canvas.create_rectangle(x1, y1, x2, y2, outline='red', width=2)
    # 拼接情绪文本
    emotion_info = f"#{idx+1} 喜:{likelihood_name[face.joy_likelihood]} 怒:{likelihood_name[face.anger_likelihood]} 惊:{likelihood_name[face.surprise_likelihood]}"
    # 文本绘制在人脸框上方
    canvas.create_text(x1, y1-8, anchor=tk.SW, text=emotion_info, fill='red', font=('黑体',9))

root.mainloop()

关键改动说明

  • grid() 是Tkinter的布局方法,仅负责控制组件在父容器中的位置,本身不需要绑定额外变量,之前无法显示是因为没有把图片内容渲染到已布局好的Canvas组件上
  • 必须将ImageTk.PhotoImage生成的图片对象绑定到一个长期存在的变量/实例属性上,否则会被Python垃圾回收机制清理,导致界面看不到图片
  • 新增的坐标缩放逻辑适配了图片缩放后的尺寸,保证人脸框位置和实际人脸位置对齐
  • 可选的人脸框和情绪文本绘制逻辑可以直接在GUI上展示识别结果,无需再查看终端输出

内容的提问来源于stack exchange,提问作者Filzo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 07:36:05