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.
Files changed (39) hide show
  1. {rawforge-0.2.0/rawforge.egg-info → rawforge-0.2.2}/PKG-INFO +47 -2
  2. {rawforge-0.2.0 → rawforge-0.2.2}/README.md +38 -0
  3. rawforge-0.2.2/RawForge/application/ImageSaver.py +70 -0
  4. rawforge-0.2.2/RawForge/application/InferenceWorker.py +84 -0
  5. rawforge-0.2.2/RawForge/application/MODEL_REGISTRY.py +785 -0
  6. {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/application/ModelHandler.py +40 -32
  7. rawforge-0.2.2/RawForge/application/ModelHandlerTorch.py +144 -0
  8. rawforge-0.2.2/RawForge/application/ONNXBackend.py +33 -0
  9. rawforge-0.2.2/RawForge/application/TorchBackend.py +36 -0
  10. {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/application/dng_utils.py +104 -62
  11. {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/application/helpers/censored_fit.py +11 -9
  12. rawforge-0.2.2/RawForge/application/helpers/exiftools.py +14 -0
  13. rawforge-0.2.2/RawForge/application/helpers/get_backend.py +27 -0
  14. rawforge-0.2.2/RawForge/application/helpers/get_image.py +64 -0
  15. rawforge-0.2.2/RawForge/application/helpers/subtract_blacklevel.py +8 -0
  16. rawforge-0.2.2/RawForge/application/helpers/torchutils.py +11 -0
  17. rawforge-0.2.2/RawForge/application/helpers/utils.py +18 -0
  18. {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/application/postprocessing.py +34 -27
  19. rawforge-0.2.2/RawForge/main.py +231 -0
  20. {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/scripts/generate_keys.py +1 -1
  21. {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/scripts/sign_models.py +4 -3
  22. rawforge-0.2.2/RawForge/sidecar.py +78 -0
  23. {rawforge-0.2.0 → rawforge-0.2.2}/pyproject.toml +8 -5
  24. {rawforge-0.2.0 → rawforge-0.2.2/rawforge.egg-info}/PKG-INFO +47 -2
  25. {rawforge-0.2.0 → rawforge-0.2.2}/rawforge.egg-info/SOURCES.txt +8 -0
  26. rawforge-0.2.2/rawforge.egg-info/entry_points.txt +3 -0
  27. {rawforge-0.2.0 → rawforge-0.2.2}/rawforge.egg-info/requires.txt +10 -1
  28. rawforge-0.2.0/RawForge/application/ImageSaver.py +0 -55
  29. rawforge-0.2.0/RawForge/application/InferenceWorker.py +0 -79
  30. rawforge-0.2.0/RawForge/application/MODEL_REGISTRY.py +0 -135
  31. rawforge-0.2.0/RawForge/application/helpers/get_image.py +0 -41
  32. rawforge-0.2.0/RawForge/application/helpers/utils.py +0 -17
  33. rawforge-0.2.0/RawForge/main.py +0 -77
  34. rawforge-0.2.0/rawforge.egg-info/entry_points.txt +0 -2
  35. {rawforge-0.2.0 → rawforge-0.2.2}/LICENSE +0 -0
  36. {rawforge-0.2.0 → rawforge-0.2.2}/RawForge/__init__.py +0 -0
  37. {rawforge-0.2.0 → rawforge-0.2.2}/rawforge.egg-info/dependency_links.txt +0 -0
  38. {rawforge-0.2.0 → rawforge-0.2.2}/rawforge.egg-info/top_level.txt +0 -0
  39. {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.0
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-web; extra == "web"
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
+