streamlit + opencv/YOLOv3 快速构建自己的图像目标检测demo网页(七)

2021-12-07 14:42:53 浏览数 (1)

文章目录

  • 1 案例介绍
  • 2 依赖安装
  • 3 页面使用
  • 4 源码细节解析
    • 4.1 直接读入markdown文件
    • 4.2 加载文件与图片
    • 4.3 opencv yolov3 检测函数

系列参考: python︱写markdown一样写网页,代码快速生成web工具:streamlit介绍(一) python︱写markdown一样写网页,代码快速生成web工具:streamlit 重要组件介绍(二) python︱写markdown一样写网页,代码快速生成web工具:streamlit 展示组件(三) python︱写markdown一样写网页,代码快速生成web工具:streamlit lay-out布局(四) python︱写markdown一样写网页,代码快速生成web工具:streamlit 缓存(五) python︱写markdown一样写网页,代码快速生成web工具:streamlit 数据探索案例(六) streamlit opencv/YOLOv3 快速构建自己的图像目标检测demo网页(七)

github代码链接:mattzheng/streamlit_demo

1 案例介绍

本案例脱胎于Udacity自动驾驶汽车图像识别,代码链接:implemented in less than 300 lines of Python

原案例中无法自己上传本地图片进行检测,事先提供好了图片url连接(标记了所有图像Ground Truth的原标签数据集),直接download使用,所以不太满足要求 。

笔者这边对该案例进行了一定的魔改,让其可以支持本地图片的使用。 github代码链接:streamlit_demo/demo2-opencv yolov3 这样才能制作自己的检测器,先贴一下笔者最终微调的结果:

2 依赖安装

使用之前需要加载:

代码语言:javascript复制
pip install --upgrade streamlit opencv-python

或者直接用线上的文件也是可以的:

代码语言:javascript复制
streamlit run https://raw.githubusercontent.com/streamlit/demo-self-driving/master/streamlit_app.py

3 页面使用

使用步骤:

  • 第一步:选择本地的一张图片(png/jpg)…
  • 第二步:调整目标检测参数
  • 第三步:点击检测的按钮

其中,切换页面模式,继承了源码的三种:目标检测 显示介绍 展示原始code

4 源码细节解析

辅助的函数介绍:

函数一:下载yolov3 模型文件

代码语言:javascript复制
# This file downloader demonstrates Streamlit animation.
def download_file(file_path):

函数二:目标检测画图函数

代码语言:javascript复制
       # Draws an image with boxes overlayed to indicate the presence of cars, pedestrians etc.
def draw_image_with_boxes(image, boxes, header, description):

函数三:目标检测函数

代码语言:javascript复制
# Run the YOLO model to detect objects.
def yolo_v3(image, confidence_threshold, overlap_threshold):
    # Load the network. Because this is cached it will only happen once.

函数四:图像加载函数

代码语言:javascript复制
@st.cache(show_spinner=False)
def load_local_image(uploaded_file):
    bytes_data = uploaded_file.getvalue()  
    image = np.array(Image.open(BytesIO(bytes_data)))
    return image

4.1 直接读入markdown文件

之前st.markdown可以直接写,但是如果很长的markdown比较麻烦,于是乎,最好可以先保存一个instructions_yolov3.md文件,然后读入。 这里采用最常规的f.read()读入方式,可以快速读入。

代码语言:javascript复制
@st.cache(show_spinner=False)
def read_markdown(path):
    with open(path, "r",encoding = 'utf-8') as f:  # 打开文件
        data = f.read()  # 读取文件
    return data

readme_text = st.markdown(read_markdown("instructions_yolov3.md"))

4.2 加载文件与图片

这里笔者被坑了蛮久。之前有python︱写markdown一样写网页,代码快速生成web工具:streamlit 重要组件介绍(二)案例是:

代码语言:javascript复制
# 单文件载入
uploaded_file = st.file_uploader("Choose a file... csv")
if uploaded_file is not None:
     # To read file as bytes:
     bytes_data = uploaded_file.read()
     st.write(bytes_data)

     # To convert to a string based IO:
     stringio = StringIO(uploaded_file.decode("utf-8"))
     st.write(stringio)

     # To read file as string:
     string_data = stringio.read()
     st.write(string_data)

     # Can be used wherever a "file-like" object is accepted:
     st.write(uploaded_file)
     dataframe = pd.read_csv(uploaded_file)
     st.write(dataframe)

后面不太了解uploaded_file读入的是什么,尝试发现,st.file_uploader读入的是文件的bytes,就跟f.read()效用一样,如果是图片的话,就需要额外将bytes -> array 经过load_local_image之后,image就变成了array,而且是RGB的方式。

代码语言:javascript复制
@st.cache(show_spinner=False)
def load_local_image(uploaded_file):
    bytes_data = uploaded_file.getvalue()  
    image = np.array(Image.open(BytesIO(bytes_data)))
    return image

uploaded_file = st.sidebar.file_uploader(" ")
image = load_local_image(uploaded_file)

4.3 opencv yolov3 检测函数

代码语言:javascript复制
yolo_boxes = yolo_v3(image, confidence_threshold, overlap_threshold)

这里输入的image的RGB数组,以及两个阈值overlap_thresholdconfidence_threshold 输出的是坐标的boxes dataframe格式:

代码语言:javascript复制
    boxes = pd.DataFrame({"xmin": xmin, "ymin": ymin, "xmax": xmax, "ymax": ymax, "labels": labels})
    return boxes[["xmin", "ymin", "xmax", "ymax", "labels"]]

这里是源码,所以不做过多的解释。

0 人点赞