Metadata-Version: 2.1
Name: nightfocus
Version: 0.1.1
Summary: autofocus algorithms for clear night sky
Author: Vincent Berenz
Author-email: vincent.berenz@tuebingen.mpg.de
Requires-Python: >=3.9,<4.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: click (==8.1.8)
Requires-Dist: loguru (>=0.7.3,<0.8.0)
Requires-Dist: matplotlib (==3.9.4)
Requires-Dist: multipledispatch (>=1.0.0,<2.0.0)
Requires-Dist: opencv-python (>=4.11.0.86,<5.0.0.0)
Requires-Dist: pillow (>=11.2.1,<12.0.0)
Requires-Dist: pytest (>=8.3.5,<9.0.0)
Requires-Dist: rich (>=14.0.0,<15.0.0)
Requires-Dist: scikit-image (==0.24.0)
Requires-Dist: scikit-learn (==1.6.1)
Requires-Dist: scikit-optimize (==0.10.2)
Requires-Dist: scipy (==1.13.1)
Requires-Dist: tifffile (==2024.8.30)
Requires-Dist: tqdm (>=4.67.1,<5.0.0)
Requires-Dist: types-pillow (>=10.2.0.20240822,<11.0.0.0)
Requires-Dist: types-tqdm (>=4.67.0.20250516,<5.0.0.0)
Description-Content-Type: text/markdown

# NightFocus

[![Tests](https://github.com/MPI-IS/nightfocus/actions/workflows/tests.yml/badge.svg)](https://github.com/MPI-IS/nightfocus/actions/workflows/tests.yml)

## What it is

Simple python package for automated focus optimization of astrophotography image patches.

## How to use it

1. create a sublcass of Camera for your camera. It must implement the take_picture method:


```python
from nightfocus.camera import Camera

class MyCamera(Camera):
    def take_picture(self, focus: int) -> np.ndarray:
        raise NotImplementedError
```

2. perform focus optimization:

```python
from nightfocus import optimize_focus

best_focus, _ = optimize_focus(camera, bounds=(0, 100))
```

## Under the hood

NightFocus uses Bayesian optimization to find the best focus position. The default metric used is the tenengrad focus measure:

```python
def tenengrad(image: np.ndarray, ksize: int = 3) -> float:
    """
    Tenengrad focus measure based on gradient magnitude.
    Works well for star images and is computationally efficient.
    """
    if len(image.shape) == 3:
        gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    else:
        gray = image

    gx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=ksize)
    gy = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=ksize)
    return float(np.mean(gx**2 + gy**2))
```

Other metrics are available in the `nightfocus.focus_metrics` module:

```python
from nightfocus.focus_metrics import FOCUS_MEASURES

FOCUS_MEASURES = {
    "tenengrad": tenengrad,
    "modified_laplacian": modified_laplacian,
    "normalized_variance": normalized_variance,
    "spectral_energy": spectral_energy,
    "brenner_gradient": brenner_gradient,
    "threshold_count": threshold_count,
    "fast_entropy": fast_entropy,
    "wavelet_measure": wavelet_measure,
}
```

### How we know it works

It could find the correct focus when running on the datasets located in the `images` folder. A dataset file corresponds to a corresponding tiff image on which increasing values of blur where applied.

## Command Line Interface

NightFocus includes a CLI for common tasks:

```bash
nightfocus --help
```

It provides this commands:

- crops: Create random crops from an image.
- dataset: Generate blurred dataset from TIFF files with increasing blur.
- evaluate: Evaluate focus scoring on a dataset.
- evaluate-directory: Evaluate focus scoring on a directory of images.
- evaluate-metrics: Evaluate multiple focus metrics on a dataset and print results.
- view: View images from a dataset file with their focus values.

## Installation

```bash
pip install nightfocus
```

## Author

Vincent Berenz, Max Planck Institute for Intelligent Systems, Tuebingen, Germany


