Skip to content

Commit

Permalink
Merge pull request #3 from juglab/jd/refac/refactor_code
Browse files Browse the repository at this point in the history
Refactor code
  • Loading branch information
ashesh-0 authored Sep 19, 2024
2 parents 8246b4e + 03a1dae commit 1e05c8a
Show file tree
Hide file tree
Showing 41 changed files with 3,809 additions and 1,627 deletions.
39 changes: 39 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
### Description

Please provide a brief description of the changes in this PR. Include any relevant context or background information.

- **What**: Clearly and concisely describe what changes you have made.
- **Why**: Explain the reasoning behind these changes. What problem are you solving? Why is this change necessary?
- **How**: Describe how you implemented these changes. Provide an overview of the approach and any important implementation details.

### Changes Made

- **Added**: List new features or files added.
- **Modified**: Describe existing features or files modified.
- **Removed**: Detail features or files that were removed.

### Related Issues

Link to any related issues or discussions. Use keywords like "Fixes", "Resolves", or "Closes" to link to issues automatically.

- Fixes #
- Resolves #
- Closes #

### Breaking changes

Describe any breaking change.


### Additional Notes and Examples

Include any additional notes or context that reviewers should be aware of, including snippets of code illustrating your new feature.

---

**Please ensure your PR meets the following requirements:**

- [ ] Code builds and passes tests locally, including doctests
- [ ] New tests have been added (for bug fixes/features)
- [ ] Pre-commit passes
- [ ] PR to the documentation exists (for bug fixes / features)
96 changes: 96 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: CI

on:
push:
branches:
- main
tags:
- "v*"
pull_request:
workflow_dispatch:
schedule:
# run every week (for --pre release tests)
- cron: "0 0 * * 0"

jobs:
check-manifest:
# check-manifest is a tool that checks that all files in version control are
# included in the sdist (unless explicitly excluded)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: pipx run check-manifest

test:
name: ${{ matrix.platform }} (${{ matrix.python-version }})
runs-on: ${{ matrix.platform }}
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories
platform: [ubuntu-latest, macos-13, windows-latest]

steps:
- name: 🛑 Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}

- uses: actions/checkout@v3

- name: 🐍 Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache-dependency-path: "pyproject.toml"
cache: "pip"

- name: Install Dependencies
run: |
python -m pip install -U pip
# if running a cron job, we add the --pre flag to test against pre-releases
python -m pip install .[dev] ${{ github.event_name == 'schedule' && '--pre' || '' }}
- name: 🧪 Run Tests
run: pytest --color=yes --cov --cov-config=pyproject.toml --cov-report=xml --cov-report=term-missing

- name: Coverage
uses: codecov/codecov-action@v3
with:
version: v0.7.3

deploy:
name: Release
needs: test
if: success() && startsWith(github.ref, 'refs/tags/') && github.event_name != 'schedule'
runs-on: ubuntu-latest

permissions:
# IMPORTANT: this permission is mandatory for trusted publishing
id-token: write

# This permission allows writing releases
contents: write

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.9"

- name: Build
run: |
python -m pip install build
python -m build
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

- uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# VSCode
.vscode

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down Expand Up @@ -160,3 +163,6 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

# Ruff
.ruff_cache
26 changes: 19 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,18 @@ ci:
autoupdate_commit_msg: "ci(pre-commit.ci): autoupdate"

repos:
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.18
hooks:
- id: validate-pyproject

- repo: https://github.com/psf/black
rev: 24.4.2
hooks:
- id: black

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.7
rev: v0.5.0
hooks:
- id: ruff
args: [--fix, --unsafe-fixes, --select, I]
Expand All @@ -15,12 +25,14 @@ repos:
rev: v1.10.0
hooks:
- id: mypy
files: "^microssim/.*\\.py$"
files: "^src/ri_ssim/.*\\.py$"
additional_dependencies:
- numpy
- pydantic
- pydantic-settings
- xarray
- types-tqdm
- pint
- platformdirs

# check docstrings
- repo: https://github.com/numpy/numpydoc
rev: v1.7.0
hooks:
- id: numpydoc-validation
exclude: "^notebooks/.*"
80 changes: 66 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,75 @@
# Objective
This is the official implementation of [MicroSSIM](https://arxiv.org/abs/2408.08747), accepted at BIC, ECCV 2024.
# MicroSSIM

MicroSSIM is an image measure aimed at addressing the shortcomings of the Structural
Similarity Index Measure (SSIM), in particular in the context of microscopy images. Indeed,
in microscopy, degraded images (e.g. lower signal to noise ratio) often have a different
dynamic range than the original images. This can lead to a poor performance of SSIM.

The measure normalizes the images using background subtraction and a more appropriate
range estimation. It then estimates a scaling factor used to scale the image
to the target (original image or ground truth). The metric is then computed
similarly to the SSIM.

MicroSSIM is easily extensible to other SSIM-like measures, such as Multi-Scale SSIM
(MS-SSIM), for which we provide an example.

See the [paper](https://arxiv.org/abs/2408.08747) for more details.

## Installation
We will soon release the package on PyPI. For now, you can install the package by cloning the repository and running the following command:

```bash
git clone [email protected]:juglab/MicroSSIM.git
cd MicroSSIM
pip install -e .
pip install microssim
```


## Usage

```python
from microssim import MicroSSIM, MicroMS3IM
gt: N x H x W
pred: N x H x W
import numpy as np
from microssim import MicroSSIM, micro_structural_similarity
from skimage.metrics import structural_similarity

rng = np.random.default_rng(42)
N = 5
gt = 200 + rng.integers(0, 65535, (N, 256, 256)) # stack of different images
pred = rng.poisson(gt) / 10

# using the convenience function
result = micro_structural_similarity(gt, pred)
print(f"MicroSSIM: {result} (convenience function)")

ssim = MicroSSIM() # or MicroMS3IM()
ssim.fit(gt, pred)
# using the class allows fitting a large dataset, then scoring a subset
microssim = MicroSSIM()
microssim.fit(gt, pred) # fit the parameters

for i in range(N):
score = ssim.score(gt[i], pred[i])
print('SSIM score for', i, 'th image:', score)
score = microssim.score(gt[i], pred[i]) # score a single pair
print(f"MicroSSIM ({i}): {score}")

# compare with SSIM from skimage
for i in range(N):
score = structural_similarity(gt[i], pred[i], data_range=65535)
print(f"SSIM ({i}): {score}")
```

The code is similar for MicroMS3IM.

## Tips for deep learning

MicroSSIM was developed in the context of deep-learning, in which SSIM is often used
as a measure to compare denoised and ground-truth images. The tips presented here are
valid beyond deep-learning.

The larger the dataset, the better the estimate of the scaling factor will be. Therefore,
it is recommended to fit the measure on the entire dataset (e.g. the whole training
dataset). Once the data fitted, the `MSSIM` class has registered the parameters used
for normalization and scaling. You can then score a subset of the data (e.g. the validation
or test datasets) using the `score` method.



## Cite us

If you use MicroSSIM in your research, please cite us:

```
Ashesh, Ashesh, Joran Deschamps, and Florian Jug. "MicroSSIM: Improved Structural Similarity for Comparing Microscopy Data." arXiv preprint arXiv:2408.08747 (2024). [link](https://arxiv.org/abs/2408.08747).
31 changes: 0 additions & 31 deletions microssim/CARE_normalization.py

This file was deleted.

4 changes: 0 additions & 4 deletions microssim/__init__.py

This file was deleted.

Loading

0 comments on commit 1e05c8a

Please sign in to comment.