Python教程:40行代码接口(第2部分)

图片



用用户界面演示Python项目从未如此简单。借助Streamlit Framework,您可以仅使用Python代码构建基于浏览器的UI。在本文中,我们将为上一个文章中详细描述的迷宫程序创建一个用户界面



流光



Streamlit是一个Web框架,旨在供数据研究人员使用Python轻松部署模型和可视化。它既快速又简约,又美观又舒适。有用于用户输入的内置小部件,例如图像加载,滑块,文本输入,以及其他熟悉的HTML元素(例如复选框和单选按钮)。每当用户与流应用程序进行交互时,python脚本就会从上到下重新启动,这在考虑应用程序的各种状态时必须考虑到这一点。

您可以使用pip安装Streamlit:



pip install streamlit


并在Python脚本中运行streamlit:



streamlit run app.py


用例



上一篇文章中,我们创建了一个Python程序,该程序将在给定图像文件和开始/结束位置的情况下遍历迷宫。我们希望将此程序变成一个单页Web应用程序,用户可以在其中上载迷宫图像(或使用默认的迷宫图像),调整迷宫的开始和结束位置,并查看他们经过的迷宫。



首先,让我们为图像加载器创建UI,并使用默认图像。我们可以使用st.write()或st.title()之类的函数添加文本输出。我们使用st.file_uploader()函数存储动态加载的文件。最后,st.checkbox()将返回一个布尔值,具体取决于用户是否已选中该框。



import streamlit as st
import cv2
import matplotlib.pyplot as plt
import numpy as np
import maze

st.title('Maze Solver')
uploaded_file = st.file_uploader("Choose an image", ["jpg","jpeg","png"]) #image uploader
st.write('Or')
use_default_image = st.checkbox('Use default maze')


结果:



图片



然后我们可以将我们的默认图像或上传的图像输出为可用的OpenCV图像格式。



if use_default_image:
    opencv_image = cv2.imread('maze5.jpg')

elif uploaded_file is not None:
    file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
    opencv_image = cv2.imdecode(file_bytes, 1)


加载图像后,我们要显示标记有起点和终点的图像。我们将使用滑块允许用户移动这些点。st.sidebar()函数在页面上添加了一个侧边栏,而st.slider()在一定的最大值和最小值范围内接受数字。我们可以根据迷宫图像的大小动态确定滑块的最小值和最大值。



if opencv_image is not None:
    st.subheader('Use the sliders on the left to position the start and end points')
    start_x = st.sidebar.slider("Start X", value= 24 if use_default_image  else 50, min_value=0, max_value=opencv_image.shape[1], key='sx')
    start_y = st.sidebar.slider("Start Y", value= 332 if use_default_image  else 100, min_value=0, max_value=opencv_image.shape[0], key='sy')
    finish_x = st.sidebar.slider("Finish X", value= 309 if use_default_image  else 100, min_value=0, max_value=opencv_image.shape[1], key='fx')
    finish_y = st.sidebar.slider("Finish Y", value= 330 if use_default_image  else 100, min_value=0, max_value=opencv_image.shape[0], key='fy')
    marked_image = opencv_image.copy()
    circle_thickness=(marked_image.shape[0]+marked_image.shape[0])//2//100 #circle thickness based on img size
    cv2.circle(marked_image, (start_x, start_y), circle_thickness, (0,255,0),-1)
    cv2.circle(marked_image, (finish_x, finish_y), circle_thickness, (255,0,0),-1)
    st.image(marked_image, channels="RGB", width=800)


图片



每当用户调整滑块时,图像都会快速重绘,并且点会更改。



在用户定义了开始位置和结束位置之后,我们需要一个按钮来解决迷宫并显示解决方案。仅在其子进程运行时显示st.spinner()元素,并且对st.image()的调用用于显示图像。



if marked_image is not None:
    if st.button('Solve Maze'):
        with st.spinner('Solving your maze'):
            path = maze.find_shortest_path(opencv_image,(start_x, start_y),(finish_x, finish_y))
        pathed_image = opencv_image.copy()
        path_thickness = (pathed_image.shape[0]+pathed_image.shape[0])//200
        maze.drawPath(pathed_image, path, path_thickness)
        st.image(pathed_image, channels="RGB", width=800)


图片



解决方案输出按钮



图片







输出量



在不到40行的代码中,我们为Python成像应用程序创建了一个简单的用户界面。我们不需要编写任何传统的前端代码。除了Streamlit能够消化简单的Python代码之外,每次用户与页面进行交互或脚本更改时,Streamlit都会从上到下智能地重新启动脚本的必要部分。这允许直接的数据流和快速的开发。



您可以在Github上找到完整的代码,并在此处第一部分说明解决迷宫的算法。可在此处找到Streamlit文档,包括重要概念和其他小部件



图片



通过参加SkillFactory的付费在线课程,了解如何从头开始或获得技能和薪资水平提高的详细信息:






阅读更多






All Articles