Gradio入门详细教程

常用的两款AI可视化交互应用比较:

  • Gradio
    Gradio的优势在于易用性,代码结构相比Streamlit简单,只需简单定义输入和输出接口即可快速构建简单的交互页面,更轻松部署模型。适合场景相对简单,想要快速部署应用的开发者。便于分享:gradio可以在启动应用时设置share=True参数创建外部分享链接,可以直接在微信中分享给用户使用。

  • Streamlit
    Streamlit的优势在于可扩展性,相比Gradio复杂,完全熟练使用需要一定时间。可以使用Python编写完整的包含前后端的交互式应用。适合场景相对复杂,想要构建丰富多样交互页面的开发者。

Gradio官网链接:https://gradio.app/
Streamlit官网链接:https://streamlit.io/

1. 安装&基本用法

Python第三方库Gradio快速上手,当前版本V3.27.0

  • python版本要求3.7及以上
pip install gradio

#为了更快安装,可以使用清华镜像源
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple gradio

安装完直接在IDE上启动快速,

1.1 快速入门

import gradio as gr
#输入文本处理程序
def greet(name):
    return "Hello " + name + "!"
#接口创建函数
#fn设置处理函数,inputs设置输入接口组件,outputs设置输出接口组件
#fn,inputs,outputs都是必填函数
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
demo.launch()

运行程序后,打开 http://localhost:7860 即可看到网页效果。左边是文本输入框,右边是结果展示框。Clear按钮用于重置网页状态,Submit按钮用于执行处理程序,Flag按钮用于保存结果到本地。

#执行结果
Running on local URL:  http://127.0.0.1:7860

To create a public link, set `share=True` in `launch()`.

打开浏览器使用即可:

在这里插入图片描述

在本地开发时,如果你想将代码作为Python脚本运行,你可以使用Gradio CLI在重载模式下启动应用程序,这将提供无缝和快速的开发。

gradio app.py

Note:你也可以做python app.py,但它不会提供自动重新加载机制。

2.基本参数|支持的接口

2.1 Interface类以及基础模块

Gradio 可以包装几乎任何 Python 函数为易于使用的用户界面。从上面例子我们看到,简单的基于文本的函数。但这个函数还可以处理很多类型。

Interface类通过以下三个参数进行初始化:

  • fn:包装的函数
  • inputs:输入组件类型,(例如:“text”、"image)
  • ouputs:输出组件类型,(例如:“text”、"image)

通过这三个参数,我们可以快速创建一个接口并发布他们。

最常用的基础模块构成。

  • 应用界面:gr.Interface(简易场景), gr.Blocks(定制化场景)

  • 输入输出:gr.Image(图像), gr.Textbox(文本框), gr.DataFrame(数据框), gr.Dropdown(下拉选项), gr.Number(数字), gr.Markdown, gr.Files

  • 控制组件:gr.Button(按钮)

  • 布局组件:gr.Tab(标签页), gr.Row(行布局), gr.Column(列布局)

1.2.1 自定义输入组件

import gradio as gr
def greet(name):
    return "Hello " + name + "!"
demo = gr.Interface(
    fn=greet,
    # 自定义输入框
    # 具体设置方法查看官方文档
    inputs=gr.Textbox(lines=3, placeholder="Name Here...",label="my input"),
    outputs="text",
)
demo.launch()

在这里插入图片描述

Interface.launch()方法返回三个值

  • app,为 Gradio 演示提供支持的 FastAPI 应用程序
    l- ocal_url,本地地址
  • share_url,公共地址,当share=True时生成
import gradio as gr

def greet(name):
    return "Hello " + name + "!"

iface = gr.Interface(
    fn=greet,
    inputs=gr.inputs.Textbox(lines=2, placeholder="Name Here..."),
    outputs="text",
)
if __name__ == "__main__":
    app, local_url, share_url = iface.launch()

1.2.2 多个输入和输出

对于复杂程序,输入列表中的每个组件按顺序对应于函数的一个参数。输出列表中的每个组件按顺序排列对应于函数返回的一个值。

import gradio as gr
#该函数有3个输入参数和2个输出参数
def greet(name, is_morning, temperature):
    salutation = "Good morning" if is_morning else "Good evening"
    greeting = f"{salutation} {name}. It is {temperature} degrees today"
    celsius = (temperature - 32) * 5 / 9
    return greeting, round(celsius, 2)
demo = gr.Interface(
    fn=greet,
    #按照处理程序设置输入组件
    inputs=["text", "checkbox", gr.Slider(0, 100)],
    #按照处理程序设置输出组件
    outputs=["text", "number"],
)
demo.launch()

在这里插入图片描述

inputs列表里的每个字段按顺序对应函数的每个参数,outputs同理。

1.2.3 图像组件

Gradio支持许多类型的组件,如image、dataframe、video。使用示例如下:

import numpy as np
import gradio as gr
def sepia(input_img):
    #处理图像
    sepia_filter = np.array([
        [0.393, 0.769, 0.189],
        [0.349, 0.686, 0.168],
        [0.272, 0.534, 0.131]
    ])
    sepia_img = input_img.dot(sepia_filter.T)
    sepia_img /= sepia_img.max()
    return sepia_img
#shape设置输入图像大小
demo = gr.Interface(sepia, gr.Image(shape=(200, 200)), "image")
demo.launch()

在这里插入图片描述

当使用Image组件作为输入时,函数将收到一个维度为(w,h,3)的numpy数组,按照RGB的通道顺序排列。要注意的是,我们的输入图像组件带有一个编辑按钮,可以对图像进行裁剪和放大。以这种方式处理图像可以帮助揭示机器学习模型中的偏差或隐藏的缺陷。

此外对于输入组件有个shape参数,指的设置输入图像大小。但是处理方式是保持长宽比的情况下,将图像最短边缩放为指定长度,然后按照中心裁剪方式裁剪最长边到指定长度。

当图像不大的情况,一种更好的方式是不设置shape,这样直接传入原图。输入组件Image也可以设置输入类型type,比如type=filepath设置传入处理图像的路径。具体可以查看官方文档,文档写的很清楚。

1.2.4 动态界面接口:简单计算器模板实时变化

在Interface添加live=True参数,只要输入发生变化,结果马上发生改变。

import gradio as gr

def calculator(num1, operation, num2):
    if operation == "add":
        return num1 + num2
    elif operation == "subtract":
        return num1 - num2
    elif operation == "multiply":
        return num1 * num2
    elif operation == "divide":
        return num1 / num2

iface = gr.Interface(
    calculator,
    ["number", gr.inputs.Radio(["add", "subtract", "multiply", "divide"]), "number"],
    "number",
    live=True,
)

iface.launch()

在这里插入图片描述

import gradio as gr
#一个简单计算器,含实例说明
def calculator(num1, operation, num2):
    if operation == "add":
        return num1 + num2
    elif operation == "subtract":
        return num1 - num2
    elif operation == "multiply":
        return num1 * num2
    elif operation == "divide":
        if num2 == 0:
            # 设置报错弹窗
            raise gr.Error("Cannot divide by zero!")
        return num1 / num2
demo = gr.Interface(
    calculator,
    # 设置输入
    [
        "number",
        gr.Radio(["add", "subtract", "multiply", "divide"]),
        "number"
    ],
    # 设置输出
    "number",
    # 设置输入参数示例
    examples=[
        [5, "add", 3],
        [4, "divide", 2],
        [-4, "multiply", 2.5],
        [0, "subtract", 1.2],
    ],
    # 设置网页标题
    title="Toy Calculator",
    # 左上角的描述文字
    description="Here's a sample toy calculator. Enjoy!",
    # 左下角的文字
    article = "Check out the examples",
)
demo.launch()

在这里插入图片描述

2.2 interface进阶使用

2.2.1 interface状态

全局变量

全局变量的好处就是在调用函数后仍然能够保存,例如在机器学习中通过全局变量从外部加载一个大型模型,并在函数内部使用它,以便每次函数调用都不需要重新加载模型。下面就展示了全局变量使用的好处。

import gradio as gr
scores = []
def track_score(score):
    scores.append(score)
    #返回分数top3
    top_scores = sorted(scores, reverse=True)[:3]
    return top_scores
demo = gr.Interface(
    track_score,
    gr.Number(label="Score"),
    gr.JSON(label="Top Scores")
)
demo.launch()

在这里插入图片描述

会话状态

Gradio支持的另一种数据持久性是会话状态,数据在一个页面会话中的多次提交中持久存在。然而,数据不会在你模型的不同用户之间共享。会话状态的典型例子就是聊天机器人,你想访问用户之前提交的信息,但你不能将聊天记录存储在一个全局变量中,因为那样的话,聊天记录会在不同的用户之间乱成一团。注意该状态会在每个页面内的提交中持续存在,但如果您在另一个标签页中加载该演示(或刷新页面),该演示将不会共享聊天历史。

要在会话状态下存储数据,你需要做三件事:

  • 在你的函数中传入一个额外的参数,它代表界面的状态。
  • 在函数的最后,将状态的更新值作为一个额外的返回值返回。
  • 在添加输入和输出时添加state组件。
import random
import gradio as gr
def chat(message, history):
    history = history or []
    message = message.lower()
    if message.startswith("how many"):
        response = random.randint(1, 10)
    elif message.startswith("how"):
        response = random.choice(["Great", "Good", "Okay", "Bad"])
    elif message.startswith("where"):
        response = random.choice(["Here", "There", "Somewhere"])
    else:
        response = "I don't know"
    history.append((message, response))
    return history, history
#设置一个对话窗
chatbot = gr.Chatbot().style(color_map=("green", "pink"))
demo = gr.Interface(
    chat,
    # 添加state组件
    ["text", "state"],
    [chatbot, "state"],
    # 设置没有保存数据的按钮
    allow_flagging="never",
)
demo.launch()

在这里插入图片描述

2.2.2 interface交互

实时变化

在Interface中设置live=True,则输出会跟随输入实时变化。这个时候界面不会有submit按钮,因为不需要手动提交输入。

同1.2.4

流模式

在许多情形下,我们的输入是实时视频流或者音频流,那么意味这数据不停地发送到后端,这是可以采用streaming模式处理数据。

import gradio as gr
import numpy as np
def flip(im):
    return np.flipud(im)
demo = gr.Interface(
    flip,
    gr.Image(source="webcam", streaming=True),
    "image",
    live=True
)
demo.launch()

2.3自定制组件:Blocks构建应用

相比Interface,Blocks提供了一个低级别的API,用于设计具有更灵活布局和数据流的网络应用。Blocks允许控制组件在页面上出现的位置,处理复杂的数据流(例如,输出可以作为其他函数的输入),并根据用户交互更新组件的属性可见性。可以定制更多组件,更多详细定制可查看文档

2.3.1 简单演示

import gradio as gr
def greet(name):
    return "Hello " + name + "!"
with gr.Blocks() as demo:
    #设置输入组件
    name = gr.Textbox(label="Name")
    # 设置输出组件
    output = gr.Textbox(label="Output Box")
    #设置按钮
    greet_btn = gr.Button("Greet")
    #设置按钮点击事件
    greet_btn.click(fn=greet, inputs=name, outputs=output)
demo.launch()

在这里插入图片描述

Blocks方式需要with语句添加组件,如果不设置布局方式,那么组件将按照创建的顺序垂直出现在应用程序中,运行界面

2.3.2 多模块应用☆

import numpy as np
import gradio as gr
def flip_text(x):
    return x[::-1]
def flip_image(x):
    return np.fliplr(x)
with gr.Blocks() as demo:
    #用markdown语法编辑输出一段话
    gr.Markdown("Flip text or image files using this demo.")
    # 设置tab选项卡
    with gr.Tab("Flip Text"):
        #Blocks特有组件,设置所有子组件按垂直排列
        #垂直排列是默认情况,不加也没关系
        with gr.Column():
            text_input = gr.Textbox()
            text_output = gr.Textbox()
            text_button = gr.Button("Flip")
    with gr.Tab("Flip Image"):
        #Blocks特有组件,设置所有子组件按水平排列
        with gr.Row():
            image_input = gr.Image()
            image_output = gr.Image()
        image_button = gr.Button("Flip")
    #设置折叠内容
    with gr.Accordion("Open for More!"):
        gr.Markdown("Look at me...")
    text_button.click(flip_text, inputs=text_input, outputs=text_output)
    image_button.click(flip_image, inputs=image_input, outputs=image_output)
demo.launch()

在这里插入图片描述

在这里插入图片描述

2.3.3 Flagging标记

相信有小伙伴已经注意到,输出框下有个Flag按钮。当测试您的模型的用户看到某个输入导致输出错误或意外的模型行为,他们可以标记这个输入让开发者知道。

这个文件夹由Interfaceflagging_dir参数指定,默认为’flagged’。将这些会导致错误的输入保存到一个csv文件。如果Interface包含文件数据,文件夹也会创建来保存这些标记数据。

打开log.csv展示如下:

在这里插入图片描述

2.3.4 样式、队列、生成器

样式

Gradio官方文档,搜索不同的组件加.style(如image.style),可以获取该组件的样式参数设置样例。例如image组件的设置如下:

img = gr.Image("lion.jpg").style(height='24', rounded=False)
队列

如果函数推理时间较长,比如目标检测;或者应用程序处理流量过大,则需要使用queue方法进行排队。queue方法使用websockets,可以防止网络超时。使用方式如下:

demo = gr.Interface(...).queue()
demo.launch()
#或
with gr.Blocks() as demo:
    #...
demo.queue()
demo.launch()
生成器

在某些情况下,你可能想显示一连串的输出,而不是单一的输出。例如,你可能有一个图像生成模型,如果你想显示在每个步骤中生成的图像,从而得到最终的图像。在这种情况下,你可以向Gradio提供一个生成器函数,而不是一个常规函数。下面是一个生成器的例子,每隔1秒返回1张图片。

import gradio as gr
import numpy as np
import time
#生成steps张图片,每隔1秒钟返回
def fake_diffusion(steps):
    for _ in range(steps):
        time.sleep(1)
        image = np.random.randint(255, size=(300, 600, 3))
        yield image
demo = gr.Interface(fake_diffusion,
                    #设置滑窗,最小值为1,最大值为10,初始值为3,每次改动增减1位
                    inputs=gr.Slider(1, 10, value=3, step=1),
                    outputs="image")
#生成器必须要queue函数
demo.queue()
demo.launch()

2.4 Blocks进阶使用

2.4.1 Blocks事件

可交互设置

任何输入的组件内容都是可编辑的,而输出组件默认是不能编辑的。如果想要使得输出组件内容可编辑,设置interactive=True即可。

import gradio as gr
def greet(name):
    return "Hello " + name + "!"
with gr.Blocks() as demo:
    name = gr.Textbox(label="Name")
    # 不可交互
    # output = gr.Textbox(label="Output Box")
    # 可交互
    output = gr.Textbox(label="Output", interactive=True)
    greet_btn = gr.Button("Greet")
    greet_btn.click(fn=greet, inputs=name, outputs=output)
demo.launch()
事件设置

我们可以为不同的组件设置不同事件,如为输入组件添加change事件。可以进一步查看官方文档,看看组件还有哪些事件。

import gradio as gr
def welcome(name):
    return f"Welcome to Gradio, {name}!"
with gr.Blocks() as demo:
    gr.Markdown(
    """
    # Hello World!
    Start typing below to see the output.
    """)
    inp = gr.Textbox(placeholder="What is your name?")
    out = gr.Textbox()
    #设置change事件
    inp.change(fn = welcome, inputs = inp, outputs = out)
demo.launch()
多个数据流

如果想处理多个数据流,只要设置相应的输入输出组件即可。

import gradio as gr
def increase(num):
    return num + 1
with gr.Blocks() as demo:
    a = gr.Number(label="a")
    b = gr.Number(label="b")
    # 要想b>a,则使得b = a+1
    atob = gr.Button("b > a")
    atob.click(increase, a, b)
    # 要想a>b,则使得a = b+1
    btoa = gr.Button("a > b")
    btoa.click(increase, b, a)
demo.launch()

在这里插入图片描述

多输出值处理

下面的例子展示了输出多个值时,以列表形式表现的处理方式。

import gradio as gr
with gr.Blocks() as demo:
    food_box = gr.Number(value=10, label="Food Count")
    status_box = gr.Textbox()
    def eat(food):
        if food > 0:
            return food - 1, "full"
        else:
            return 0, "hungry"
    gr.Button("EAT").click(
        fn=eat,
        inputs=food_box,
        #根据返回值改变输入组件和输出组件
        outputs=[food_box, status_box]
    )
demo.launch()

下面的例子展示了输出多个值时,以字典形式表现的处理方式。

组件配置修改

事件监听器函数的返回值通常是相应的输出组件的更新值。有时我们也想更新组件的配置,比如说可见性。在这种情况下,我们可以通过返回update函数更新组件的配置。

import gradio as gr
def change_textbox(choice):
    #根据不同输入对输出控件进行更新
    if choice == "short":
        return gr.update(lines=2, visible=True, value="Short story: ")
    elif choice == "long":
        return gr.update(lines=8, visible=True, value="Long story...")
    else:
        return gr.update(visible=False)
with gr.Blocks() as demo:
    radio = gr.Radio(
        ["short", "long", "none"], label="Essay Length to Write?"
    )
    text = gr.Textbox(lines=2, interactive=True)
    radio.change(fn=change_textbox, inputs=radio, outputs=text)
demo.launch()

在这里插入图片描述

2.4.2 Blocks布局

Blocks应用的是html中的flexbox模型布局,默认情况下组件垂直排列。

组件水平排列

使用Row函数会将组件按照水平排列,但是在Row函数块里面的组件都会保持同等高度。

import gradio as gr
with gr.Blocks() as demo:
    with gr.Row():
        img1 = gr.Image()
        text1 = gr.Text()
    btn1 = gr.Button("button")
demo.launch()
组件垂直排列与嵌套

组件通常是垂直排列,我们可以通过Row函数Column函数生成不同复杂的布局。

import gradio as gr
with gr.Blocks() as demo:
    with gr.Row():
        text1 = gr.Textbox(label="t1")
        slider2 = gr.Textbox(label="s2")
        drop3 = gr.Dropdown(["a", "b", "c"], label="d3")
    with gr.Row():
        # scale与相邻列相比的相对宽度。例如,如果列A的比例为2,列B的比例为1,则A的宽度将是B的两倍。
        # min_width设置最小宽度,防止列太窄
        with gr.Column(scale=2, min_width=600):
            text1 = gr.Textbox(label="prompt 1")
            text2 = gr.Textbox(label="prompt 2")
            inbtw = gr.Button("Between")
            text4 = gr.Textbox(label="prompt 1")
            text5 = gr.Textbox(label="prompt 2")
        with gr.Column(scale=1, min_width=600):
            img1 = gr.Image("test.jpg")
            btn = gr.Button("Go")
demo.launch()
组件可视化:输出可视化从无到有

如下所示,我们可以通过visibleupdate函数构建更为复杂的应用。

import gradio as gr
with gr.Blocks() as demo:
    # 出错提示框
    error_box = gr.Textbox(label="Error", visible=False)
    # 输入框
    name_box = gr.Textbox(label="Name")
    age_box = gr.Number(label="Age")
    symptoms_box = gr.CheckboxGroup(["Cough", "Fever", "Runny Nose"])
    submit_btn = gr.Button("Submit")
    # 输出不可见
    with gr.Column(visible=False) as output_col:
        diagnosis_box = gr.Textbox(label="Diagnosis")
        patient_summary_box = gr.Textbox(label="Patient Summary")
    def submit(name, age, symptoms):
        if len(name) == 0:
            return {error_box: gr.update(value="Enter name", visible=True)}
        if age < 0 or age > 200:
            return {error_box: gr.update(value="Enter valid age", visible=True)}
        return {
            output_col: gr.update(visible=True),
            diagnosis_box: "covid" if "Cough" in symptoms else "flu",
            patient_summary_box: f"{name}, {age} y/o"
        }
    submit_btn.click(
        submit,
        [name_box, age_box, symptoms_box],
        [error_box, diagnosis_box, patient_summary_box, output_col],
    )
demo.launch()

在这里插入图片描述

组件渲染:点击作为输入

在某些情况下,您可能希望在实际在UI中呈现组件之前定义组件。

例如,您可能希望在相应的gr.Textbox输入上方显示使用gr.examples的示例部分。由于gr.Examples需要输入组件对象作为参数,因此您需要先定义输入组件,然后在定义gr.Exmples对象后再进行渲染。解决方法是在gr.Blocks()范围外定义gr.Textbox,并在UI中希望放置的任何位置使用组件的.render()方法

import gradio as gr
input_textbox = gr.Textbox()
with gr.Blocks() as demo:
    #提供示例输入给input_textbox,示例输入以嵌套列表形式设置
    gr.Examples(["hello", "bonjour", "merhaba"], input_textbox)
    # render函数渲染input_textbox
    input_textbox.render()
demo.launch()

在这里插入图片描述

2.4.3 样式修改

自定义css

要获得额外的样式功能,您可以设置行内css属性将任何样式给应用程序。如下所示。

import gradio as gr
#修改blocks的背景颜色
with gr.Blocks(css=".gradio-container {background-color: red}") as demo:
    box1 = gr.Textbox(value="Good Job")
    box2 = gr.Textbox(value="Failure")
demo.launch()

在这里插入图片描述

元素选择

您可以向任何组件添加HTML元素。通过elem_id选择对应的css元素

import gradio as gr
# 这里用的是id属性设置
with gr.Blocks(css="#warning {background-color: red}") as demo:
    box1 = gr.Textbox(value="Good Job", elem_id="warning")
    box2 = gr.Textbox(value="Failure")
    box3 = gr.Textbox(value="None", elem_id="warning")
demo.launch()

在这里插入图片描述

3. 应用分享

3.1 互联网分享

如果运行环境能够连接互联网,在launch函数中设置share参数为True,那么运行程序后。Gradio的服务器会提供XXXXX.gradio.app地址。通过其他设备,比如手机或者笔记本电脑,都可以访问该应用。这种方式下该链接只是本地服务器的代理,不会存储通过本地应用程序发送的任何数据。这个链接在有效期内是免费的,好处就是不需要自己搭建服务器,坏处就是太慢了,毕竟数据经过别人的服务器。

demo.launch(share=True)

3.2 huggingface托管

为了便于向合作伙伴永久展示我们的模型App,可以将gradio的模型部署到 HuggingFace的 Space托管空间中,完全免费的哦。

方法如下:

  1. 注册huggingface账号:https://huggingface.co/join

  2. space空间中创建项目:https://huggingface.co/spaces

  3. 创建好的项目有一个Readme文档,可以根据说明操作,也可以手工编辑app.py和requirements.txt文件。

3.3 局域网分享

通过设置server_name=‘0.0.0.0’(表示使用本机ip),server_port(可不改,默认值是7860)。那么可以通过本机ip:端口号在局域网内分享应用。

#show_error为True表示在控制台显示错误信息。
demo.launch(server_name='0.0.0.0', server_port=8080, show_error=True)

这里host地址可以自行在电脑查询,C:\Windows\System32\drivers\etc\hosts 修改一下即可 127.0.0.1再制定端口号

3.4 密码验证

在首次打开网页前,可以设置账户密码。比如auth参数为(账户,密码)的元组数据。这种模式下不能够使用queue函数。

demo.launch(auth=("admin", "pass1234"))

如果想设置更为复杂的账户密码和密码提示,可以通过函数设置校验规则。

#账户和密码相同就可以通过
def same_auth(username, password):
    return username == password
demo.launch(auth=same_auth,auth_message="username and password must be the same")

4.案例升级展示

4.1 文本分类

#!pip install gradio, ultralytics, transformers, torchkeras
import gradio as gr 
from transformers import pipeline
 
pipe = pipeline("text-classification")
 
def clf(text):
    result = pipe(text)
    label = result[0]['label']
    score = result[0]['score']
    res = {label:score,'POSITIVE' if label=='NEGATIVE' else 'NEGATIVE': 1-score}
    return res 
 
demo = gr.Interface(fn=clf, inputs="text", outputs="label")
gr.close_all()
demo.launch(share=True)

4.2 图像分类

import gradio as gr 
import pandas as pd 
from ultralytics import YOLO
from skimage import data
from PIL import Image
 
model = YOLO('yolov8n-cls.pt')
def predict(img):
    result = model.predict(source=img)
    df = pd.Series(result[0].names).to_frame()
    df.columns = ['names']
    df['probs'] = result[0].probs
    df = df.sort_values('probs',ascending=False)
    res = dict(zip(df['names'],df['probs']))
    return res
gr.close_all() 
demo = gr.Interface(fn = predict,inputs = gr.Image(type='pil'), outputs = gr.Label(num_top_classes=5), 
                    examples = ['cat.jpeg','people.jpeg','coffee.jpeg'])
demo.launch()

4.3 目标检测

import gradio as gr 
import pandas as pd 
from skimage import data
from ultralytics.yolo.data import utils 
 
model = YOLO('yolov8n.pt')
 
#load class_names
yaml_path = str(Path(ultralytics.__file__).parent/'datasets/coco128.yaml') 
class_names = utils.yaml_load(yaml_path)['names']

def detect(img):
    if isinstance(img,str):
        img = get_url_img(img) if img.startswith('http') else Image.open(img).convert('RGB')
    result = model.predict(source=img)
    if len(result[0].boxes.boxes)>0:
        vis = plots.plot_detection(img,boxes=result[0].boxes.boxes,
                     class_names=class_names, min_score=0.2)
    else:
        vis = img
    return vis
    
with gr.Blocks() as demo:
    gr.Markdown("# yolov8目标检测演示")
 
    with gr.Tab("捕捉摄像头喔"):
        in_img = gr.Image(source='webcam',type='pil')
        button = gr.Button("执行检测",variant="primary")
 
        gr.Markdown("## 预测输出")
        out_img = gr.Image(type='pil')
 
        button.click(detect,
                     inputs=in_img, 
                     outputs=out_img)
        
    
gr.close_all() 
demo.queue(concurrency_count=5)
demo.launch()

4.4 图片筛选器

尽管gradio的设计初衷是为了快速创建机器学习用户交互页面。但实际上,通过组合gradio的各种组件,用户可以很方便地实现非常实用的各种应用小工具。

例如: 数据分析展示dashboard, 数据标注工具, 制作一个小游戏界面等等。

本范例我们将应用 gradio来构建一个图片筛选器,从百度爬取的一堆猫咪表情包中刷选一些我们喜欢的出来。

#!pip install -U torchkeras
import torchkeras 
from torchkeras.data import download_baidu_pictures 
download_baidu_pictures('猫咪表情包',100)

import gradio as gr
from PIL import Image
import time,os
from pathlib import Path 
base_dir = '猫咪表情包'
selected_dir = 'selected'
files = [str(x) for x in 
         Path(base_dir).rglob('*.jp*g') 
         if 'checkpoint' not in str(x)]
def show_img(path):
    return Image.open(path)
def fn_before(done,todo):
    ...
    return done,todo,path,img
def fn_next(done,todo):
    ...
    return done,todo,path,img
def save_selected(img_path):
    ...
    return msg 
def get_default_msg():
    ...
    return msg
    
    
with gr.Blocks() as demo:
    with gr.Row():
        total = gr.Number(len(files),label='总数量')
        with gr.Row(scale = 1):
            bn_before = gr.Button("上一张")
            bn_next = gr.Button("下一张")
        with gr.Row(scale = 2):
            done = gr.Number(0,label='已完成')
            todo = gr.Number(len(files),label='待完成')
    path = gr.Text(files[0],lines=1, label='当前图片路径')
    feedback_button = gr.Button("选择图片",variant="primary")
    msg = gr.TextArea(value=get_default_msg,lines=3,max_lines = 5)
    img = gr.Image(value = show_img(files[0]),type='pil')
    
    bn_before.click(fn_before,
                 inputs= [done,todo], 
                 outputs=[done,todo,path,img])
    bn_next.click(fn_next,
                 inputs= [done,todo], 
                 outputs=[done,todo,path,img])
    feedback_button.click(save_selected,
                         inputs = path,
                         outputs = msg
                         )

demo.launch()

参考链接:
Gradio官方仓库

基于Gradio可视化部署机器学习应用

gradio官方文档

Gradio让你的机器学习模型性感起来

Gradio搭建演示系统

Gradio上手教程

Gradio:轻松实现AI算法可视化部署

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/247155.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣二叉树--总结篇(2)

前言 总体回顾&#xff1a;11.18-12.14&#xff0c;中间有一个星期左右因为考试没有写题。37道题。 内容 这是第二阶段刷的题 从路径到构造二叉树&#xff0c;合并二叉树&#xff0c;再到二叉搜索树&#xff0c;公共祖先问题 看到二叉树&#xff0c;看到递归 都会想&#…

常见的Linux基本指令

目录 什么是Linux&#xff1f; Xshell如何远程控制云服务器 Xshell远程连接云服务器 Linux基本指令 用户管理指令 pwd指令 touch指令 mkdir指令 ls指令 cd指令 rm指令 man命令 cp指令 mv指令 cat指令 head指令 ​编辑 tail指令 ​编辑echo指令 find命令 gr…

【教程】源代码加密、防泄密软件

​ 什么是代码混淆&#xff1f; 代码混淆 是一种将应用程序二进制文件转换为功能上等价&#xff0c;但人类难于阅读和理解的行为。在编译 Dart 代码时&#xff0c;混淆会隐藏函数和类的名称&#xff0c;并用其他符号替代每个符号&#xff0c;从而使攻击者难以进行逆向工程。 …

认识产品经理以及Axure简单安装与入门

目录 一.认识产品经理 1.1.项目团队 1.2.概述 1.3.认识产品经理 1.4.产品经理工作范围 1.5.产品经理工作流程 1.6.产品经理的职责 1.7.产品经理的分类 1.8.产品经理能力要求 1.9.产品工具 1.10.产品体验报告 二.Axure简介 三.应用场景 四.安装与汉化 4.1.安装 4…

认知觉醒(七)

认知觉醒(七) 第三章 元认知——人类的终极能能力 第一节 元认知&#xff1a;成长慢&#xff0c;是因为你不会“飞” 1946年10月24日&#xff0c;一群科学家为了研究太阳的紫外线&#xff0c;在美国新墨西哥州白沙导弹试验场发射了当时世界上最先进的V2液体火箭&#xff0…

mysql 数据库 关于库的基本操作

库的操作 如果想到 mysql 客户端当中数据 系统当中的命令的话&#xff0c;直接输入的话&#xff0c;会被认为是 mysql 当中的命令。 所以&#xff0c;在mysql 当中执行系统当中的命令的话&#xff0c;要在系统命令之前带上 ststem &#xff0c;表示系统命令&#xff1a; 但是…

代码随想录二刷 | 二叉树 | 110.平衡二叉树

代码随想录二刷 &#xff5c; 二叉树 &#xff5c; 110.平衡二叉树 题目描述解题思路递归迭代 代码实现递归法迭代法 题目描述 110.平衡二叉树 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉…

奥比中光 Femto Bolt相机ROS配置

作者&#xff1a; Herman Ye Auromix 测试环境&#xff1a; Ubuntu20.04/22.04 、ROS1 Noetic/ROS2 Humble、X86 PC/Jetson Orin、Kinect DK/Femto Bolt 更新日期&#xff1a; 2023/12/12 注1&#xff1a; Auromix 是一个机器人爱好者开源组织。 注2&#xff1a; 由于笔者水平有…

FL Studio水果软件最新版本号V21.0.3.3517内置中文补丁,可以切换成中文界面。

FL Studio 21.0.3.3517 Producer Edition 全称Fruity Loops Studio 21 Producer Edition &#xff0c;就是大家熟悉的水果编曲软件&#xff0c;一个全能的音乐制作软件&#xff0c;包括编曲、录音、剪辑和混音等诸多功能&#xff0c;让你的电脑编程一个全能的录音室。FL Studio…

关于响应式布局,你需要了解的知识点

什么是响应式布局&#xff1f; 响应式布局&#xff0c;就是根据不同设备展示不同的布局&#xff0c;以免更方便用户浏览页面。 举个很简单的例子&#xff0c;我们在电脑上浏览网页&#xff0c;屏幕非常大&#xff0c;这时候可能采用的是如下图所示的布局方式。这种布局方式很宽…

C++类和对象(3)

目录 再谈构造函数 构造函数体赋值 初始化列表 【注意】 explicit关键字 Static成员 概念 特性 友元 友元函数 友元类 内部类 概念 特性&#xff1a; 匿名对象 拷贝对象时的一些编译器优化 再谈构造函数 构造函数体赋值 在创建对象时&#xff0c;编译…

后端打印不了trace等级的日志?-SpringBoot日志打印-Slf4j

在调用log变量的方法来输出日志时&#xff0c;有以上5个级别对应的方法&#xff0c;从不太重要&#xff0c;到非常重要 调用不同的方法&#xff0c;就会输出不同级别的日志。 trace&#xff1a;跟踪信息debug&#xff1a;调试信息info&#xff1a;一般信息warn&#xff1a;警告…

炒股怎么做杠杆?安全正规的融资融券了解一下!

加杠杆炒股是指放大投资资金进行股票交易&#xff0c;比如自有资金100万&#xff0c;向证券公司融资100万&#xff0c;那么投资者炒股的本金就有200万。当股市行情好的时候可以放大我们的收益&#xff01; 目前我国股票加杠杆通过融资融券来实现&#xff0c;这个是唯一安全正规…

网络协议 - DNS 相关详解

网络协议 - DNS 相关详解 DNS简介域名层级结构域名服务器 DNS 解析流程为什么DNS通常基于UDP DNS 查询dig 查询host查询nslookup查询whois查询在线工具查询 DNS 调度原理地理位置调度不准确规则变更生效时间不确定高可用 DNS 安全相关什么是DNS劫持什么是DNS污染为什么要DNS流量…

电源适配器老化测试方法分享 电源测试系统助力老化测试

电源适配器老化测试是指对适配器进行高负荷、长时间的运行测试&#xff0c;从而评估电源适配器的性能、稳定性和可靠性。通过老化测试可以检测电源适配器长时间的使用情况&#xff0c;从而指导适配器的设计和研发&#xff0c;提高电源适配器的质量。由于老化测试要求长时间运行…

innovus:ccopt_design流程

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 ccopt完整的流程包括如下几个步骤&#xff1a; spec文件可以只创建一次&#xff0c;无需多次创建。 1&#xff09;clustering阶段 set_ccopt_property balance_mode cluster …

camunda流程引擎——Java集成Camunda(上)(笔记)

目录 一、以一个处理流程开始1.1 后端1.2 前端1.3 执行 二、Camunda的补充2.1 使用方式2.2 可视化平台的Cockpit2.3 流程相关数据2.4 表介绍2.5 前端集成Modeler 三、用Java集成Camunda3.1 集成配置3.2 自动部署3.2.1 修改process.xml位置3.2.2 多进程引擎配置与多租户 3.3 历史…

《Java 核心技术·卷I (第11版)》笔记

文章目录 第1章 Java程序设计概述1.1 Java程序设计平台1.2 Java “白皮书” 的关键术语1.2.1 简单性1.2.2 面向对象1.2.3 分布式1.2.4 健壮性1.2.5 安全性1.2.6 体系结构中立1.2.7 可移植性1.2.8 解释型1.2.9 高性能1.2.10 多线程1.2.11 动态性 1.3 Java applet 与 Internet1.4…

线性回归在数据库中的应用

简介 今天看到微信群有人问&#xff0c;如何知道数据库一年的磁盘增量&#xff1f;如果没有研究过统计学&#xff0c;IT人员对于这个问题就只能靠经验了去断定了。没经验的往往都是回复扩容越大越好。当然未来的事情我们是无法预料的。本博主就通过简单的线性回归做一个计算&am…

XS9922B-国产cvi协议,满足国内车载视频传输领域国产化降本需求

XS9922B 是一款 4 通道模拟复合视频解码芯片&#xff0c;支持 HDCCTV 高清协议和 CVBS 标 清协议&#xff0c;视频制式支持 720P/1080P 高清制式和 960H/D1 标清制式。芯片将接收到的高清 模拟复合视频信号经过模数转化&#xff0c;视频解码以及 2D 图像处理之后&#xff0c;转…