Flask集成YOLOv5应用上传图片后无法显示问题求助
问题:Flask+YOLOv5龋齿检测应用图片路径错误导致无法显示
开发基于YOLOv5的口腔龋齿检测应用时,用户上传图片后已成功保存到应用目录,但浏览器无法显示图片。打印图片URL发现路径错误,得到的路径为Image URL: /static//static/1685369990.0033317.jpg,而正确路径应为/static/[图片名].jpg。
问题原因分析
- 静态路径重复叠加:初始化Flask应用时显式设置了
static_url_path='/static',而url_for('static', ...)会自动添加默认的静态资源前缀,两者叠加导致路径出现重复的/static。 - 标签获取逻辑错误:代码中
labels = results.names[0]错误地取了类别名称字典的单个元素,会导致后续绘制 bounding box 时出现匹配异常。
解决方案及修改后的代码
核心修改点
- 移除
static_url_path='/static'的显式配置,使用Flask默认的静态路径规则 - 修正类别标签的获取逻辑,改为获取完整的类别名称字典
- 添加静态目录自动创建逻辑,避免因目录缺失导致图片保存失败
- 增加字体加载容错处理,防止缺失字体导致程序崩溃
修改后的完整代码:
import io import os import time import torch from PIL import Image, ImageDraw, ImageFont from flask import Flask, jsonify, url_for, render_template, request, redirect # 使用Flask默认静态路径配置,移除显式的static_url_path设置 app = Flask(__name__) RESULT_FOLDER = os.path.join('static') app.config['RESULT_FOLDER'] = RESULT_FOLDER # 确保静态目录存在,避免保存图片时出错 os.makedirs(RESULT_FOLDER, exist_ok=True) model = torch.hub.load('ultralytics/yolov5', 'custom', path='./best.pt') model.eval() def draw_boxes(image, boxes, labels): draw = ImageDraw.Draw(image) # 处理字体加载失败的情况,改用默认字体 try: font = ImageFont.truetype("arial.ttf", size=12) except: font = ImageFont.load_default() for box in boxes: x1, y1, x2, y2, conf, cls = box.tolist() draw.rectangle([x1, y1, x2, y2], outline='red', width=2) # 根据类别ID获取对应标签名称 label_name = labels[int(cls)] text = f'{label_name}: {conf:.2f}' text_width, text_height = font.getsize(text) draw.rectangle([x1, y1 - text_height, x1 + text_width, y1], fill='red') draw.text((x1, y1 - text_height), text, fill='white', font=font) return image def get_prediction(img_bytes): img = Image.open(io.BytesIO(img_bytes)) imgs = [img] # batched list of images # 模型推理 results = model(imgs, size=640) # 包含NMS处理 boxes = results.xyxy[0] # 获取边界框数据 labels = results.names # 获取完整类别名称字典 # 在原图上绘制边界框和标签 img_with_boxes = draw_boxes(img, boxes, labels) return img_with_boxes, boxes @app.route('/', methods=['GET', 'POST']) def predict(): if request.method == 'POST': if 'file' not in request.files: return redirect(request.url) file = request.files.get('file') if not file: return img_bytes = file.read() try: img_with_boxes, boxes = get_prediction(img_bytes) img_name = str(time.time()) + '.jpg' img_path = os.path.join(app.config['RESULT_FOLDER'], img_name) img_with_boxes.save(img_path) # 生成正确的静态资源URL image_url = url_for('static', filename=img_name) print("Image URL:", image_url) return render_template('test.html', result_image= image_url) except Exception as e: print(str(e)) # 打印异常用于调试 return render_template('error.html', error=str(e)) return render_template('index.html') if __name__ == '__main__': app.run(debug=True)
内容的提问来源于stack exchange,提问作者Shad
相关产品推荐
相关产品推荐

