--- title: Gradio DualVision Demo emoji: 👀 colorFrom: blue colorTo: red sdk: gradio sdk_version: 4.44.1 app_file: app.py pinned: true license: cc-by-sa-4.0 --- #### This thing ☝️ is metadata required at the top of README.md for hosting this exact repository as a Hugging Face Space 🤗. # Gradio DualVision [![Hugging Face Space](https://img.shields.io/badge/🤗%20Hugging%20Face%20-Space-yellow)](https://huggingface.co/spaces/toshas/gradio-dualvision) DualVision is a Gradio template app for image processing. It was developed to support the [Marigold](https://marigoldcomputervision.github.io) project. The app features: - A web interface, powered by [Gradio](www.gradio.app) and [gradio-imageslider](https://github.com/pngwn/gradio-imageslider). - Compatibility with desktop and mobile browsers. - Native integration with Hugging Face Spaces. - GPU support in the backend, including Hugging Face [ZeroGPU](https://huggingface.co/docs/hub/spaces-zerogpu). - Easily upload input images, including from the camera roll. - Easily add configurable settings and see their effect instantly. - Instant processing and side-by-side inspection. - Multi-modal prediction: as it often happens, your algorithm can produce multiple images. - Radio-buttons for easy switch between the inputs and produced outputs. - A built-in examples gallery for a smoother user experience. ## Live demo YouTube video:
[![YouTube](http://i.ytimg.com/vi/8j0X8qXfKCg/hqdefault.jpg)](https://www.youtube.com/watch?v=8j0X8qXfKCg) This very space running live on Hugging Face Spaces: A few real examples: - [Marigold Depth](https://huggingface.co/spaces/prs-eth/marigold) ## Quick start Check out the template image processing [app.py](app.py); copy it and start modifying! 1. Install as a python package: `pip install git+https://github.com/toshas/gradio-dualvision.git`. 2. Create an `app.py` file. 3. Import and subclass from `DualVisionApp`. 4. Implement `build_user_components` and `process` methods, and optionally `make_header`. 5. Launch the app! ## DualVisionApp API - `title`: Title of the application (str, required). - `examples_path`: Base path where examples will be searched (Default: `"examples"`). - `examples_per_page`: How many examples to show at the bottom of the app (Default: `12`). - `examples_cache`: Examples caching policy, corresponding to `cache_examples` argument of gradio.Examples (Default: `"lazy"`). - `squeeze_canvas`: When True, the image is fit to the browser viewport. When False, the image is fit to width (Default: `True`). - `squeeze_viewport_height_pct`: Percentage of the browser viewport height (Default: `75`). - `left_selector_visible`: Whether controls for changing modalities in the left part of the slider are visible (Default: `False`). - `advanced_settings_can_be_half_width`: Whether allow placing advanced settings dropdown in half-column space whenever possible (Default: `True`). - `key_original_image`: Name of the key under which the input image is shown in the modality selectors (Default: `"Original"`). - `spaces_zero_gpu_enabled`: When True, the app wraps the processing function with the ZeroGPU decorator. - `spaces_zero_gpu_duration`: Defines an integer duration in seconds passed into the ZeroGPU decorator. - `slider_position`: Position of the slider between 0 and 1 (Default: `0.5`). - `slider_line_color`: Color of the slider line (Default: `"#FFF"`). - `slider_line_width`: Width of the slider line (Default: `"4px"`). - `slider_arrows_color`: Color of the slider arrows (Default: `"#FFF"`). - `slider_arrows_width`: Width of the slider arrows (Default: `2px`). - `gallery_thumb_min_size`: Min size of the gallery thumbnail (Default: `96px`). - `**kwargs`: Any other arguments that Gradio Blocks class can take. **NB**: when setting `spaces_zero_gpu_enabled=True`, it may be required to add `import spaces` at the top of the app.py to avoid the `RuntimeError` with "CUDA has been initialized before importing the `spaces` package". ## Real talk **Q: What is the idea behind this template?**
A: Processing an image with various settings, inspecting multiple outputs side-by-side, and deploying such a demo with readily-accessible examples is a common pattern in computer vision and image processing. This template extends upon the [gradio-imageslider](https://github.com/pngwn/gradio-imageslider) custom component, adds modality selectors (radio buttons), and connects it all nicely with the Gradio's built-in Examples functionality. **Q: Isn't it exactly what `gradio-imageslider` is doing?**
A: Not quite. See the [gradio_dualvision/gradio_patches](gradio_dualvision/gradio_patches) directory for a complete set of version-specific changes required to wire it all up _nicely_. Indeed, a custom component with all these functions would be more efficient. **Q: What is the architecture of the template?**
- Inputs: an input image (that is either uploaded or sent from Examples), and any settings you create in the `build_user_components` override. - Outputs: a dictionary of `PIL.Image`s produced by your `process` function override, subsets of which you want to inspect side-by-side in the Slider. - State: a hidden `gradio.Gallery` component that stores all the output modalities from your `process` override. - Selectors: `gradio.Radio` buttons, which react to clicks and send requested images from the State to the Slider. - Slider: `gradio-imageslider` custom component that allows using the slider to reveal parts of the images. - Examples: `gradio.Examples` component that displays a gallery of example images, processes them upon the first click, and caches the result for next users. **Q: What are the conventions for `build_user_components` and `process` overrides?**
- `build_user_components` defines `gradio` components and their layout, which will be visible in the "Advanced Settings" dropdown under the Slider component. - Each such component will have a default value; it is possible to either hardcode it, or use a class variable, as it will be needed again in the `process` function (for example, define it as `self.DEFAULT_SETTING_VALUE`). - Associate a string with each created setting (for example, `"setting_name"`) that you want to pass around and output a dictionary of them. - `process` takes an image and `**kwargs`, which may or may not contain the settings of interest. - To resolve a setting, use `kwargs.get("setting_name", self.DEFAULT_SETTING_VALUE)` in order to fall back to the initial value of this setting. - This way, default settings will be applied only to Example images that did not have _custom example settings_. **Q: How do I specify custom default arguments for an example image?**
A: Just create a file called `.settings.json` and populate it with the custom settings for this sample - they will take precedence over the global default settings. **Q: How do I modify the app header?**
A: Override the `make_header` method and use `gradio.HTML` or `gradio.Markdown` to customize the header. **Q: What's up with the Example cats?**
These are the cats of the Marigold authors! ## Limitations - Does not work correctly inside the `TabbedInterface`. - Double copying between the hidden gallery component and the slider introduces visible flickering. - Fixed versions of `gradio==4.44.1` and `gradio_imageslider==0.0.20`; PRs are welcome but should start as a discussion in the [Issues](https://github.com/toshas/gradio-dualvision/issues) first. ## Citation: If you find this code useful, we kindly ask you to cite our papers: ``` @InProceedings{ke2023repurposing, title={Repurposing Diffusion-Based Image Generators for Monocular Depth Estimation}, author={Bingxin Ke and Anton Obukhov and Shengyu Huang and Nando Metzger and Rodrigo Caye Daudt and Konrad Schindler}, booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)}, year={2024} } ``` ## License [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/)