Streamlit部署YOLOv5目标检测

标签: YOLO streamlit yolo | 发表时间:2021-08-27 13:59 | 作者:迷途小书童
出处:https://xugaoxiang.com

环境

  • windows 10 64位
  • anaconda with python 3.8
  • streamlit 0.86.0
  • yolov5 v5.0

streamlit是什么

streamlit是一个开源的 python库,它能够快速的帮助我们创建定制化的 web应用,而且还非常便于和他人分享,特别是在机器学习和数据科学领域。整个过程不需要你了解任何前端的知识,包括 htmlcssjavascript等,对非前端开发人员非常的友好。

streamlit安装

streamlit要求 python版本大于等于3.6,可以直接使用 pip进行安装

  pip install streamlit

安装成功后,使用其内置的 hello app测试,执行命令

  streamlit hello

服务启动后,它会自动帮我们打开页面,地址是 http://localhost:8501

streamlit

可以看到, streamlit默认使用端口8501

除此之外, streamlit官方还提供了一个稍复杂的应用,它结合了 yolov3的目标检测算法,仓库地址: https://github.com/streamlit/demo-self-driving,感兴趣的可以去研究研究,代码简短,但功能完整

streamlit

那么,针对我们自己的写的源码文件,该怎么运行呢?其实也非常简单,比如源码文件是 app.py,那么可以执行

  streamlit run app.py

这里再说2个常用的命令

  • streamlit docs 查看文档
  • streamlit cache clear 清缓存

streamlit常用组件

按钮

  import streamlit as st

button = st.button('按钮')

streamlit button

文本输入框

  import streamlit as st

st.text_input('请输入最喜欢的编程语言', key="name")

streamlit text_input

文本显示

  import streamlit as st

st.write('Hello streamlit.')

streamlit write

streamlit完美支持 markdown语法,可以直接使用 write方法,来看示例

  import streamlit as st

st.write("""
    # 一级标题
    ## 二级标题
    ### 三级标题

    **强调**

    >这是引用

    . python    
    . java    
    . c/c++    
    . rust    
""")

streamlit write markdown

除了 write方法, streamlit还提供了 text方法,同样可以显示文本信息

  import streamlit as st

st.text('Hello streamlit.')

标题

  import streamlit as st

st.title('title')

streamlit title

除了 titlestreamlit还提供了 headersubheader

  import streamlit as st

st.header('header')
st.subheader('subheader')

streamlit header

滑动条

  import streamlit as st

number = st.slider('Pick a number', 0, 100)

streamlit slider

选择框

  import streamlit as st

flag = st.checkbox('Yes')

streamlit checkbox

单选按钮

  import streamlit as st

languages = ['python', 'c', 'rust', 'c++']

st.radio('Pick a language', languages)

streamlit radio

下拉选择框

  import streamlit as st

st.selectbox('用过哪几种编程语言?', ('python', 'c', 'java', 'rust'))

streamlit selectbox

日期选择器

  import streamlit as st

date = st.date_input('Pick a date')

streamlit date_input

颜色选择器

  import streamlit as st

color = st.color_picker('Pick a color')

streamlit color_picker

文件选择器

  import streamlit as st

file = st.file_uploader('Pick a file')

streamlit file_uploader

streamlit的其它功能

显示json

  import streamlit as st

st.json({
    "code": 0,
    "data": {
        "sex": "female",
        "age": 18,
        "score": 100
    }
})

streamlit json

显示代码

  from numpy.core.arrayprint import _leading_trailing
import streamlit as st

code = """
    def func():
        print('Hello streamlit.')
"""
st.code(code, language='python')

streamlit code

显示pandas中的dataframe

  from numpy.core.arrayprint import _leading_trailing
import streamlit as st
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(50, 5), columns=(
    'col %d' % i for i in range(5)))
st.dataframe(df)

streamlit pandas dataframe

最后一句中的 st.dataframe(df)可以用 st.write(df)来代替,效果一样

显示表格

  import streamlit as st
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(50, 5), columns=(
    'col %d' % i for i in range(5)))
st.table(df)

streamlit table

与上边的 dataframe不同的是,表格会将所有数据都显示出来,而没有了滚动条

指标性数据显示

这里还需要安装另一个库 streamlit-metrics,执行安装命令 pip install streamlit-metrics即可

  import streamlit as st
from streamlit_metrics import metric_row

st.write("一周数据统计")
metric_row(
    {
        "关注人数": 100,
        "点赞人数": 200,
        "在看人数": 300,
        "分享人数": 400
    }
)

streamlit metric

streamlit的会话状态和回调

会话状态session state

在浏览器中打开新的页面,就创建了一个会话( session)。会话状态是页面 rerun(并非类似 F5的页面刷新)时数据交互的一种方式。

看个计数的示例

  import streamlit as st

st.title('Hello streamlit.')
counter = 0

increment = st.button('Increment')
if increment:
    counter += 1

st.write('Count= ', counter)

streamlit session state

可以看到只有第一次点击按钮时, Count增加了1,后面的点击, counter都不会改变,这显然跟我们的预期是不一样的。

我们修改下上面的代码

  from typing import Counter
import streamlit as st

st.title('Hello streamlit.')
if 'counter' not in st.session_state:
    st.session_state.counter = 0

increment = st.button('Increment')
if increment:
    st.session_state.counter += 1

st.write('Count= ', st.session_state.counter)

streamlit session state

这样功能就正常了,每点击一次按钮, Count就加1

回调callbacks

回调( callbacks)是一个 python函数,它在输入组件更改时被调用,比如按钮被点击、滑动条被拉拽等。

针对上边的示例,使用 callbacks修改一下

  from typing import Counter
import streamlit as st

# callbacks
def increment_counter():
    st.session_state.counter += 1

st.title('Callbacks')
if 'counter' not in st.session_state:
    st.session_state.counter = 0

st.button('Increment', on_click=increment_counter)
st.write('Count= ', st.session_state.counter)

代码执行的效果是一样的。这是无需传参的示例,如果需要数据交互,可以使用 argskwargs,看下面的示例

  import streamlit as st

st.title('Callbacks with args')
if 'counter' not in st.session_state:
    st.session_state.counter = 0

increment_value = st.number_input('Enter a value', value=0, step=1)

def increment_counter(increment_value):
    st.session_state.counter += increment_value

increment = st.button('Increment', on_click=increment_counter,
                      args=(increment_value, ))

st.write('Count = ', st.session_state.counter)

streamlit callbacks args

下面看看 kwargs的用法,它接收的是命名参数

  import streamlit as st

st.title('Callbacks with kwargs')
if 'counter' not in st.session_state:
    st.session_state.counter = 0

def increment_counter(increment_value=0):
    st.session_state.counter += increment_value

def decrement_counter(decrement_value=0):
    st.session_state.counter -= decrement_value

st.button('Increment', on_click=increment_counter,
          kwargs=dict(increment_value=5))

st.button('Decrement', on_click=decrement_counter,
          kwargs=dict(decrement_value=1))

st.write('Count = ', st.session_state.counter)

callbacks kwargs

点击 Increment按钮, Count就加5,点击 Decrement按钮, Count就减1

会话状态的注意事项

关于会话状态,有两点需要注意,分别是

  • 只要页面打开并连接到 streamlit服务器,会话状态就会一直存在。一旦关闭选项卡,会话状态中存储的所有内容都会丢失

  • 会话状态不会持久化。如果 streamlit服务器崩溃,那么存储在会话状态中的所有内容都会被删除

streamlit部署

streamlit最重要的一个优势就是分享了

进入站点 https://streamlit.io/sharing ,请求邀请

streamlit share

填写基本信息后,就是等待回复了

streamlit share

streamlit处理的很快,我是第二天就收到了确认的邮件

stremlit share email

电子邮件中,详细给出了部署的步骤,基本上照着操作就可以了

  1. 将工程保存到 github中,默认是 main分支,工程下需要有 requirements.txt文件

  2. 访问 https://share.streamlit.io/, 使用 github的账号登录

  3. 创建应用

streamlit share

  1. 填写项目信息,分支和入口文件不要填错

streamlit share

  1. 开始部署,后台就开始安装各种依赖

streamlit share

  1. 项目运行

streamlit share

我这里报了个错

  Traceback (most recent call last):

  File "/home/appuser/venv/lib/python3.7/site-packages/streamlit/script_runner.py", line 350, in _run_script

    exec(code, module.__dict__)

  File "/app/   yolov5-streamlit/main.py", line 5, in <module>

    from detect import detect

  File "/app/   yolov5-streamlit/detect.py", line 5, in <module>

    import cv2

  File "/home/appuser/venv/lib/python3.7/site-packages/cv2/__init__.py", line 5, in <module>

    from .cv2 import *

ImportError: libGL.so.1: cannot open shared object file: No such file or directory

这里需要将 requirements.txt文件中的 opencv-python更改为 opencv-python-headless

点击右上方的 rerun后,重新安装依赖,就可以运行成功了

streamlit share

最后,来测试下功能是否正常。选择一张本地图片上传,然后点击检测

streamlit share

没有问题,那至此,整个 App的部署就完成了,可以分享给你的朋友们了

streamlit share

streamlit share

如果想线上体验下,可以访问

https://share.streamlit.io/xugaoxiang/yolov5-streamlit/main/main.py

源码下载

github地址: https://github.com/xugaoxiang/yolov5-streamlit

入口文件是 main.py,里面跟 streamlit相关的界面代码,其实非常少,这样看, streamlit真的是非常适合不懂前端的朋友。 yolov5的代码部分,基本上把原始的项目拷贝过来,只修改了2个地方

  1. detect.py中的detect方法,增加了一个参数 opt
  2. 修改视频检测后存储的格式,由原来的 mp4v改成了 avc1。原因是 streamlit中的 video适合播放 h264编码的 mp4,详细的操作可以参考 https://xugaoxiang.com/2021/08/20/opencv-h264-videowrite/

参考资料

相关 [streamlit yolov5 目标] 推荐:

Streamlit部署YOLOv5目标检测

- - YOLO – 迷途小书童的Note
windows 10 64位. streamlit是一个开源的 python库,它能够快速的帮助我们创建定制化的 web应用,而且还非常便于和他人分享,特别是在机器学习和数据科学领域. 整个过程不需要你了解任何前端的知识,包括 html、 css、 javascript等,对非前端开发人员非常的友好.

使用opencv的dnn模块来进行yolov5的目标检测

- - YOLO – 迷途小书童的Note
yolov5 的 C++ 部署方案中,. opencv 应该是最能被想到的一种,从 3.3 版本后, opencv 就加入了. dnn 这个模块,有了这个模块,很多的机器学习项目就可以通过它来实现部署了,下面我们就来看看具体的实现步骤. 由于 opencv 无法直接读取. yolov5 中的 pt 模型文件,因此,需要将原来的 pt 文件转换成 opencv 能直接读取的 onnx 模型文件.

YOLODet检测效果图-- 包含YOLOv5、YOLOv4、PP-YOLO、YOLOv3等YOLO系列目标检测算法PyTorch版本实现

- - 开源软件 - ITeye博客
YOLODet-PyTorch是端到端基于pytorch框架复现yolo最新算法的目标检测开发套件,旨在帮助开发者更快更好地完成检测模型的训练、精度速度优化到部署全流程. YOLODet-PyTorch以模块化的设计实现了多种主流YOLO目标检测算法,并且提供了丰富的数据增强、网络组件、损失函数等模块.

YOLOv5发布v6.0版本

- - YOLO – 迷途小书童的Note
就在昨天(2021年10月13日),. yolov5 发布了 V6.0 版本,这个新版本在 V5.0 的基础上集成了很多的新特性,而且在网络结构上也做了微调,引入了全新的更小( Nano )的模型 P5( YOLOv5n) 和 P6( YOLOv5n6). yolov5s 模型的深度( depth ),宽度( width ) 则是从0.5降到了0.25,经过这个操作后,总参数减少了 75%,从 7.5M 缩小到了 1.9M,这样的话,就非常适合于移动端或者是 CPU 的环境.

YOLOv5 的 Android 部署,基于 tflite

- - YOLO – 迷途小书童的Note
前文 借助NCNN,在Android上运行YOLOv5目标检测 和 在Android上进行yolov5目标检测,使用torchscript方式,我们分别使用了 ncnn 和 torchscript 这2种方式将 YOLOv5 部署到了. 本篇我们将使用另一种方式 tflite 来进行部署,所以,喜欢哪个就用哪个吧.

下一个目标:广播

- yimin - It Talks-魏武挥的blog
从报纸杂志到书籍电视,传统媒体在全方位地受到数字媒体的冲击,数字革命的颠覆性正在横扫一切传统媒体的角落,现在看来,最后一个堡垒:广播业,也将迎来有力挑战. 美国著名传媒杂志《Media Life》在去年年底展望2011年全美传媒行业的时候,还很乐观地估计,广播行业将从09年的14%衰退中迎来复苏. 在当时,潘朵拉(Pandora.com)这类“网络电台”已经兴起,但该杂志依然满不在乎地说:“尽管Pandora互联网广播服务和其它网站可以依据个人喜好定制个性化网络电台服务,但那仍然属于小众市场.

我的愿望与目标

- bill boy - 嘉佑中文博客
中午,大学校友通过微信语音留言给我,说他要回家结婚了,7月5日走,要请我吃饭. 他们在台州本地的团购网站上预订了晚餐,我跟他们刚刚从九峰山下的某酒店吃完回来. 他们打算 10月2日 结婚,再三嘱咐我一定要过去参加他们的婚礼. 我肯定届时会去郑州,但是这很可能是最后一次在台州见他们. 又一个朋友,而且是很要好的朋友,就要走了,有点失落因为在台州又少了一个依靠,同时也让我多了一个离开黄岩的借口.

有目标?请闭嘴

- - Starming星光社最新更新
当你给了自己一个全新的目标,你会不会想要跟身边(亲密)的人分享它呢. 通常来讲,很多人都会说出来,在这种行为背后,有些是出于“期望获得来自他人的有效监督”的目的,而有些则纯粹是觉得“没什么好隐瞒的,不妨说出来”. 但如果效率天阶告诉你:当有一天你的目标宣告失败(或迟迟不能达成),其根本原因却仅仅是因为你“告诉别人了”,你会不会觉得难以置信呢.

谈技术团队目标

- - Tim[后端技术]
技术主管新年想得最多的一件事必定是如何比上一年做得更好. 宏大的目标设定每个团队都会做,谈几个不引人注意的小问题. 见过一些技术团队将计划定义为“按时完成需求”,需求驱动并没有什么不对,但是研发工作仅考虑被动需求的话是很难做好. 之前完成的许多需求有什么共性. 经常出问题/bug/故障的项目/功能/模块是哪些.

目标管理体系:OKR

- - 标点符
OKR体系的全称是Objectives & Key Results,即目标与关键成果. 所谓OKR,O = Objective 可以理解为企业目标,KR =Key Results 可以理解为关键结果. 浓缩在一起就是“为确保达成企业目标的关键结果分解与实施”. OKR是企业进行目标管理的一个简单有效的系统,能够将目标管理自上而下贯穿到基层.