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

如何修复TensorFlow目标检测报OSError: invalid face handle错误

问题背景

实操TensorFlow实时目标检测教程到最终摄像头推理环节时,程序抛出OSError: invalid face handle错误,沿调用链路排查后,初步怀疑ImageFont.py文件内size, offset = self.font.getsize(text, "L", direction, features, language)行是报错触发点。

复现代码
import cv2 
import numpy as np
import os
from object_detection.utils import label_map_util
from object_detection.utils import visualization_utils as viz_utils
from object_detection.utils import config_util
from object_detection.builders import model_builder 
import tensorflow as tf
from object_detection.utils import config_util
from object_detection.protos import pipeline_pb2
from google.protobuf import text_format

WORKSPACE_PATH = 'Tensorflow/workspace'
SCRIPTS_PATH = 'Tensorflow/scripts'
APIMODEL_PATH = 'Tensorflow/models'
ANNOTATION_PATH = WORKSPACE_PATH+'/annotations'
IMAGE_PATH = WORKSPACE_PATH+'/images'
MODEL_PATH = WORKSPACE_PATH+'/models'
PRETRAINED_MODEL_PATH = WORKSPACE_PATH+'/pre-trained-models'
CONFIG_PATH = MODEL_PATH+'/my_ssd_mobnet/pipeline.config'
CHECKPOINT_PATH = MODEL_PATH+'/my_ssd_mobnet/'

CUSTOM_MODEL_NAME = 'my_ssd_mobnet' 

CONFIG_PATH = MODEL_PATH+'/'+CUSTOM_MODEL_NAME+'/pipeline.config'

# 加载管线配置、构建检测模型
configs = config_util.get_configs_from_pipeline_file(CONFIG_PATH)
detection_model = model_builder.build(model_config=configs['model'], is_training=False)

# 恢复检查点
ckpt = tf.compat.v2.train.Checkpoint(model=detection_model)
ckpt.restore(os.path.join(CHECKPOINT_PATH, 'ckpt-11')).expect_partial()

@tf.function
def detect_fn(image):
    image, shapes = detection_model.preprocess(image)
    prediction_dict = detection_model.predict(image, shapes)
    detections = detection_model.postprocess(prediction_dict, shapes)
    return detections

cap = cv2.VideoCapture(0)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
category_index = label_map_util.create_category_index_from_labelmap(ANNOTATION_PATH+'/label_map.pbtxt')
while True: 
    ret, frame = cap.read()
    image_np = np.array(frame)
    
    input_tensor = tf.convert_to_tensor(np.expand_dims(image_np, 0), dtype=tf.float32)
    detections = detect_fn(input_tensor)
    
    num_detections = int(detections.pop('num_detections'))
    detections = {key: value[0, :num_detections].numpy()
                  for key, value in detections.items()}
    detections['num_detections'] = num_detections

    # 检测类别需转为整型
    detections['detection_classes'] = detections['detection_classes'].astype(np.int64)

    label_id_offset = 1
    image_np_with_detections = image_np.copy()

    viz_utils.visualize_boxes_and_labels_on_image_array(
                image_np_with_detections,
                detections['detection_boxes'],
                detections['detection_classes']+label_id_offset,
                detections['detection_scores'],
                category_index,
                use_normalized_coordinates=True,
                max_boxes_to_draw=5,
                min_score_thresh=.5,
                agnostic_mode=False)

    cv2.imshow('object detection',  cv2.resize(image_np_with_detections, (800, 600)))
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        cap.release()
        break
报错堆栈
Traceback (most recent call last):
  File "c:/Users/Rohan/Desktop/facial recognition/RealTimeObjectDetection-main/RealTimeObjectDetection-main/test.py", line 73, in <module>
    agnostic_mode=False)
  File "C:\Users\Rohan\AppData\Local\Programs\Python\Python37\lib\site-packages\object_detection\utils\visualization_utils.py", line 1259, in visualize_boxes_and_labels_on_image_array
    use_normalized_coordinates=use_normalized_coordinates)
  File "C:\Users\Rohan\AppData\Local\Programs\Python\Python37\lib\site-packages\object_detection\utils\visualization_utils.py", line 162, in draw_bounding_box_on_image_array
    use_normalized_coordinates)
  File "C:\Users\Rohan\AppData\Local\Programs\Python\Python37\lib\site-packages\object_detection\utils\visualization_utils.py", line 219, in draw_bounding_box_on_image
    display_str_heights = [font.getsize(ds)[1] for ds in display_str_list]
  File "C:\Users\Rohan\AppData\Local\Programs\Python\Python37\lib\site-packages\object_detection\utils\visualization_utils.py", line 219, in <listcomp>
    display_str_heights = [font.getsize(ds)[1] for ds in display_str_list]
  File "C:\Users\Rohan\AppData\Local\Programs\Python\Python37\lib\site-packages\PIL\ImageFont.py", line 414, in getsize
    size, offset = self.font.getsize(text, "L", direction, features, language)
OSError: invalid face handle
故障原因

该错误由Pillow库版本和TensorFlow目标检测API的可视化模块字体加载逻辑不兼容导致:高版本Pillow加载默认字体失败时会返回无效的字体句柄,后续调用getsize()方法计算文本尺寸时就会触发invalid face handle报错。

解决方案
  • 方案一:降级Pillow到兼容版本,执行命令pip install pillow==8.4.0,安装完成后重新运行脚本即可正常显示检测框和标签。
  • 方案二:手动修改可视化工具的字体加载逻辑,找到本地visualization_utils.py文件中draw_bounding_box_on_image函数内加载字体的代码段,显式指定系统内存在的有效ttf字体路径,比如Windows系统可替换为加载C:/Windows/Fonts/arial.ttf,避免加载无效默认字体。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 10:33:18