rawforge 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rawforge-0.2.0/rawforge.egg-info → rawforge-0.2.2}/PKG-INFO +47 -2
- {rawforge-0.2.0 → rawforge-0.2.2}/README.md +38 -0
- rawforge-0.2.2/RawForge/application/ImageSaver.py +70 -0
- rawforge-0.2.2/RawForge/application/InferenceWorker.py +84 -0
- rawforge-0.2.2/RawForge/application/MODEL_REGISTRY.py +785 -0
- {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/application/ModelHandler.py +40 -32
- rawforge-0.2.2/RawForge/application/ModelHandlerTorch.py +144 -0
- rawforge-0.2.2/RawForge/application/ONNXBackend.py +33 -0
- rawforge-0.2.2/RawForge/application/TorchBackend.py +36 -0
- {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/application/dng_utils.py +104 -62
- {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/application/helpers/censored_fit.py +11 -9
- rawforge-0.2.2/RawForge/application/helpers/exiftools.py +14 -0
- rawforge-0.2.2/RawForge/application/helpers/get_backend.py +27 -0
- rawforge-0.2.2/RawForge/application/helpers/get_image.py +64 -0
- rawforge-0.2.2/RawForge/application/helpers/subtract_blacklevel.py +8 -0
- rawforge-0.2.2/RawForge/application/helpers/torchutils.py +11 -0
- rawforge-0.2.2/RawForge/application/helpers/utils.py +18 -0
- {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/application/postprocessing.py +34 -27
- rawforge-0.2.2/RawForge/main.py +231 -0
- {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/scripts/generate_keys.py +1 -1
- {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/scripts/sign_models.py +4 -3
- rawforge-0.2.2/RawForge/sidecar.py +78 -0
- {rawforge-0.2.0 → rawforge-0.2.2}/pyproject.toml +8 -5
- {rawforge-0.2.0 → rawforge-0.2.2/rawforge.egg-info}/PKG-INFO +47 -2
- {rawforge-0.2.0 → rawforge-0.2.2}/rawforge.egg-info/SOURCES.txt +8 -0
- rawforge-0.2.2/rawforge.egg-info/entry_points.txt +3 -0
- {rawforge-0.2.0 → rawforge-0.2.2}/rawforge.egg-info/requires.txt +10 -1
- rawforge-0.2.0/RawForge/application/ImageSaver.py +0 -55
- rawforge-0.2.0/RawForge/application/InferenceWorker.py +0 -79
- rawforge-0.2.0/RawForge/application/MODEL_REGISTRY.py +0 -135
- rawforge-0.2.0/RawForge/application/helpers/get_image.py +0 -41
- rawforge-0.2.0/RawForge/application/helpers/utils.py +0 -17
- rawforge-0.2.0/RawForge/main.py +0 -77
- rawforge-0.2.0/rawforge.egg-info/entry_points.txt +0 -2
- {rawforge-0.2.0 → rawforge-0.2.2}/LICENSE +0 -0
- {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/__init__.py +0 -0
- {rawforge-0.2.0 → rawforge-0.2.2}/rawforge.egg-info/dependency_links.txt +0 -0
- {rawforge-0.2.0 → rawforge-0.2.2}/rawforge.egg-info/top_level.txt +0 -0
- {rawforge-0.2.0 → rawforge-0.2.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rawforge
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A compute backend/CLI application for using machine learning models on raw images.
|
|
5
5
|
Author: Ryan Mueller
|
|
6
6
|
License: MIT License
|
|
@@ -46,14 +46,21 @@ Requires-Dist: platformdirs~=4.5
|
|
|
46
46
|
Requires-Dist: tqdm~=4.67
|
|
47
47
|
Requires-Dist: cryptography>=46.0
|
|
48
48
|
Requires-Dist: tifffile
|
|
49
|
+
Requires-Dist: pyexiftool
|
|
49
50
|
Provides-Extra: cpu
|
|
50
51
|
Requires-Dist: onnxruntime; extra == "cpu"
|
|
51
52
|
Provides-Extra: cuda
|
|
52
53
|
Requires-Dist: onnxruntime-gpu; extra == "cuda"
|
|
53
54
|
Provides-Extra: web
|
|
54
|
-
Requires-Dist: onnxruntime-
|
|
55
|
+
Requires-Dist: onnxruntime-webgpu; extra == "web"
|
|
55
56
|
Provides-Extra: directml
|
|
56
57
|
Requires-Dist: onnxruntime-directml; extra == "directml"
|
|
58
|
+
Provides-Extra: torch
|
|
59
|
+
Requires-Dist: torch; extra == "torch"
|
|
60
|
+
Provides-Extra: fastapi
|
|
61
|
+
Requires-Dist: fastapi; extra == "fastapi"
|
|
62
|
+
Requires-Dist: pydantic; extra == "fastapi"
|
|
63
|
+
Requires-Dist: uvicorn; extra == "fastapi"
|
|
57
64
|
Dynamic: license-file
|
|
58
65
|
|
|
59
66
|
# RawRefinery
|
|
@@ -73,6 +80,41 @@ Currently in **alpha release**.
|
|
|
73
80
|
pip install rawforge
|
|
74
81
|
```
|
|
75
82
|
|
|
83
|
+
|
|
84
|
+
## New: ONNX backend!
|
|
85
|
+
|
|
86
|
+
### NVIDIA: For cuda (tested, must have CUDA installed):
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pip install rawforge[cuda]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### AMD and NVIDIA on Windows:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install rawforge[directml]
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
### All others, including M1+ Macs (CoreML)
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pip install rawforge[cpu]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### For web:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
pip install rawforge[web]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Useage is the same, but use the CLI "rawforgeonnx".
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
rawforgeonnx TreeNetDenoiseHeavy test.CR2 test_heavy.dng --cfa
|
|
116
|
+
```
|
|
117
|
+
|
|
76
118
|
---
|
|
77
119
|
## Example command line syntax:
|
|
78
120
|
|
|
@@ -105,6 +147,9 @@ options:
|
|
|
105
147
|
--chroma CHROMA Chroma noise (0-1).
|
|
106
148
|
```
|
|
107
149
|
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
108
153
|
----
|
|
109
154
|
|
|
110
155
|
## Acknowledgments
|
|
@@ -15,6 +15,41 @@ Currently in **alpha release**.
|
|
|
15
15
|
pip install rawforge
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
|
|
19
|
+
## New: ONNX backend!
|
|
20
|
+
|
|
21
|
+
### NVIDIA: For cuda (tested, must have CUDA installed):
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install rawforge[cuda]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### AMD and NVIDIA on Windows:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install rawforge[directml]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### All others, including M1+ Macs (CoreML)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install rawforge[cpu]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### For web:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install rawforge[web]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Useage is the same, but use the CLI "rawforgeonnx".
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
rawforgeonnx TreeNetDenoiseHeavy test.CR2 test_heavy.dng --cfa
|
|
51
|
+
```
|
|
52
|
+
|
|
18
53
|
---
|
|
19
54
|
## Example command line syntax:
|
|
20
55
|
|
|
@@ -47,6 +82,9 @@ options:
|
|
|
47
82
|
--chroma CHROMA Chroma noise (0-1).
|
|
48
83
|
```
|
|
49
84
|
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
50
88
|
----
|
|
51
89
|
|
|
52
90
|
## Acknowledgments
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from RawForge.application.dng_utils import convert_color_matrix, to_dng
|
|
3
|
+
import tifffile
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ImageSaver:
|
|
7
|
+
def __init__(self, model_params, rh, dims=None):
|
|
8
|
+
self.rh = rh
|
|
9
|
+
self.model_params = model_params
|
|
10
|
+
self.dims = dims
|
|
11
|
+
|
|
12
|
+
def to_tiff(self, image, filename, apply_ccm=True):
|
|
13
|
+
image = image
|
|
14
|
+
if apply_ccm:
|
|
15
|
+
transform_matrix = self.rh.rgb_colorspace_transform(
|
|
16
|
+
colorspace="lin_rec2020"
|
|
17
|
+
)
|
|
18
|
+
image = image[0].transpose(1, 2, 0)
|
|
19
|
+
transformed = image @ transform_matrix.T
|
|
20
|
+
else:
|
|
21
|
+
transformed = image[0].transpose(1, 2, 0)
|
|
22
|
+
|
|
23
|
+
transformed = np.clip(transformed, 0, 1)
|
|
24
|
+
transformed = transformed ** (1 / 2.2)
|
|
25
|
+
transformed = transformed * (2**8 - 1)
|
|
26
|
+
|
|
27
|
+
uint_img = transformed.astype(np.uint8)
|
|
28
|
+
|
|
29
|
+
tifffile.imwrite(
|
|
30
|
+
filename,
|
|
31
|
+
uint_img,
|
|
32
|
+
photometric="rgb", # Explicitly define the color space
|
|
33
|
+
compression="deflate", # Optional: Lossless compression supported by darktable
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
def to_raw(self, denoised, filename, save_cfa):
|
|
37
|
+
# Compute CFA
|
|
38
|
+
if self.model_params["demosaicing"] == "rawpy" or self.model_params["demosaicing"] == "sixchan":
|
|
39
|
+
if self.dims is None:
|
|
40
|
+
self.dims = [0, 9999999, 0, 9999999]
|
|
41
|
+
_, mask = self.rh.compute_mask_and_sparse(dims=self.dims)
|
|
42
|
+
denoised = denoised[0]
|
|
43
|
+
denoised = denoised.clip(0, 1)
|
|
44
|
+
|
|
45
|
+
denoised = np.where(mask, denoised, 0)
|
|
46
|
+
denoised = denoised.sum(axis=0)
|
|
47
|
+
denoised = (
|
|
48
|
+
denoised * (self.rh.core_metadata.white_level)
|
|
49
|
+
+ self.rh.core_metadata.black_level_per_channel[0]
|
|
50
|
+
)
|
|
51
|
+
self.rh.to_dng(filename, uint_img=denoised)
|
|
52
|
+
else:
|
|
53
|
+
transform_matrix = np.linalg.inv(
|
|
54
|
+
self.rh.rgb_colorspace_transform(colorspace=self.rh.colorspace)
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
CCM = self.rh.rgb_colorspace_transform(colorspace="XYZ")
|
|
58
|
+
CCM = np.linalg.inv(CCM)
|
|
59
|
+
denoised = denoised[0].transpose(1, 2, 0)
|
|
60
|
+
transformed = denoised @ transform_matrix.T
|
|
61
|
+
uint_img = np.clip(transformed * 2**16 - 1, 0, 2**16 - 1).astype(np.uint16)
|
|
62
|
+
ccm1 = convert_color_matrix(CCM)
|
|
63
|
+
to_dng(
|
|
64
|
+
uint_img,
|
|
65
|
+
self.rh,
|
|
66
|
+
filename,
|
|
67
|
+
ccm1,
|
|
68
|
+
save_cfa=save_cfa,
|
|
69
|
+
convert_to_cfa=True,
|
|
70
|
+
)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from blended_tiling_numpy import TilingModule
|
|
3
|
+
from tqdm import tqdm
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class InferenceWorker:
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
backend,
|
|
10
|
+
model_params,
|
|
11
|
+
conditioning,
|
|
12
|
+
disable_tqdm=False,
|
|
13
|
+
):
|
|
14
|
+
self.backend = backend
|
|
15
|
+
self.model_params = model_params
|
|
16
|
+
self.conditioning = conditioning
|
|
17
|
+
|
|
18
|
+
self.tile_size = model_params.get("tile_size", 256)
|
|
19
|
+
self.tile_overlap = model_params.get("tile_overlap", 0.25)
|
|
20
|
+
self.batch_size = model_params.get("batch_size", 2)
|
|
21
|
+
|
|
22
|
+
self.disable_tqdm = disable_tqdm
|
|
23
|
+
self._is_cancelled = False
|
|
24
|
+
|
|
25
|
+
def cancel(self):
|
|
26
|
+
self._is_cancelled = True
|
|
27
|
+
|
|
28
|
+
def _build_conditioning(self):
|
|
29
|
+
cond = np.array([self.conditioning], dtype=np.float32)
|
|
30
|
+
|
|
31
|
+
if "max_iso" in self.model_params:
|
|
32
|
+
cond[:, 0] = min(cond[:, 0], self.model_params["max_iso"])
|
|
33
|
+
cond[:, 0] /= 6400.0
|
|
34
|
+
cond[:, 1] = 0.0
|
|
35
|
+
cond = cond[:, :1].astype(np.float16)
|
|
36
|
+
|
|
37
|
+
if "cond_scale" in self.model_params:
|
|
38
|
+
cond *= cond * self.model_params["cond_scale"]
|
|
39
|
+
|
|
40
|
+
return self.backend.prepare_conditioning(cond)
|
|
41
|
+
|
|
42
|
+
def run(self, image_RGB, progress_callback=None):
|
|
43
|
+
|
|
44
|
+
full_size = image_RGB.shape[2:]
|
|
45
|
+
|
|
46
|
+
tiler = TilingModule(
|
|
47
|
+
tile_size=[self.tile_size] * 2,
|
|
48
|
+
tile_overlap=[self.tile_overlap] * 2,
|
|
49
|
+
base_size=list(full_size),
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
tiles = tiler.split_into_tiles(image_RGB)
|
|
53
|
+
|
|
54
|
+
batches = [
|
|
55
|
+
tiles[i:i+self.batch_size]
|
|
56
|
+
for i in range(0, len(tiles), self.batch_size)
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
cond = self._build_conditioning()
|
|
60
|
+
|
|
61
|
+
outputs = []
|
|
62
|
+
|
|
63
|
+
for i, batch in tqdm(
|
|
64
|
+
enumerate(batches),
|
|
65
|
+
total=len(batches),
|
|
66
|
+
disable=self.disable_tqdm,
|
|
67
|
+
):
|
|
68
|
+
|
|
69
|
+
if self._is_cancelled:
|
|
70
|
+
return None, None
|
|
71
|
+
|
|
72
|
+
outputs.append(
|
|
73
|
+
self.backend.infer(batch, cond)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
if progress_callback:
|
|
77
|
+
progress_callback((i + 1) / len(batches))
|
|
78
|
+
|
|
79
|
+
stitched = tiler.rebuild_with_masks(
|
|
80
|
+
np.concatenate(outputs, axis=0)
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
return image_RGB, stitched
|
|
84
|
+
|