{"id":50828806,"url":"https://github.com/antoinehabis/deep-contourflow","last_synced_at":"2026-06-13T21:01:29.054Z","repository":{"id":192110358,"uuid":"686009705","full_name":"antoinehabis/Deep-ContourFlow","owner":"antoinehabis","description":"Unsupervised, one-shot, instance-based active contour using deep learning features in python.","archived":false,"fork":false,"pushed_at":"2025-08-06T20:12:35.000Z","size":218309,"stargazers_count":16,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-06T22:06:58.855Z","etag":null,"topics":["active-contour","background-removal","deep-learning","foreground-extraction","foreground-segmentation","instance-based-learning","machine-learning","one-shot-learning","python","torch","unsupervised","unsupervised-learning"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/antoinehabis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-09-01T14:17:46.000Z","updated_at":"2025-08-06T20:12:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"62a820a9-d817-482d-9aaf-6a90da7806da","html_url":"https://github.com/antoinehabis/Deep-ContourFlow","commit_stats":null,"previous_names":["antoinehabis/deep-active-contour","antoinehabis/deep-contourflow"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/antoinehabis/Deep-ContourFlow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antoinehabis%2FDeep-ContourFlow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antoinehabis%2FDeep-ContourFlow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antoinehabis%2FDeep-ContourFlow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antoinehabis%2FDeep-ContourFlow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/antoinehabis","download_url":"https://codeload.github.com/antoinehabis/Deep-ContourFlow/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antoinehabis%2FDeep-ContourFlow/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34300116,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["active-contour","background-removal","deep-learning","foreground-extraction","foreground-segmentation","instance-based-learning","machine-learning","one-shot-learning","python","torch","unsupervised","unsupervised-learning"],"created_at":"2026-06-13T21:00:41.933Z","updated_at":"2026-06-13T21:01:29.048Z","avatar_url":"https://github.com/antoinehabis.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# Deep ContourFlow\n\n### Training-free active contours powered by deep features\n\n[![Python](https://img.shields.io/badge/python-3.10+-3670A0?style=for-the-badge\u0026logo=python\u0026logoColor=ffdd54)](https://www.python.org/)\n[![PyTorch](https://img.shields.io/badge/PyTorch-EE4C2C?style=for-the-badge\u0026logo=pytorch\u0026logoColor=white)](https://pytorch.org/)\n[![arXiv](https://img.shields.io/badge/arXiv-2407.10696-b31b1b?style=for-the-badge)](https://arxiv.org/abs/2407.10696)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge)](./LICENSE)\n\n[![CI](https://github.com/antoinehabis/Deep-ContourFlow/actions/workflows/ci.yml/badge.svg)](https://github.com/antoinehabis/Deep-ContourFlow/actions/workflows/ci.yml)\n[![Open in Spaces](https://huggingface.co/datasets/huggingface/badges/resolve/main/open-in-hf-spaces-md.svg)](https://huggingface.co/spaces/antoinehabis/DeepContourFlow)\n\n[![torch-contour downloads](https://static.pepy.tech/badge/torch_contour/month)](https://pepy.tech/project/torch_contour)\n[![torch-contour total downloads](https://static.pepy.tech/badge/torch_contour)](https://pepy.tech/project/torch_contour)\n\n\u003c/div\u003e\n\n\u003e **Deep ContourFlow (DCF)** segments objects by *evolving a contour* — like a classical active contour / snake — but instead of hand-crafted image energies it is driven by the rich multi-scale features of a **frozen, pretrained CNN**. There is **no training and no annotated dataset required**: the contour itself is the only thing that is optimized.\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"./assets/contour_evolution.gif\" alt=\"Deep ContourFlow — a contour converging onto a lion\" width=\"340\"\u003e\n\n\u003csub\u003e\u003ci\u003eUnsupervised DCF — a single circle initialization flows toward the object boundary, guided only by deep features.\u003c/i\u003e\u003c/sub\u003e\n\n\u003c/div\u003e\n\n---\n\n## ✨ Why DCF?\n\n- 🧠 **Training-free** — uses a frozen ImageNet backbone (VGG16 / ResNet). No fine-tuning, no labels, no dataset to collect.\n- 🎯 **Two regimes in one repo** — fully **unsupervised** segmentation, or **one-shot** segmentation from a *single* annotated example.\n- 🔬 **Domain-agnostic** — works on natural images *and* medical imaging (histopathology, dermoscopy) out of the box.\n- 🪶 **Lightweight \u0026 interpretable** — you optimize an explicit contour (a set of points), so every step is visualizable and the output is a clean, closed boundary.\n- ⚡ **GPU / MPS ready** — built on PyTorch with optional mixed-precision.\n\n---\n\n## 🖼️ Results\n\n### Unsupervised — real-life images\n\nStarting from a simple circle, the contour is pushed to maximize the feature contrast between the inside and the outside of the curve.\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"./assets/lion.png\" alt=\"Unsupervised DCF on a lion\" width=\"100%\"\u003e\n\u003cimg src=\"./assets/flower0.png\" alt=\"Unsupervised DCF on a flower\" width=\"100%\"\u003e\n\u003cimg src=\"./assets/flower1.png\" alt=\"Unsupervised DCF on a flower\" width=\"100%\"\u003e\n\u003cimg src=\"./assets/pineapple.png\" alt=\"Unsupervised DCF on a pineapple\" width=\"100%\"\u003e\n\n\u003c/div\u003e\n\n### One-shot — medical imaging\n\nGiven a **single** support image + mask, DCF transfers the target appearance to new query images and evolves a contour to match it.\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src=\"./assets/skin_lesions.png\" alt=\"One-shot DCF on dermoscopy skin lesions\" width=\"100%\"\u003e\n\u003csub\u003e\u003ci\u003eDermoscopy — skin-lesion segmentation across optimization epochs.\u003c/i\u003e\u003c/sub\u003e\n\n\u003cbr\u003e\u003cbr\u003e\n\n\u003cimg src=\"./assets/tumor_region.png\" alt=\"One-shot DCF on histology tumor regions\" width=\"100%\"\u003e\n\u003csub\u003e\u003ci\u003eHistopathology — tumor-region segmentation, with ground truth on the right.\u003c/i\u003e\u003c/sub\u003e\n\n\u003c/div\u003e\n\n---\n\n## 🚀 Installation\n\n```bash\ngit clone https://github.com/antoinehabis/Deep-ContourFlow.git\ncd Deep-ContourFlow\npip install -e .\n```\n\nThis installs the `deep_contourflow` package (and all dependencies) in editable mode, so you can `from deep_contourflow import UnsupervisedDCF, OneShotDCF` from anywhere. Prefer a bare dependency install? `pip install -r requirements.txt` also works.\n\nDCF builds on the companion library [**`torch-contour`**](https://pypi.org/project/torch-contour/) (`Contour_to_mask`, `Contour_to_distance_map`, `CleanContours`, `Smoothing`, …), which is installed automatically.\n\n---\n\n## ⚡ Quick start\n\nTwo ready-to-run notebooks live in [`notebooks/`](./notebooks):\n\n| Notebook | Mode | Open in Colab |\n|----------|------|---------------|\n| [`unsupervised_dcf.ipynb`](./notebooks/unsupervised_dcf.ipynb) | Unsupervised | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/antoinehabis/Deep-ContourFlow/blob/master/notebooks/unsupervised_dcf.ipynb) |\n| [`oneshot_dcf.ipynb`](./notebooks/oneshot_dcf.ipynb) | One-shot | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/antoinehabis/Deep-ContourFlow/blob/master/notebooks/oneshot_dcf.ipynb) |\n\n\u003e In Colab, run a first cell to `!git clone` the repo and `%cd Deep-ContourFlow` so the `deep_contourflow` package is importable.\n\n### Unsupervised segmentation\n\nDrop your image in [`data/`](./data) and run:\n\n```python\nimport cv2, numpy as np, torch, matplotlib.pyplot as plt\nfrom torch_contour import CleanContours\nfrom deep_contourflow import UnsupervisedDCF as DCF\nfrom deep_contourflow.features import define_contour_init\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nheight = 512\n\n# 1. Load an image as a (1, 3, H, W) tensor in [0, 1]\nimg = cv2.resize(plt.imread(\"data/pineapple.jpg\"), (height, height)).astype(np.uint8)\ntensor = (torch.tensor(np.moveaxis(img, -1, 0)[None]) / 255).to(device)\n\n# 2. Initialize a circular contour\ncontour_init, _ = define_contour_init(n=height, shape=\"circle\", size=0.5)\ncontour_init = CleanContours().interpolate(contour_init, 200).clip(0, 1)\ncontour_init = torch.tensor(contour_init)[None, None].float().to(device)\n\n# 3. Evolve the contour — no training, no labels\ndcf = DCF(model=\"vgg16\", n_epochs=100, learning_rate=1e-2, area_force=1e-3, sigma=5e-1)\ncontours, loss_history, final_contour = dcf.predict(tensor, contour_init)\n```\n\n### One-shot segmentation\n\nProvide a **support image + mask** and a **query image**:\n\n```python\nfrom deep_contourflow import OneShotDCF as DCF\n\ndcf = DCF(n_epochs=200, nb_augment=100, learning_rate=1e-2,\n          augmentations=[\"rot90\", \"vflip\"], lambda_area=1e-3)\n\n# 1. Capture the target's features from a single annotated example\ndcf.fit(tensor_support, contour_support)\n\n# 2. Segment any new query image\ncontours, score, loss_history, energies = dcf.predict(tensor_query, contour_init)\n```\n\nSee the notebook for the full data-loading and visualization code.\n\n---\n\n## 🔍 How it works\n\nDCF revisits the classical **active contour (snake)** idea with modern deep features. A curve $\\Gamma$ is represented by a set of points and deformed by gradient descent — but the energy that drives it comes from a **pretrained, frozen CNN** rather than raw image gradients.\n\n1. **Feature extraction.** The input image is passed once through a frozen backbone (VGG16 by default; ResNet / ResNet-FPN also supported). Multi-scale activations are collected from several layers.\n2. **Inside / outside pooling.** The current contour is rasterized into a soft mask (via `torch-contour`), which splits the feature maps into *inside* ($f_\\text{in}$) and *outside* ($f_\\text{out}$) regions.\n3. **Contour energy.**\n   - **Unsupervised:** maximize the contrast between inside and outside — minimize $-\\lVert f_\\text{in} - f_\\text{out}\\rVert\\,/\\,\\lVert \\text{activations}\\rVert$ across scales.\n   - **One-shot:** minimize the distance between the query's contour features and the *support* features aggregated at `fit()` time over many augmentations.\n4. **Gradient flow.** The contour points are the **only** optimized variables. The displacement field is Gaussian-smoothed (`sigma`) and clipped (`clip`) for stable, regular evolution; an optional area term prevents collapse/explosion.\n5. **Stopping.** A piecewise-linear fit on the loss curve (unsupervised) or early-stopping (one-shot) selects when to stop, and an optional GrabCut post-processing refines the final boundary.\n\nBecause the backbone is never updated, DCF needs **zero training** — it works on a single image, and adapts to new domains simply by swapping the backbone.\n\n---\n\n## 📁 Repository layout\n\n```\ndeep_contourflow/        # The installable package\n├── unsupervised.py      #   UnsupervisedDCF\n├── oneshot.py           #   OneShotDCF (fit + predict)\n├── features.py          #   Feature aggregation \u0026 contour utilities\n├── postprocessing.py    #   Optional GrabCut refinement\n├── visualization.py     #   Contour-evolution plotting helpers\n└── models/              #   Frozen backbones (VGG16, ResNet, ResNet-FPN)\nnotebooks/                # Ready-to-run notebooks\ndata/                    # Sample images (+ ground-truth masks in data/gt)\nassets/                  # Figures used in this README\n```\n\n---\n\n## 📜 Citation\n\nIf you use this code, please cite:\n\n```bibtex\n@misc{habis2024deepcontourflowadvancingactive,\n      title        = {Deep ContourFlow: Advancing Active Contours with Deep Learning},\n      author       = {Antoine Habis and Vannary Meas-Yedid and Elsa Angelini and Jean-Christophe Olivo-Marin},\n      year         = {2024},\n      eprint       = {2407.10696},\n      archivePrefix= {arXiv},\n      primaryClass = {cs.CV},\n      url          = {https://arxiv.org/abs/2407.10696},\n}\n```\n\n---\n\n## 🤝 Contributing\n\nIssues and pull requests are welcome! If DCF helped your work, a ⭐ on the repo is the best way to support the project.\n\n## 📬 Contact\n\nAntoine Habis — [![Mail](https://img.shields.io/badge/Gmail-D14836?style=flat\u0026logo=gmail\u0026logoColor=white)](mailto:antoine.habis.tlcm@gmail.com)\n\n## 📄 License\n\nReleased under the [MIT License](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantoinehabis%2Fdeep-contourflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantoinehabis%2Fdeep-contourflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantoinehabis%2Fdeep-contourflow/lists"}