Image Crop Comparator (ICC): A research-oriented, interactive image crop comparator for pixel-level method analysis, designed for a fast and flexible interactive workflow with multi-ROI selection, automatic layout arrangement, and rich customization options.
- ROI-based multi-image previewer for image restoration (or other else) tasks
- Fast and flexible multi-ROI selection via keyboard- and mouse-shortcut, with undo/redo support
- Automatic layout arrangement (left / right / top / bottom)
- Support for multiple workspace structures
- Highly customizable CLI for future research, and a user-friendly Web interface (gradio) for improved experience
- 2025.12.30 A quick demo of our tool is available on Hugging Face. ๐ค
- 2025.12.30 Update Web version, a Gradio-based UI, providing better user experience for broader users. ๐
- 2025.12.29 Update basic tutorial. ๐งพ
- 2025.12.28 Update ICC-CLI original-version, a runnable command-line (CLI) tool, including local/external sources, ROI selection, layout preview, and export. ๐
- Getting Started ๐
- User Guidance ๐งญ
- Reference โ๏ธ
- Community ๐ค
- Python 3.8+
- requirements.txt pins
opencv-python==4.7.*andnumpy==1.26.*; install withpip install -r requirements.txt. - Packages: opencv-python, numpy, natsort, Pillow
# Conda (recommended)
conda create -n crop-comparer python=3.10 -y # python>=3.8 (e.g. 3.9) is also supported, and python<=3.12 is recommended
conda activate crop-comparer
pip install -r requirements.txtvenv alternative
python -m venv .venv
source .venv/bin/activate # Windows: .venv\\Scripts\\activate
pip install -r requirements.txtpython compare.py- Local mode (default) expects the example datasets under
examples/; adjustRoot/Structurein the UI if using your own layout.
python gradio_app.py- Runs the Gradio UI locally on http://127.0.0.1:7860/ by default.
- Local mode (default) expects the example datasets under
examples/; adjustRoot/Structurein the UI if using your own layout.
(for default local source) Methods live under the workspace root, and each holds datasets.
<root>/
<method>/
<dataset>/
<images...>
Example
examples/ # <root>
A-Net/ # <method>
LOL-v2-real/ # <dataset>
00698.png # <images...>
00775.png
SDSD-indoor/
00101.png
00259.png
B-Former/
LOL-v2-real/
00698.png
00775.png
SDSD-indoor/
00101.png
00259.png
...
Supported structures (use `--structure`)
group-dataset-pair:<root>/<method>/<group>/<dataset>/<pair>/<img>.pnggroup-dataset(default classic):<root>/<method>/<group>/<dataset>/<img>.pngdataset-only:<root>/<method>/<dataset>/<img>.pngflat:<root>/<method>/<img>.pngshared:<root>/<image-id>/<method>.pngauto(default): tries the above in order.
Structure examples
group-dataset-pair(deep):<root>/<method>/<group>/<dataset>/<pair>/<img>.png
<root>/
<method1>/
<group>/
<dataset>/
<pair>/
<img1.png>
<img2.png>
...
<imgn.png>
<method2>/
<group>/
<dataset>/
<pair>/
<img1.png>
<img2.png>
...
<imgn.png>
group-dataset(default classic):<root>/<method>/<group>/<dataset>/<img>.png
<root>/
<method1>/
<group>/
<dataset>/
<img1.png>
<img2.png>
...
<imgn.png>
<method2>/
<group>/
<dataset>/
<img1.png>
<img2.png>
...
<imgn.png>
dataset-only:<root>/<method>/<dataset>/<img>.png(example of current default for local source)
<root>/
<method1>/
<dataset>/
<img1.png>
<img2.png>
...
<imgn.png>
<method2>/
<dataset>/
<img1.png>
<img2.png>
...
<imgn.png>
flat(images directly under method):<root>/<method>/<img>.png
<root>/
<method1>/
<img1.png>
<img2.png>
...
<imgn.png>
<method2>/
<img1.png>
<img2.png>
...
<imgn.png>
shared(per-image folders contain per-method files):<root>/<image-id>/<methodA>.png, <methodB>.png, ...
<root>/
<img1>/
<method1.png>
<method2.png>
...
<methodn.png>
<img2>/
<method1.png>
<method2.png>
...
<methodn.png>
auto(default): tries the above in order until images are found.
Keyboard
| Key | Action |
|---|---|
a |
Add new ROI |
1โ9 |
Add / select ROI by id; Tapping active id to reselect |
Shift+1โ9 |
Duplicate active ROI to target id or copy its size |
d |
Add ROI with active size |
โ โ โ โ |
Change layout direction |
z / y |
Undo / redo |
Enter |
Switch dataset (group/dataset or dataset) |
Space |
Jump to image by name |
n / p |
Next / previous image |
s |
Save outputs |
i |
Toggle idle (hide/show grids) |
r |
Clear all ROIs |
q / Esc |
Quit |
Note: Arrow keys (
โ โ โ โ) control the layout direction, not ROI movement. ROI movement is performed by mouse dragging in position mode.
Mouse
- Draw in selection mode; drag to reposition in position mode.
- Hold
Shiftwhile drawing a ROI: constrain to a square using the longer side.
Quick actions:
- Right-click on overlapping ROIs: cycle to the next higher id in that stack (wraps to smallest).
- Right-click outside any ROI: add the next ROI (same as
a). - Right-click down inside a ROI, release after the cursor leaves that ROI: delete it.
- Middle-button inside the active ROI: duplicate it to a new ROI, then drag the new ROI while holding.
- Middle-button inside a non-active ROI: copy the active ROI size to that ROI (Shift+digit).
Local images with auto-discovery:
python compare.py --source local --root <root> --group <group> --dataset <dataset> --layout rightExternal datasets
External (video-form) datasets require methods.txt:
python compare.py --source external --dataset SDSD-indoor --pair pair13 --layout leftCore switches
--source:localorexternal--root: workspace root (local)--group,--dataset,--pair: dataset selectors--structure: layout of files (see above)--output: output root directory
Display and layout
--layout:left|top|right|bottom--columns: grid columns for per-ROI previews--magnify/--scale: display-only magnification (ignored for multi-ROI final)--layout-padding: padding between crops and base image--display-thickness-mult: overlay thickness multiplier for final layout
Interaction defaults
--mode:selection|position|idle--preview: method key for final preview (GT/inputif present)--thickness: ROI and crop border thickness
Logging
--log-level:debug|info|warn|error--no-color: disable ANSI colors
On s, outputs are written to:
<output>/<timestamp>/<dataset>/<image-basename>/
orig_<method>.png
final_<method>.png
crop_roi<id>_<method>.png
Each method writes its own originals, composed final previews, and all crops for active ROIs.
- Linux terminals show colored status messages: info (cyan), success (green), warnings (yellow), errors (red), notes (bright cyan).
- Toggle with
--no-color; set verbosity via--log-level.
Issue:
cv2.error: OpenCV(4.7.0) /io/opencv/modules/highgui/src/window.cpp:1266: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvDestroyAllWindows'
Solution:
- uninstall
opencv-python-headlessand reinstallopencv-python:pip uninstall opencv-python-headless pip install "opencv-python==4.7.*" - If operation system is Linux, ensure GTK is installed:
sudo apt-get install libgtk2.0-dev pkg-config
- โญ If you like ICC, give it a star. It helps others discover the project and supports its growth.















