Yolov8 TFLite模型Python测试大量误检person问题求助
解决Yolov8 TFLite模型误检大量Person问题
问题场景
将Yolov8e导出为TFLite模型后,在Python中测试时,模型将图片中仅有的2人识别为上百个置信度70%-100%的person,出现严重误检。
核心问题与修复方案
1. 图像预处理不符合Yolov8要求
Yolov8模型要求输入图像进行归一化处理(通常是将像素值除以255缩放到0-1区间),当前代码直接使用img_to_array得到0-255的像素值,未做归一化,导致模型输入异常。
修改预处理代码:
# Load and preprocess the image image_path = "C:\\Users\\Downloads\\2.jpeg" image = tf.keras.preprocessing.image.load_img(image_path, target_size=(640, 640)) image_array = tf.keras.preprocessing.image.img_to_array(image) # 添加归一化:将0-255的像素值缩放到0-1区间 preprocessed_image = np.expand_dims(image_array / 255.0, axis=0) # 若模型导出时使用了--half参数,可尝试[-1,1]范围归一化: # preprocessed_image = np.expand_dims((image_array / 127.5) - 1, axis=0)
2. NMS非极大值抑制代码位置错误
将cv2.dnn.NMSBoxes放在遍历候选框的for循环内部,会导致每遍历一个框就执行一次NMS,无法有效过滤重复框,产生大量冗余检测结果。
调整代码位置:
将NMS代码移到for循环外部,收集完所有候选框后再执行:
boxes = [] scores = [] class_ids = [] for i in range(rows): classes_scores = outputs[0][i][4:] (minScore, maxScore, minClassLoc, (x, maxClassIndex)) = cv2.minMaxLoc(classes_scores) if maxScore >= 0.60: box = [outputs[0][i][0] - (0.5 * outputs[0][i][2]), outputs[0][i][1] - (0.5 * outputs[0][i][3]), outputs[0][i][2], outputs[0][i][3]] boxes.append(box) scores.append(maxScore) class_ids.append(maxClassIndex) # 将NMS代码移至for循环外部 result_boxes = cv2.dnn.NMSBoxes(boxes, scores, 0.25, 0.45, 0.5) detections = [] # 适配不同OpenCV版本的NMS返回格式 if len(result_boxes) > 0: if isinstance(result_boxes[0], list): result_boxes = [i[0] for i in result_boxes] for index in result_boxes: box = boxes[index] detection = { 'class_id': class_ids[index], 'class_name': CLASSES[class_ids[index]], 'confidence': scores[index], 'box': box, 'scale': scale} if CLASSES[class_ids[index]] == 'person': detections.append(detection) draw_bounding_box(original_image, class_ids[index], scores[index], round(box[0] * scale), round(box[1] * scale), round((box[0] + box[2]) * scale), round((box[1] + box[3]) * scale))
3. 输出张量解析逻辑适配Yolov8格式
Yolov8的TFLite模型输出格式为(1, num_classes + 4, 8400),前4个值是边界框的(x, y, w, h),后面是类别置信度,当前转置操作导致维度顺序错误。
修正输出解析:
# 获取输出张量并调整维度顺序 output_tensor = interpreter.get_tensor(output_details[0]['index']) # 转置为(1, 8400, 84),方便遍历所有锚框 outputs = np.transpose(output_tensor, (0, 2, 1)) rows = outputs.shape[1] # rows对应8400个锚框
4. 确认类别映射文件正确性
确保coco128.yml中的类别顺序和Yolov8e模型训练时的COCO数据集类别顺序完全一致(person应为第0类),可打印验证:
print(CLASSES) # 正常输出第一个元素应为'person'
额外建议
- 使用官方推荐命令导出TFLite模型,确保参数正确:
yolo export model=yolov8e.pt format=tflite imgsz=640 - 先通过Ultralytics官方代码验证模型有效性,再自行编写解析逻辑:
from ultralytics import YOLO # 加载TFLite模型 model = YOLO('yolov8e_float32.tflite') # 推理测试 results = model('C:\\Users\\Downloads\\2.jpeg') # 可视化结果 results[0].show()
内容的提问来源于stack exchange,提问作者Aleshan
相关产品推荐
相关产品推荐

