AI计算机视觉笔记三:WEB端部署YOLOv5

本文涉及的产品
视觉智能开放平台,分割抠图1万点
视觉智能开放平台,图像资源包5000点
视觉智能开放平台,视频资源包5000点
简介: 本文档介绍了如何将YOLOv5目标检测模型部署到Web端的方法,包括基于Flask和Streamlit两种实现方案。首先创建Python虚拟环境并安装必要的依赖库。接着详细展示了Flask方案下的前端HTML页面与后端Python逻辑代码,该方案利用Flask框架搭建服务器,处理实时视频流,并显示检测结果。随后介绍了Streamlit方案,该方案更简洁直观,适合快速开发交互式的机器学习应用。通过`streamlit run`命令即可启动应用,支持图像、视频及实时摄像头的目标检测演示。两种部署方式各有优势,Flask灵活性高,适用于复杂项目;而Streamlit则易于上手,便于快速原型设计。

一、介绍

最近接触网页大屏,所以就想把YOLOV5部署到WEB端,通过了解,知道了两个方法:

1、基于Flask部署YOLOv5目标检测模型。

2、基于Streamlit部署YOLOv5目标检测。

代码在github上,个人感觉两个比较好的,所以基于两份代码测试。

https://github.com/ngzhili/Yolov5-Real-Time-Object-Detection

GitHub - harshit-tech03/Fire_Detection: A fire detection web app using yolov5.

一、虚拟环境创建

1、创建虚拟环境

conda create -n yolov5_env python=3.8

2、激活环境

conda activate yolov5_env

3、下载yolov5

https://github.com/ultralytics/yolov5

4、安装yolov5

pip install -r requirements.txt

注意以下测试都是基于此环境测试

二、基于Flask部署YOLOv5目标检测模型。

1、安装环境

requirements.txt

flask
requests
black

matplotlib>=3.2.2
numpy>=1.18.5
opencv-python>=4.1.2
Pillow
PyYAML>=5.3.1
scipy>=1.4.1
torch>=1.7.0
torchvision>=0.8.1
tqdm>=4.41.0

tensorboard>=2.4.1

seaborn>=0.11.0
pandas

thop  # FLOPs computation

代码感觉相对简单,而且也挺详细的,所以直接上代码。

2、前端代码

index.html


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">

    <title>YOLOV5 Real Time Inference</title>
    <style>
      .corner {
        border-radius: 25px;
        border: 5px solid #212aad;
        padding: 0px;
        width:60%;
        height:auto;
        text-align: center;
      }

      .video-container {
        justify-content: center;
        text-align: center;
        height:100%;
        /*border: 1px solid black;*/
      }

    </style>
  </head>

  <body >
      <div class="container">
        <div class="row" style="text-align: center; width:100%;">
          <img src="../static/pytorch.png" style="width:40px; position:relative; left: -10px; display:inline-block;">
            <h1 style="text-align: center; display:inline-block;">Template for YOLOV5 Object Detection Model Real-Time Inference Using Web Cam</h1>
          </img>
          <h2 style="text-align: center;">Built by Zhili</h2>
        </div>
      </div>

      <div class="video-container">
          <img src="{
  
  { url_for('video') }}" class="corner"></img>
          <!--<img src="../static/pytorch.png" class="corner"></img>-->
          <!--<img src="{
  
  { url_for('video') }}" width="50%"/>-->
      </div>
    </body>
</html>

3、后端代码

app.py

"""
Simple app to upload an image via a web form 
and view the inference results on the image in the browser.
"""
import argparse
import io
import os
from PIL import Image
import cv2
import numpy as np

import torch
from flask import Flask, render_template, request, redirect, Response

app = Flask(__name__)


#'''
# Load Pre-trained Model
#model = torch.hub.load(
#        "ultralytics/yolov5", "yolov5s", pretrained=True, force_reload=True
#        )#.autoshape()  # force_reload = recache latest code
#'''
# Load Custom Model
#model = torch.hub.load("ultralytics/yolov5", "custom", path = "./best_damage.pt", force_reload=True)
model = torch.hub.load('./yolov5', 'custom', './yolov5s.pt',source='local')
# Set Model Settings
model.eval()
model.conf = 0.6  # confidence threshold (0-1)
model.iou = 0.45  # NMS IoU threshold (0-1) 

from io import BytesIO

def gen():
    cap=cv2.VideoCapture(0)
    # Read until video is completed
    while(cap.isOpened()):

        # Capture frame-by-fram ## read the camera frame
        success, frame = cap.read()
        if success == True:

            ret,buffer=cv2.imencode('.jpg',frame)
            frame=buffer.tobytes()

            #print(type(frame))

            img = Image.open(io.BytesIO(frame))
            results = model(img, size=640)
            #print(results)
            #print(results.pandas().xyxy[0])
            #results.render()  # updates results.imgs with boxes and labels
            results.print()  # print results to screen
            #results.show() 
            #print(results.imgs)
            #print(type(img))
            #print(results)
            #plt.imshow(np.squeeze(results.render()))
            #print(type(img))
            #print(img.mode)

            #convert remove single-dimensional entries from the shape of an array
            img = np.squeeze(results.render()) #RGB
            # read image as BGR
            img_BGR = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) #BGR

            #print(type(img))
            #print(img.shape)
            #frame = img
            #ret,buffer=cv2.imencode('.jpg',img)
            #frame=buffer.tobytes()
            #print(type(frame))
            #for img in results.imgs:
                #img = Image.fromarray(img)
            #ret,img=cv2.imencode('.jpg',img)
            #img=img.tobytes()

            #encode output image to bytes
            #img = cv2.imencode('.jpg', img)[1].tobytes()
            #print(type(img))
        else:
            break
        #print(cv2.imencode('.jpg', img)[1])

        #print(b)
        #frame = img_byte_arr

        # Encode BGR image to bytes so that cv2 will convert to RGB
        frame = cv2.imencode('.jpg', img_BGR)[1].tobytes()
        #print(frame)

        yield(b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')


@app.route('/')
def index():

    return render_template('index.html')

@app.route('/video')
def video():
    """Video streaming route. Put this in the src attribute of an img tag."""

    return Response(gen(),
                        mimetype='multipart/x-mixed-replace; boundary=frame')
'''                        
@app.route('/video')
def video():
    return Response(generate_frames(),mimetype='multipart/x-mixed-replace; boundary=frame')
'''
'''
@app.route("/", methods=["GET", "POST"])
def predict():
    if request.method == "POST":
        if "file" not in request.files:
            return redirect(request.url)
        file = request.files["file"]
        if not file:
            return
        img_bytes = file.read()
        img = Image.open(io.BytesIO(img_bytes))
        results = model(img, size=640)
        # for debugging
        # data = results.pandas().xyxy[0].to_json(orient="records")
        # return data
        results.render()  # updates results.imgs with boxes and labels
        for img in results.imgs:
            img_base64 = Image.fromarray(img)
            img_base64.save("static/image0.jpg", format="JPEG")
        return redirect("static/image0.jpg")
    return render_template("index.html")
'''

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Flask app exposing yolov5 models")
    parser.add_argument("--port", default=5000, type=int, help="port number")
    args = parser.parse_args()
    '''
    model = torch.hub.load(
        "ultralytics/yolov5", "yolov5s", pretrained=True, force_reload=True
    ).autoshape()  # force_reload = recache latest code
    model.eval()
    '''
    app.run(host="0.0.0.0", port=args.port)  # debug=True causes Restarting with stat

# Docker Shortcuts
# docker build --tag yolov5 .
# docker run --env="DISPLAY" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" --device="/dev/video0:/dev/video0" yolov5

4、运行结果

执行python app.py

image.png

image.png

三、基于Streamlit部署YOLOv5目标检测。

1、什么是Streamlit

Streamlit 是一个用于数据科学和机器学习的开源 Python 框架。它提供了一种简单的方式来构建交互式应用程序,使数据科学家和机器学习工程师可以更轻松地将他们的模型展示给其他人。

以下是 Streamlit 常用的一些方法:

st.write():打印文本、数据框、图表等。
st.title():创建标题。
st.header():创建大标题。
st.subheader():创建小标题。
st.text():打印文本。
st.markdown():打印 Markdown 文本。
st.latex():打印 LaTeX 公式。
st.dataframe():显示数据框。
st.table():显示表格。
st.line_chart():创建线形图。
st.area_chart():创建面积图。
st.bar_chart():创建条形图。
st.map():创建地图。
st.pyplot():显示 Matplotlib 图表。
st.altair_chart():显示 Altair 图表。
st.vega_lite_chart():显示 Vega-Lite 图表。
st.bokeh_chart():显示 Bokeh 图表。
st.plotly_chart():显示 Plotly 图表。
st.image():显示图像。
st.audio():显示音频。
st.video():显示视频。
st.file_uploader():上传文件。
st.download_button():下载文件。
以上是 Streamlit 的一些常用方法,可以根据需要选择使用。

只能説Streamlit比Flask更简单,更容易看懂。

在上面环境的基础上在安装一次环境

2、安装环境

requirements.txt

yolov5
opencv_python_headless
streamlit
numpy
Pillow
torch
torchvision
PyYAML
tqdm
matplotlib
requests
scipy
tensorboard
pandas
seaborn
streamlit-webrtc
IPython

3、代码

代码不分前后端

Fire_Detection.py

import streamlit as st
import cv2
import numpy as np
import av
import torch
import tempfile
from PIL import Image

@st.cache
def load_model():
    model = torch.hub.load('ultralytics/yolov5','custom',path="weights/last.pt",force_reload=True)
    return model

demo_img = "fire.9.png"
demo_video = "Fire_Video.mp4"

st.title('Fire Detection')
st.sidebar.title('App Mode')


app_mode = st.sidebar.selectbox('Choose the App Mode',
                                ['About App','Run on Image','Run on Video','Run on WebCam'])

if app_mode == 'About App':
    st.subheader("About")
    st.markdown("<h5>This is the Fire Detection App created with custom trained models using YoloV5</h5>",unsafe_allow_html=True)

    st.markdown("- <h5>Select the App Mode in the SideBar</h5>",unsafe_allow_html=True)
    st.image("Images/first_1.png")
    st.markdown("- <h5>Upload the Image and Detect the Fires in Images</h5>",unsafe_allow_html=True)
    st.image("Images/second_2.png")
    st.markdown("- <h5>Upload the Video and Detect the fires in Videos</h5>",unsafe_allow_html=True)
    st.image("Images/third_3.png")
    st.markdown("- <h5>Live Detection</h5>",unsafe_allow_html=True)
    st.image("Images/fourth_4.png")
    st.markdown("- <h5>Click Start to start the camera</h5>",unsafe_allow_html=True)
    st.markdown("- <h5>Click Stop to stop the camera</h5>",unsafe_allow_html=True)

    st.markdown("""
                ## Features
- Detect on Image
- Detect on Videos
- Live Detection
## Tech Stack
- Python
- PyTorch
- Python CV
- Streamlit
- YoloV5
## 🔗 Links
[![twitter](https://img.shields.io/badge/Github-1DA1F2?style=for-the-badge&logo=github&logoColor=white)](https://github.com/AntroSafin)
""")


if app_mode == 'Run on Image':
    st.subheader("Detected Fire:")
    text = st.markdown("")

    st.sidebar.markdown("---")
    # Input for Image
    img_file = st.sidebar.file_uploader("Upload an Image",type=["jpg","jpeg","png"])
    if img_file:
        image = np.array(Image.open(img_file))
    else:
        image = np.array(Image.open(demo_img))

    st.sidebar.markdown("---")
    st.sidebar.markdown("**Original Image**")
    st.sidebar.image(image)

    # predict the image
    model = load_model()
    results = model(image)
    length = len(results.xyxy[0])
    output = np.squeeze(results.render())
    text.write(f"<h1 style='text-align: center; color:red;'>{length}</h1>",unsafe_allow_html = True)
    st.subheader("Output Image")
    st.image(output,use_column_width=True)

if app_mode == 'Run on Video':
    st.subheader("Detected Fire:")
    text = st.markdown("")

    st.sidebar.markdown("---")

    st.subheader("Output")
    stframe = st.empty()

    #Input for Video
    video_file = st.sidebar.file_uploader("Upload a Video",type=['mp4','mov','avi','asf','m4v'])
    st.sidebar.markdown("---")
    tffile = tempfile.NamedTemporaryFile(delete=False)

    if not video_file:
        vid = cv2.VideoCapture(demo_video)
        tffile.name = demo_video
    else:
        tffile.write(video_file.read())
        vid = cv2.VideoCapture(tffile.name)

    st.sidebar.markdown("**Input Video**")
    st.sidebar.video(tffile.name)

    # predict the video
    while vid.isOpened():
        ret, frame = vid.read()
        if not ret:
            break
        frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
        model = load_model()
        results = model(frame)
        length = len(results.xyxy[0])
        output = np.squeeze(results.render())
        text.write(f"<h1 style='text-align: center; color:red;'>{length}</h1>",unsafe_allow_html = True)
        stframe.image(output)

if app_mode == 'Run on WebCam':
    st.subheader("Detected Fire:")
    text = st.markdown("")

    st.sidebar.markdown("---")

    st.subheader("Output")
    stframe = st.empty()

    run = st.sidebar.button("Start")
    stop = st.sidebar.button("Stop")
    st.sidebar.markdown("---")

    cam = cv2.VideoCapture(0)
    if(run):
        while(True):
            if(stop):
                break
            ret,frame = cam.read()
            frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
            model = load_model()
            results = model(frame)
            length = len(results.xyxy[0])
            output = np.squeeze(results.render())
            text.write(f"<h1 style='text-align: center; color:red;'>{length}</h1>",unsafe_allow_html = True)
            stframe.image(output)

4、运行结果

运行指令

 streamlit run Fire_Detection.py

image.png
会自动打开网页
image.png

demo提供了图片测试,视频测试,和摄像头几个方式的测试方法。由于使用的模型是训练好的模型,所以yolo版本不能修改,只能联网下载。
image.png

如果想用自己的yolov5

那修改加载模型,改成本地加载,模型也需要修改。

image.png

四、总结

通过两个方式,个人对部署web有了个相对的简单的认识。

在此感谢github,和网友提供的代码。

相关文章
|
1天前
|
人工智能 弹性计算 运维
|
1天前
|
域名解析 人工智能 API
使用 Websoft9 面板部署 LobeChat,打造个人 AI 大脑
本书详细介绍了从服务器环境准备到LobeChat部署与维护的全过程。首先,指导用户选购云服务器并配置安全组和SSH登录;接着,通过Websoft9面板一键安装并初始化,支持域名解析。随后,重点讲解了LobeChat的部署方法,包括应用市场和手动部署,并深入探讨多模型接入及插件扩展。最后,提供了日常维护命令和常见问题解决方法,确保系统稳定运行。适合新手及进阶用户参考。
19 0
|
6天前
|
人工智能 弹性计算 自然语言处理
5分钟部署,解锁100种和AI大模型的交互可能
阿里云弹性计算推出了一套高效、易用的个人AI大模型部署方案,帮助用户快速搭建专属的AI主页,开启智能化新体验,真正的实把“AI玩出花”。
|
6天前
|
人工智能 运维 自然语言处理
2025保姆级JupyterLab 4.0安装指南|全平台部署+AI编程环境配置
JupyterLab 是下一代交互式计算开发环境,2025年发布的4.0版本新增多语言内核支持(Python/R/Julia/JavaScript一键切换)、实时协作功能、AI辅助编程(集成GPT-5代码补全与错误诊断)和可视化调试器等特性。本文详细介绍其技术定位、跨平台安装方案、安装流程、高阶功能配置、典型应用场景及故障排查指南,帮助用户高效使用JupyterLab进行开发。
|
7天前
|
人工智能 搜索推荐 安全
基于函数计算一键部署 AI 陪练,快速打造你的专属口语对练伙伴
AI 口语学习涵盖发音训练、对话交流、即时反馈、个性化场景模拟和流利度提升等。本方案以英语口语学习的场景为例,利用函数计算 FC 部署 Web 应用,结合智能媒体服务(AI 实时互动)的 AI 智能体和百炼工作流应用,实现英语口语陪练。
|
7天前
|
人工智能 弹性计算 自然语言处理
5分钟部署,解锁100种和AI大模型的交互可能
在AI技术飞速发展的今天,个人大模型的部署与应用面临复杂流程和高门槛。阿里云推出高效、易用的个人AI大模型部署方案,支持多模型集成、灵活扩展和定制化主页,帮助用户快速搭建专属AI主页,实现智能化新体验,真正把“AI玩出花”。
|
9天前
|
弹性计算 人工智能 API
部署AI网站-进阶配置
通过Open WebUI部署个人AI网站后,您可能还面临如下问题:希望使用DeepSeek R1模型对话问答时显示思考过程、 希望可以在AI网站上使用联网搜索、希望将AI网站分享给其他用户使用、希望在AI主页上使用多种模型等。本文将介绍如何通过相应配置,解决这些问题。
|
10天前
|
人工智能 弹性计算 Ubuntu
从零开始即刻拥有 DeepSeek-R1 满血版并使用 Dify 部署 AI 应用
本文介绍了如何使用阿里云提供的DeepSeek-R1大模型解决方案,通过Chatbox和Dify平台调用百炼API,实现稳定且高效的模型应用。首先,文章详细描述了如何通过Chatbox配置API并开始对话,适合普通用户快速上手。接着,深入探讨了使用Dify部署AI应用的过程,包括选购云服务器、安装Dify、配置对接DeepSeek-R1模型及创建工作流,展示了更复杂场景下的应用潜力。最后,对比了Chatbox与Dify的输出效果,证明Dify能提供更详尽、精准的回复。总结指出,阿里云的解决方案不仅操作简便,还为专业用户提供了强大的功能支持,极大提升了用户体验和应用效率。
682 18
从零开始即刻拥有 DeepSeek-R1 满血版并使用 Dify 部署 AI 应用
|
13天前
|
人工智能 安全 搜索推荐
基于函数计算一键部署 AI 陪练,快速打造你的专属口语对练伙伴
基于函数计算一键部署 AI 陪练,快速打造你的专属口语对练伙伴
|
13天前
|
人工智能 Kubernetes jenkins
容器化AI模型的持续集成与持续交付(CI/CD):自动化模型更新与部署
在前几篇文章中,我们探讨了容器化AI模型的部署、监控、弹性伸缩及安全防护。为加速模型迭代以适应新数据和业务需求,需实现容器化AI模型的持续集成与持续交付(CI/CD)。CI/CD通过自动化构建、测试和部署流程,提高模型更新速度和质量,降低部署风险,增强团队协作。使用Jenkins和Kubernetes可构建高效CI/CD流水线,自动化模型开发和部署,确保环境一致性并提升整体效率。

热门文章

最新文章