flask+YOLOv5網頁攝像頭檢測:解決檢測框顯示問題
本文針對使用Flask和YOLOv5構建的html網頁應用中,攝像頭檢測框無法顯示的問題,提供詳細的排查步驟和代碼分析。
前端代碼 (HTML & JavaScript):
<div class="row" style="padding:3%;"> <div class="col-lg-6"> <h5>輸入視頻:</h5> <video autoplay="" id="video"></video> </div> <div class="col-lg-6"> <h5>檢測結果:</h5> @@##@@ </div> </div> <script> function start() { navigator.mediaDevices.getUserMedia({ video: true }) .then(stream => { const video = document.querySelector('video'); video.srcObject = stream; const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); setInterval(() => { const videoWidth = video.videoWidth; const videoHeight = video.videoHeight; canvas.width = videoWidth; canvas.height = videoHeight; ctx.drawImage(video, 0, 0, videoWidth, videoHeight); const imageData = canvas.toDataURL('image/png', 1); // 壓縮圖片 $.ajax({ type: 'POST', url: '/image_data', data: { id: $("#uid").val(), image_data: imageData }, success: response => console.log(response) }); }, 1000 / 30); // 每秒30幀 }) .catch(error => console.error(error)); $("#res").attr("src", "/img_feed?id=" + $("#uid").val()); } </script>
后端代碼 (python – Flask):
import cv2 import time import io import base64 from flask import Flask, request, Response, render_template app = Flask(__name__) # 假設 'd' 是你的 YOLOv5 檢測對象 # d = ... # 你的 YOLOv5 模型加載代碼 # 視頻流生成器 def gen(path): cap = cv2.VideoCapture(path) while cap.isOpened(): try: start_time = time.time() success, frame = cap.read() if success: im, label, c = d.detect(frame) # YOLOv5 檢測 ret, jpeg = cv2.imencode('.png', im) if ret: frame = jpeg.tobytes() elapsed_time = time.time() - start_time print(f"Processing time: {elapsed_time:.3f} seconds") yield (b'--framern' b'Content-Type: image/jpegrnrn' + frame + b'rnrn') else: break else: break except Exception as e: print(e) continue cap.release() # 視頻流路由 @app.route('/video_feed') def video_feed(): f = request.args.get("f") print(f'Processing video: upload/{f}') return Response(gen(f'upload/{f}'), mimetype='multipart/x-mixed-replace; boundary=frame') # 圖片數據處理路由 @app.route('/image_data', methods=['POST']) def image_data(): image_data = request.form.get('image_data') user_id = request.form.get('id') image_data = io.BytesIO(base64.b64decode(image_data.split(',')[1])) img = Image.open(image_data) # PIL Image img.save(f'upload/temp{user_id}.png') return "ok" if __name__ == '__main__': app.run(debug=True)
問題排查:
立即學習“前端免費學習筆記(深入)”;
-
攝像頭路徑: cv2.VideoCapture(path) 中的 path 必須正確。對于默認攝像頭,通常是 0;如果是RTSP流,則使用RTSP地址;如果是文件,則使用完整路徑。確保f變量在/video_feed路由中正確傳遞了視頻源路徑。
-
錯誤信息: 仔細檢查控制臺的錯誤信息,這能幫助你快速定位問題。
-
文件路徑: 使用絕對路徑避免相對路徑導致的錯誤。
-
接口調用: 前端代碼必須正確調用 /video_feed 接口,例如:$(“#res”).attr(“src”, “/video_feed?f=” + $(“#uid”).val()); 確保$(“#uid”).val()返回正確的文件名或攝像頭標識符。
-
YOLOv5 模型: 確保YOLOv5模型正確加載并能夠進行檢測。 d.detect(frame)這一行是關鍵,檢查模型是否正確預測并返回處理后的圖像。
-
圖像編碼: 確認cv2.imencode(‘.png’, im)正確編碼圖像。 嘗試使用.jpg編碼,查看是否有區別。
-
前后端數據類型: 確保前后端數據類型匹配。前端發送的是base64編碼的圖像數據,后端需要正確解碼。
通過仔細檢查以上步驟,并結合控制臺錯誤信息,你應該能夠找到并解決檢測框顯示問題。 記得安裝必要的庫:opencv-python, pillow, flask, requests。 同時,確保你的YOLOv5模型已經成功運行,并且能夠正確地處理圖像并返回檢測結果。