andfanilo / streamlit-drawable-canvas

Do you like Quick, Draw? Well what if you could train/predict doodles drawn inside Streamlit? Also draws lines, circles and boxes over background images for annotation.
https://drawable-canvas.streamlit.app/
MIT License
541 stars 83 forks source link

Canvas doesn't reset when I upload a new image #100

Open ajkailash opened 1 year ago

ajkailash commented 1 year ago

Hi, I am using the streamlit canvas element to build a demo app for a deep learning project and ran into a couple of issues. I've provided the app flow below for additional context.

  1. User uploads an image (the image is read, resized and displayed on the canvas)
  2. Bounding boxes for three objects are drawn by the user using the "rect" drawing mode. (The bounding box values are displayed as a data frame)
  3. Once done, the user clicks on submit to pass the image and bounding box coordinates to the DL model for inference
  4. The model returns a torch.Tensor. Which is converted to a numpy array and displayed using an image element.

When I upload a new image for testing, the bounding boxes draw for the pervious image are superimposed on the new image. Also, the data frame displayed for the previous image, is also displayed below the new image. I also tried to delete all the entries in the st.sesstion_state, but still does't work.

I have provide the code below (please ignore the model_run function call) I am not sure what I am doing wrong, any help on this would be much appreciated.


def main():
    about()
    main_app()

def clear_session():
    for key in st.session_state.keys():
        del st.session_state[key]

def main_app():
    drawing_mode = "rect"
    fill_color = "#00000000"
    stroke_width = st.sidebar.slider("Strok width", min_value=1, max_value=3, value=2)
    stroke_color = st.sidebar.color_picker("Stroke color hex code: ", "#FFFB00")
    uploaded_file = st.sidebar.file_uploader("Background image", type=["jpg", "jpeg"])
    realtime_update = st.sidebar.checkbox("Update in real time", True)
    if uploaded_file is not None:
        image = Image.open(uploaded_file)
        image = image.resize((512, 512))
    else:
        image = None
    #create a canvas element
    st.text("Uploaded image")
    canvas_result = st_canvas(
        fill_color= fill_color,
        stroke_width = stroke_width,
        height=512,
        width=512,
        stroke_color = stroke_color,
        drawing_mode=drawing_mode,
        background_image= image,
        update_streamlit= realtime_update,
        key="main_app",
    )
    btn_placeholder = st.empty()    
    btn_placeholder.button('Submit', disabled=True, key="dummy_btn")
    if canvas_result.json_data is not None:
        df = pd.json_normalize(canvas_result.json_data["objects"])
        if len(df) == 0:
            return
        anno_df = df[["top", "left", "width", "height"]]
        st.dataframe(anno_df)
        if len(anno_df) == 3:
            bbox1, bbox2, bbox3 = anno_df.iloc[0].to_list(), anno_df.iloc[1].to_list(), anno_df.iloc[2].to_list()
            btn_placeholder.button('Submit', disabled=False, key="submit-btn")

    st.text("Predicted image")
    pred_map_placeholder = st.empty()
    if "submit-btn" in st.session_state and st.session_state["submit-btn"]:
        with st.spinner('Running model inference.'):
            bbox_list = [bbox1, bbox2, bbox3]
            pred_map = model_run(image, bbox_list)
            count = round(pred_map.sum().item())
            pred_map_placeholder.image(pred_map)
            st.write(f"Count: {count}")
        st.success('Done!')
        st.button("Clear", on_click=clear_session, key="clear-btn")

if __name__ == "__main__":
    st.set_page_config(page_title="Sample")
    st.title("Sample")
    st.sidebar.subheader("Configuration")
    main()```