"""Application to demo inpainting, Median and Bilateral Blur using streamlit. Run using: streamlit run 10_04_image_restoration_app.py """ import streamlit as st import pathlib from streamlit_drawable_canvas import st_canvas import cv2 import numpy as np import io import base64 from PIL import Image # # Function to create a download link for output image # def get_image_download_link(img, filename, text): # """Generates a link to download a particular image file.""" # buffered = io.BytesIO() # img.save(buffered, format='JPEG') # img_str = base64.b64encode(buffered.getvalue()).decode() # href = f'{text}' # return href # Set title. st.sidebar.title('Image Restoration App with OpenCV') # Description st.sidebar.text('Upload an image and apply various restoration techniques.') # Specify canvas parameters in application uploaded_file = st.sidebar.file_uploader("Upload Image to restore:", type=["png", "jpg"]) image = None res = None if uploaded_file is not None: # Convert the file to an opencv image. file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8) image = cv2.imdecode(file_bytes, 1) # Display the uploaded image st.subheader("Original Image") st.image(image[:, :, ::-1]) # Display a selection box for choosing the filter to apply. option = st.sidebar.selectbox('Median or Bilateral Blur or Inpaint?', ('None', 'Median Blur', 'Bilateral Blur', 'Image Inpaint')) if option == 'Median Blur': ksize = st.sidebar.slider("ksize: ", 3, 15, 5, 2) image = cv2.medianBlur(image, ksize) res=image[:,:,::-1] st.subheader("Median Blurred Image") st.image(res) # Display download button result = Image.fromarray(res) buffered = io.BytesIO() result.save(buffered, format="PNG") img_bytes = buffered.getvalue() st.download_button(label='Download Output', data=img_bytes, file_name='median_blur_output.png', mime='image/png') elif option == 'Bilateral Blur': dia = st.sidebar.slider("diameter: ", 1, 50, 20) sigmaColor = st.sidebar.slider("sigmaColor: ", 0, 250, 200, 10) sigmaSpace = st.sidebar.slider("sigmaSpace: ", 0, 250, 100, 10) image = cv2.bilateralFilter(image, dia, sigmaColor, sigmaSpace) res=image[:,:,::-1] st.subheader("Bilateral Blurred Image") st.image(res) # Display download button result = Image.fromarray(res) buffered = io.BytesIO() result.save(buffered, format="PNG") img_bytes = buffered.getvalue() st.download_button(label='Download Output', data=img_bytes, file_name='bilateral_blur_output.png', mime='image/png') elif option == 'Image Inpaint': stroke_width = st.sidebar.slider("Stroke width: ", 1, 25, 5) h, w = image.shape[:2] if w > 800: h_, w_ = int(h * 800 / w), 800 else: h_, w_ = h, w # Create a canvas component. st.subheader("Draw over the areas you want to inpaint:") canvas_result = st_canvas( fill_color='white', stroke_width=stroke_width, stroke_color='black', background_image=Image.open(uploaded_file).resize((h_, w_)), update_streamlit=True, height=h_, width=w_, drawing_mode='freedraw', key="canvas", ) stroke = canvas_result.image_data if stroke is not None: if st.sidebar.checkbox('show mask'): st.subheader("Mask") st.image(stroke) mask = cv2.split(stroke)[3] mask = np.uint8(mask) mask = cv2.resize(mask, (w, h)) st.sidebar.caption('Happy with the selection?') option = st.sidebar.selectbox('Mode', ['None', 'Telea', 'NS', 'Compare both']) if option == 'Telea': st.subheader('Result of Telea') res = cv2.inpaint(src=image, inpaintMask=mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA)[:,:,::-1] st.image(res) # Display download button result = Image.fromarray(res) buffered = io.BytesIO() result.save(buffered, format="PNG") img_bytes = buffered.getvalue() st.download_button(label='Download Output', data=img_bytes, file_name='inpaint_telea_output.png', mime='image/png') elif option == 'Compare both': col1, col2 = st.columns(2) res1 = cv2.inpaint(src=image, inpaintMask=mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA)[:,:,::-1] res2 = cv2.inpaint(src=image, inpaintMask=mask, inpaintRadius=3, flags=cv2.INPAINT_NS)[:,:,::-1] with col1: st.subheader('Result of Telea') st.image(res1) # Display download button result1 = Image.fromarray(res1) buffered1 = io.BytesIO() result1.save(buffered1, format="PNG") img_bytes1 = buffered1.getvalue() st.download_button(label='Download Output', data=img_bytes1, file_name='inpaint_telea_output.png', mime='image/png') with col2: st.subheader('Result of NS') st.image(res2) # Display download button result2 = Image.fromarray(res2) buffered2 = io.BytesIO() result2.save(buffered2, format="PNG") img_bytes2 = buffered2.getvalue() st.download_button(label='Download Output', data=img_bytes2, file_name='inpaint_ns_output.png', mime='image/png') elif option == 'NS': st.subheader('Result of NS') res = cv2.inpaint(src=image, inpaintMask=mask, inpaintRadius=3, flags=cv2.INPAINT_NS)[:,:,::-1] st.image(res) # Display download button result = Image.fromarray(res) buffered = io.BytesIO() result.save(buffered, format="PNG") img_bytes = buffered.getvalue() st.download_button(label='Download Output', data=img_bytes, file_name='inpaint_ns_output.png', mime='image/png') else: pass