# Multiscale BM3D filter for streak noise / ring artifact attenuation
This package contains the full pipeline for multiscale BM3D streak noise reduction in sinogram data as described in
Mäkinen, Y., Marchesini, S., Foi, A., 2021, \
"Ring artifact reduction via multiscale nonlocal collaborative filtering of spatially correlated noise" \
J. Synchrotron Rad. 28(3). DOI: http://doi.org/10.1107/S1600577521001910
## Usage:
The denoising is applied to **sinogram data**.
**NOTE**: Input data streaks should be along the first axis:
(theta, y, x)
or
(theta, x)
```python
from bm3d_streak_removal import *
```
For the full pipeline as described in the paper:
```python
data_denoised = full_streak_pipeline(data, brightfield, darkfield)
```
For extreme streak attenuation and multiscale denoising without normalizations
(input is presumed to be in log-scale):
```python
data_norm = extreme_streak_attenuation(data_norm)
data_denoised = multiscale_streak_removal(data_norm)
```
For a demo example, see the "demo" folder inside the package or download the demo files from https://webpages.tuni.fi/foi/streak/bm3d_streak_removal_demo.zip.
### Adjusting the filter:
All algorithm parameters are automatically calculated based on the input data.
The main extra parameter is the horizontal binning count ("K"). The automatic value is based solely on axis size; while the usually a good guess, it may be possible to improve denoising quality by adjusting it.
To reduce the number of scales (the denoising result was oversmooth in low frequencies):
```python
# Bin count when max_bin_iter_horizontal='auto' (default)
default_bin_count = default_horizontal_bins(data_norm)
# Use one scale less
data_denoised = multiscale_streak_removal(data_norm, max_bin_iter_horizontal=default_bin_count-1)
```
Likewise, if the widest streaks were not denoised:
```python
# Use one scale more
data_denoised = multiscale_streak_removal(data_norm, max_bin_iter_horizontal=default_bin_count+1)
```
For simple overall BM3D filtering strength adjustment, use the filter_strength parameter (default is 1):
```python
# Increase filtering strength slightly
data_denoised = multiscale_streak_removal(data_norm, filter_strength=1.1)
```
For other possible inputs, see the respective function comments in the Python file.
## License
The package is available for non-commercial use only. For details, see LICENSE.
## Authors:
Ymir Mäkinen (ymir.makinen@tuni.fi) \
Stefano Marchesini \
Alessandro Foi