Getting Started with Gradio for Python
Explore how to use the Gradio library to build simple and custom user interfaces in Python. This lesson guides you through creating a text transformation UI and more complex image processing interfaces using OpenCV, providing a foundation for developing barcode readers and other visual applications.
In this lesson, we’ll take a look at three examples that show how we can quickly create a user interface with Python and Gradio. A Gradio user interface can be used for many applications. The most common application is machine learning, but it can also be used for other applications, like computer vision and image processing.
In general, Gradio is a powerful tool that allows us to quickly create and share demos of any Python function with a UI. It’s particularly useful when we want to showcase our work to nontechnical users. Another use of Gradio is to get user feedback without the need for them to understand or interact directly with the code.
The first example demonstrates a simple text transformation function, converting input text into a title case. While this is a straightforward operation in Python, the Gradio interface allows this functionality to be easily accessed and used by anyone with access to the UI.
The second and third examples are more complex, as they involve image processing tasks using the OpenCV library. These two examples allow us to add text to an image.
In the second example, we’ll use a one-liner to quickly build an interface. This is also possible if we want more control over the placement of the Gradio interface elements. This will be shown in the third example.
The latter two examples involve more complex operations and illustrate the power of Gradio in creating interfaces for functions that take complex inputs like images.
All three examples provide an introduction to the Gradio library and demonstrate how we can quickly build a UI for image processing functions. We’ll use this knowledge in the next lesson to build an actual barcode reader.
Converting text to title case with Gradio
In this first example, we’ll create a simple Gradio UI that will take some text input and output it in the title case.
import gradio as gr
def title_case(text):
result = text.title()
return result
demo = gr.Interface(fn=title_case, inputs="text", outputs="text")
demo.launch(server_name="0.0.0.0", server_port=7860)Line 1: First, we import the gradio library and alias it as gr. The gradio is the Python library that allows us to create user interfaces for our Python functions quickly. We’ll be using this and the following lessons.
Lines 3–5: Next, we define a function called title_case() that takes one argument, text.
Inside the title_case() function, a line is calling the title() method on the text argument. The title() method is a built-in Python function that converts the first character of each word to uppercase and the remaining characters to lowercase. Finally, the title_case() function returns the result.
Line 7: To create a basic interface for a given function with Gradio, we can use gr.Interface(). This method creates an instance of the Interface class from the Gradio library. The fn parameter is the function that the interface will use. In this case, it is set to title_case(). The inputs and outputs parameters specify that the function takes a text input and returns a text output.
Line 9: Now we can launch the Gradio interface with demo.launch(). The server_name and server_port parameters are setting the IP address and port number of the web server. When this line is run, a web server is started, and a URL is printed to the console.
We can now enter text, and when we submit the form, the title_case() function will be called with the text we entered, and the result will be displayed in the interface.
When running the above script, we notice that the Gradio gr.Interface() function creates an interface with inputs and outputs as we have defined them. In addition to that, it also creates three buttons. These three buttons are the default for the one-liner UI function.
Here is an overview of the three buttons:
-
Clear button: The “Clear” button is used to reset all the input fields in the Gradio interface to their initial state. This is useful when we want to remove all current input data and start fresh. For example, if we have entered text, clicking the “Clear” button will remove the text from the input field.
-
Submit button: The “Submit” button is used to execute the function associated with the Gradio interface using the data currently in the input fields. When we click the “Submit” button, the input data is passed to the function, the function is executed, and the results are displayed in the output fields of the Gradio UI.
-
Flag button: The “Flag” button is used to flag an input-output pair for review. This is useful when we use Gradio to collect data or test a model. If the function produces an unexpected or incorrect result for a particular input, we can click the “Flag” button to mark that input-output pair. Flagged pairs are stored and can be reviewed later, which can be helpful for debugging our function or improving our model. In our examples here, we haven’t used this button.
Adding text to an image with a default UI
In this second example, we’ll learn how to create a simple UI that takes both text and an image as input and shows the image with the text overlayed as output.
import cv2
import gradio as gr
def add_text(text, image):
h,w = image.shape[:2]
cv2.putText(image, text, (20, h - 20), \
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
return image
demo = gr.Interface(fn=add_text, inputs=["text","image"], outputs="image")
demo.launch(server_name="0.0.0.0", server_port=7861)Lines 1–2: First, we import the libraries, cv2 and gradio as gr.
Lines 4–8: Next, we define a function called add_text() that takes two arguments, text and image. This function will put the text on an image.
Inside the add_text() function, image.shape[:2] gets the height h and width w of the image. The shape attribute of an image in OpenCV is a tuple that contains the number of rows (height), columns (width), and channels (if the image is color). The [:2] is slicing this tuple to get only the first two elements (height and width).
Using cv2.putText() from the OpenCV library, we can now add the text to the image. The parameters are as follows:
image: The image to add the text to.text: The text to add.(20, h - 20): The coordinates of the bottom-left corner of the text string in the image. In this case, the text will be pixels from the left edge and pixels from the bottom edge of the image.cv2.FONT_HERSHEY_SIMPLEX: The font type.0.5: The font scale (size).(0, 255, 0): The color of the text in BGR (Blue, Green, Red). In this case, the text will be green.2: The thickness of the lines used to draw the text.
Finally, the add_text() function returns the image with the added text.
Line 10: By writing demo = gr.Interface(), we create an instance of the Interface class from the Gradio library to set up a user interface, called demo, for our function.
In this case, the fn parameter is add_text(). The inputs parameter specifies that the function takes a text input and an image input. Note that these two inputs are in a list. The outputs parameter specifies that the function returns an image output.
Line 12: Finally, we can launch the Gradio interface with demo.launch(). We can now enter text and upload an image. When we submit the form, the add_text() function will be called with the text and image we provided. The resulting image with the added text will subsequently be displayed in the interface.
Creating a custom UI for adding text to an image
In the last example of this lesson, we’ll create a custom UI where we will have more control over the placement of the input, output, and button elements.
import cv2
import gradio as gr
print(gr.__version__)
def add_text(text, image):
h,w = image.shape[:2]
cv2.putText(image, text, (20, h - 20), \
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
return image
with gr.Blocks() as demo:
with gr.Row():
txt = gr.Text()
with gr.Row():
with gr.Column():
im = gr.Image(height=300, width=400)
btn = gr.Button(value="Add Text", variant="primary")
with gr.Column():
im_2 = gr.Image(height=300, width=400)
btn_2 = gr.ClearButton([im, im_2, txt])
btn.click(add_text, inputs=[txt, im], outputs=[im_2])
demo.launch(server_name="0.0.0.0", server_port=7862)Lines 1-2: To start out, we import the necessary libraries: cv2 and gradio. Where gradio has gr as its alias.
Lines 5-9: Next, we define a function called add_text() that takes two arguments, text and image.
Inside the add_text() function, we get the height and width of the image using image.shape[:2]. Then we call the cv2.putText() function from the OpenCV library to add the text to the image and return the image.
Now, instead of using gr.Interface() to create the interface, we can create the interface ourselves using various methods from the Gradio library.
Line 12: First, we can start a context manager for a Blocks object. The Blocks object is used to create a layout for the Gradio interface. The as demo is assigning this Blocks object to the variable demo.
Line 14: Next, we can create a context manager for a Row object using with gr.Row(). The Row object is used to create a row in the Gradio interface layout.
Line 15: We then create a Text object using gr.Text() and assign it to the variable txt. The Text object is a text input field in the Gradio interface.
Line 17: We can start another context manager for a Row object. This will create a second row in the interface layout.
Line 18: Inside this row, we create a context manager for a Column object using gr.Column(). The Column object is used to create a column in the interface layout.
In this column, we create two blocks:
-
First, we create an
Imageobject usinggr.Image()and assign it to the variableim. TheImageobject is an image input field in the Gradio interface. Theheightandwidthparameters are setting the size of the image input field. -
Below the image input field, we create a
Buttonobject usinggr.Button()and assign it to the variablebtn. Thevalueparameter is setting the text of the button. Thevariantparameter is setting the style of the button. In this case, the button will be styled as a primary button.
Line 23: Next, we create a second column in the current row of the Gradio interface layout. In this column, we again create two blocks:
-
First, we create another
Imageobject from the Gradio library and assign it to the variableim_2. This will be another image input field in our interface. -
Below the image input field, we place a
ClearButtonobject usinggr.ClearButton()and assign it to the variablebtn_2. TheClearButtonobject is a button in the Gradio interface that clears the values of the specified inputs and outputs when clicked. The parameter is a list of the inputs and outputs to clear. In this case, theim,im_2, andtxtinputs and outputs will be cleared when the button is clicked.
Line 27: To assign a click event handler to the button btn, we can then use btn.click(). When the button is clicked, the add_text() function will be called with the values of the txt and im inputs, and the result will be displayed in the im_2 output.
Line 29: To launch our custom Gradio interface, we can then again use demo.launch().
We can now enter text, upload an image, and click the buttons to add text to the image or clear the text from the image. The resulting image will be displayed in the interface.