Being able to choose between one input or another in Gradio

Hello, I made an object detection model and I managed to display predictions in Gradio using a webcam or uploading a picture, but in separated gradio apps, using as input:

input_1 = gr.inputs.Image(type='pil', label="Original Image", source="upload")

or

input_2 = gr.inputs.Image(type='pil', label="Original Image", source="webcam")

I’d like to have both options in the same app, so users would be able to choose between uploading a picture or making a picture using the webcam. I tried to pass both inputs as a list:
inputs = [input_1, input_2]

When I try to make the prediction the output image shows an error message. I tried setting the optional property in the inputs as True, but it still shows the error.

The interface goes like this:

input = gr.inputs.Image(type='pil', label="Original Image", source="upload", optional=True)
input_2 = gr.inputs.Image(type='pil', label="Original Image", source="webcam", optional=True)
inputs = [input, input_2]
outputs = gr.outputs.Image(type="pil", label="Output Image")
title = "Object detection with Yolov5"

gr.Interface(predict,
             inputs, 
             outputs, 
             title=title,
             theme="huggingface").launch(enable_queue=True)

And the predict function goes like this:

def predict(im, size=640):
    g = (size / max(im.size))  # gain
    im = im.resize((int(x * g) for x in im.size), Image.ANTIALIAS)  # resize

    results = model(im)  # inference
    results.render()  # updates results.imgs with boxes and labels
    return Image.fromarray(results.imgs[0])

Is there a way to make this or I should just keep the inputs as separated apps?

Thanks in advance

I think the issue lies in how you’re using your predict function. Gradio passes each input in order to your predict function, so right now if you have

def predict(im, size=640):

and your inputs are

inputs = [input, input_2]

then input is being passed into predict as im, and input_2 is being passed in as size. In other words, the uploaded image is being set to im, and the webcam image (even if it’s None) is being set to size. You should likely rename those parameters to be something like:

def predict(uploaded_image, webcam_image):

and then you can write some logic to decide which of the variables to use in that function. Alternatively, you could use a tabbed interface!

1 Like

Solved! Thank you

1 Like