setiastrosuitepro 1.6.4__py3-none-any.whl → 1.7.1.post2__py3-none-any.whl
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.
Potentially problematic release.
This version of setiastrosuitepro might be problematic. Click here for more details.
- setiastro/images/TextureClarity.svg +56 -0
- setiastro/images/abeicon.svg +16 -0
- setiastro/images/acv_icon.png +0 -0
- setiastro/images/colorwheel.svg +97 -0
- setiastro/images/cosmic.svg +40 -0
- setiastro/images/cosmicsat.svg +24 -0
- setiastro/images/first_quarter.png +0 -0
- setiastro/images/full_moon.png +0 -0
- setiastro/images/graxpert.svg +19 -0
- setiastro/images/last_quarter.png +0 -0
- setiastro/images/linearfit.svg +32 -0
- setiastro/images/narrowbandnormalization.png +0 -0
- setiastro/images/new_moon.png +0 -0
- setiastro/images/pixelmath.svg +42 -0
- setiastro/images/planetarystacker.png +0 -0
- setiastro/images/waning_crescent_1.png +0 -0
- setiastro/images/waning_crescent_2.png +0 -0
- setiastro/images/waning_crescent_3.png +0 -0
- setiastro/images/waning_crescent_4.png +0 -0
- setiastro/images/waning_crescent_5.png +0 -0
- setiastro/images/waning_gibbous_1.png +0 -0
- setiastro/images/waning_gibbous_2.png +0 -0
- setiastro/images/waning_gibbous_3.png +0 -0
- setiastro/images/waning_gibbous_4.png +0 -0
- setiastro/images/waning_gibbous_5.png +0 -0
- setiastro/images/waxing_crescent_1.png +0 -0
- setiastro/images/waxing_crescent_2.png +0 -0
- setiastro/images/waxing_crescent_3.png +0 -0
- setiastro/images/waxing_crescent_4.png +0 -0
- setiastro/images/waxing_crescent_5.png +0 -0
- setiastro/images/waxing_gibbous_1.png +0 -0
- setiastro/images/waxing_gibbous_2.png +0 -0
- setiastro/images/waxing_gibbous_3.png +0 -0
- setiastro/images/waxing_gibbous_4.png +0 -0
- setiastro/images/waxing_gibbous_5.png +0 -0
- setiastro/qml/ResourceMonitor.qml +84 -82
- setiastro/saspro/__main__.py +20 -1
- setiastro/saspro/_generated/build_info.py +2 -2
- setiastro/saspro/abe.py +37 -4
- setiastro/saspro/aberration_ai.py +364 -33
- setiastro/saspro/aberration_ai_preset.py +29 -3
- setiastro/saspro/acv_exporter.py +379 -0
- setiastro/saspro/add_stars.py +33 -6
- setiastro/saspro/astrospike_python.py +45 -3
- setiastro/saspro/backgroundneutral.py +108 -40
- setiastro/saspro/blemish_blaster.py +4 -1
- setiastro/saspro/blink_comparator_pro.py +150 -55
- setiastro/saspro/clahe.py +4 -1
- setiastro/saspro/continuum_subtract.py +4 -1
- setiastro/saspro/convo.py +13 -7
- setiastro/saspro/cosmicclarity.py +129 -18
- setiastro/saspro/crop_dialog_pro.py +123 -7
- setiastro/saspro/curve_editor_pro.py +181 -64
- setiastro/saspro/curves_preset.py +249 -47
- setiastro/saspro/doc_manager.py +245 -15
- setiastro/saspro/exoplanet_detector.py +120 -28
- setiastro/saspro/frequency_separation.py +1158 -204
- setiastro/saspro/ghs_dialog_pro.py +81 -16
- setiastro/saspro/graxpert.py +1 -0
- setiastro/saspro/gui/main_window.py +706 -264
- setiastro/saspro/gui/mixins/dock_mixin.py +245 -24
- setiastro/saspro/gui/mixins/file_mixin.py +35 -16
- setiastro/saspro/gui/mixins/menu_mixin.py +35 -1
- setiastro/saspro/gui/mixins/theme_mixin.py +160 -14
- setiastro/saspro/gui/mixins/toolbar_mixin.py +499 -24
- setiastro/saspro/gui/mixins/update_mixin.py +138 -36
- setiastro/saspro/gui/mixins/view_mixin.py +42 -0
- setiastro/saspro/halobgon.py +4 -0
- setiastro/saspro/histogram.py +184 -8
- setiastro/saspro/image_combine.py +4 -0
- setiastro/saspro/image_peeker_pro.py +4 -0
- setiastro/saspro/imageops/narrowband_normalization.py +816 -0
- setiastro/saspro/imageops/serloader.py +1345 -0
- setiastro/saspro/imageops/starbasedwhitebalance.py +23 -52
- setiastro/saspro/imageops/stretch.py +582 -62
- setiastro/saspro/isophote.py +4 -0
- setiastro/saspro/layers.py +13 -9
- setiastro/saspro/layers_dock.py +183 -3
- setiastro/saspro/legacy/image_manager.py +154 -20
- setiastro/saspro/legacy/numba_utils.py +68 -48
- setiastro/saspro/legacy/xisf.py +240 -98
- setiastro/saspro/live_stacking.py +203 -82
- setiastro/saspro/luminancerecombine.py +228 -27
- setiastro/saspro/mask_creation.py +174 -15
- setiastro/saspro/mfdeconv.py +113 -35
- setiastro/saspro/mfdeconvcudnn.py +119 -70
- setiastro/saspro/mfdeconvsport.py +112 -35
- setiastro/saspro/morphology.py +4 -0
- setiastro/saspro/multiscale_decomp.py +81 -29
- setiastro/saspro/narrowband_normalization.py +1618 -0
- setiastro/saspro/numba_utils.py +72 -57
- setiastro/saspro/ops/commands.py +18 -18
- setiastro/saspro/ops/script_editor.py +10 -2
- setiastro/saspro/ops/scripts.py +122 -0
- setiastro/saspro/perfect_palette_picker.py +37 -3
- setiastro/saspro/plate_solver.py +84 -49
- setiastro/saspro/psf_viewer.py +119 -37
- setiastro/saspro/remove_green.py +1 -1
- setiastro/saspro/resources.py +73 -0
- setiastro/saspro/rgbalign.py +460 -12
- setiastro/saspro/selective_color.py +4 -1
- setiastro/saspro/ser_stack_config.py +82 -0
- setiastro/saspro/ser_stacker.py +2321 -0
- setiastro/saspro/ser_stacker_dialog.py +1838 -0
- setiastro/saspro/ser_tracking.py +206 -0
- setiastro/saspro/serviewer.py +1625 -0
- setiastro/saspro/sfcc.py +662 -216
- setiastro/saspro/shortcuts.py +171 -33
- setiastro/saspro/signature_insert.py +692 -33
- setiastro/saspro/stacking_suite.py +1347 -485
- setiastro/saspro/star_alignment.py +247 -123
- setiastro/saspro/star_spikes.py +4 -0
- setiastro/saspro/star_stretch.py +38 -3
- setiastro/saspro/stat_stretch.py +892 -129
- setiastro/saspro/subwindow.py +787 -363
- setiastro/saspro/supernovaasteroidhunter.py +1 -1
- setiastro/saspro/texture_clarity.py +593 -0
- setiastro/saspro/wavescale_hdr.py +4 -1
- setiastro/saspro/wavescalede.py +4 -1
- setiastro/saspro/whitebalance.py +84 -12
- setiastro/saspro/widgets/common_utilities.py +28 -21
- setiastro/saspro/widgets/resource_monitor.py +209 -111
- setiastro/saspro/widgets/spinboxes.py +10 -13
- setiastro/saspro/wimi.py +27 -656
- setiastro/saspro/wims.py +13 -3
- setiastro/saspro/xisf.py +101 -11
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/METADATA +4 -2
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/RECORD +132 -87
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/WHEEL +0 -0
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/entry_points.txt +0 -0
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/licenses/LICENSE +0 -0
- {setiastrosuitepro-1.6.4.dist-info → setiastrosuitepro-1.7.1.post2.dist-info}/licenses/license.txt +0 -0
|
@@ -30,10 +30,10 @@ cached_star_sources: Optional[np.ndarray] = None
|
|
|
30
30
|
cached_flux_radii: Optional[np.ndarray] = None
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
def _tone_preserve_bg_neutralize(rgb: np.ndarray
|
|
33
|
+
def _tone_preserve_bg_neutralize(rgb: np.ndarray, *, return_pivot: bool = False):
|
|
34
34
|
"""
|
|
35
35
|
Neutralize background using the darkest grid patch in a tone-preserving way.
|
|
36
|
-
|
|
36
|
+
Returns float32 RGB in [0,1]. If return_pivot, also returns the patch median (pivot).
|
|
37
37
|
"""
|
|
38
38
|
h, w = rgb.shape[:2]
|
|
39
39
|
patch_size = 10
|
|
@@ -56,12 +56,15 @@ def _tone_preserve_bg_neutralize(rgb: np.ndarray) -> np.ndarray:
|
|
|
56
56
|
out = rgb.copy()
|
|
57
57
|
if best is not None:
|
|
58
58
|
avg = float(np.mean(best))
|
|
59
|
-
# “tone-preserving” shift+scale channel-wise toward avg
|
|
60
59
|
for c in range(3):
|
|
61
60
|
diff = float(best[c] - avg)
|
|
62
61
|
denom = (1.0 - diff) if abs(1.0 - diff) > 1e-8 else 1e-8
|
|
63
62
|
out[:, :, c] = np.clip((out[:, :, c] - diff) / denom, 0.0, 1.0)
|
|
64
|
-
|
|
63
|
+
|
|
64
|
+
if return_pivot:
|
|
65
|
+
pivot = best.astype(np.float32) if best is not None else np.median(rgb, axis=(0, 1)).astype(np.float32)
|
|
66
|
+
return out.astype(np.float32, copy=False), pivot
|
|
67
|
+
return out.astype(np.float32, copy=False)
|
|
65
68
|
|
|
66
69
|
|
|
67
70
|
def apply_star_based_white_balance(
|
|
@@ -73,38 +76,16 @@ def apply_star_based_white_balance(
|
|
|
73
76
|
) -> Tuple[np.ndarray, int, np.ndarray, np.ndarray, np.ndarray] | Tuple[np.ndarray, int, np.ndarray]:
|
|
74
77
|
"""
|
|
75
78
|
Star-based white balance with background neutralization and an RGB overlay of detected stars.
|
|
76
|
-
|
|
77
|
-
Parameters
|
|
78
|
-
----------
|
|
79
|
-
image : np.ndarray
|
|
80
|
-
RGB image (any dtype). Assumed RGB ordering.
|
|
81
|
-
threshold : float
|
|
82
|
-
SExtractor detection threshold (in background sigma).
|
|
83
|
-
autostretch : bool
|
|
84
|
-
If True, overlay is built from an autostretched view for visibility.
|
|
85
|
-
reuse_cached_sources : bool
|
|
86
|
-
If True, reuses star positions measured on a previous call (same scene).
|
|
87
|
-
return_star_colors : bool
|
|
88
|
-
If True, also returns (raw_star_pixels, after_star_pixels).
|
|
89
|
-
|
|
90
|
-
Returns
|
|
91
|
-
-------
|
|
92
|
-
balanced_rgb : float32 RGB in [0,1]
|
|
93
|
-
star_count : int
|
|
94
|
-
overlay_rgb : float32 RGB in [0,1] with star ellipses drawn
|
|
95
|
-
(optional) raw_star_pixels : (N,3) float array, colors sampled from ORIGINAL image
|
|
96
|
-
(optional) after_star_pixels : (N,3) float array, colors sampled after WB
|
|
79
|
+
(Correct version: does NOT crush data below the pivot.)
|
|
97
80
|
"""
|
|
98
81
|
if image.ndim != 3 or image.shape[2] != 3:
|
|
99
82
|
raise ValueError("apply_star_based_white_balance: input must be an RGB image (H,W,3).")
|
|
100
83
|
|
|
101
|
-
# 0) normalize
|
|
102
84
|
img_rgb = _to_float01(image)
|
|
103
85
|
|
|
104
|
-
# 1)
|
|
105
|
-
bg_neutral = _tone_preserve_bg_neutralize(img_rgb)
|
|
86
|
+
# 1) background neutralization + pivot (per-channel medians of darkest patch)
|
|
87
|
+
bg_neutral, pivot = _tone_preserve_bg_neutralize(img_rgb, return_pivot=True)
|
|
106
88
|
|
|
107
|
-
# 2) detect / reuse star positions
|
|
108
89
|
if sep is None:
|
|
109
90
|
raise ImportError(
|
|
110
91
|
"apply_star_based_white_balance requires the 'sep' package. "
|
|
@@ -135,7 +116,6 @@ def apply_star_based_white_balance(
|
|
|
135
116
|
cached_star_sources = sources
|
|
136
117
|
cached_flux_radii = r
|
|
137
118
|
|
|
138
|
-
# filter: small-ish, star-like
|
|
139
119
|
mask = (r > 0) & (r <= 10)
|
|
140
120
|
sources = sources[mask]
|
|
141
121
|
r = r[mask]
|
|
@@ -143,15 +123,14 @@ def apply_star_based_white_balance(
|
|
|
143
123
|
raise ValueError("All detected sources were rejected as non-stellar (too large).")
|
|
144
124
|
|
|
145
125
|
h, w = gray.shape
|
|
146
|
-
# raw colors from ORIGINAL image - optimized vectorized extraction
|
|
147
126
|
xs = sources["x"].astype(np.int32)
|
|
148
127
|
ys = sources["y"].astype(np.int32)
|
|
149
128
|
valid = (xs >= 0) & (xs < w) & (ys >= 0) & (ys < h)
|
|
129
|
+
|
|
150
130
|
raw_star_pixels = img_rgb[ys[valid], xs[valid], :]
|
|
151
131
|
|
|
152
|
-
#
|
|
132
|
+
# overlay
|
|
153
133
|
disp = stretch_color_image(bg_neutral.copy(), 0.25) if autostretch else bg_neutral.copy()
|
|
154
|
-
|
|
155
134
|
if cv2 is not None:
|
|
156
135
|
overlay_bgr = cv2.cvtColor((disp * 255).astype(np.uint8), cv2.COLOR_RGB2BGR)
|
|
157
136
|
for i in range(len(sources)):
|
|
@@ -160,41 +139,35 @@ def apply_star_based_white_balance(
|
|
|
160
139
|
theta_deg = float(sources["theta"][i] * 180.0 / np.pi)
|
|
161
140
|
center = (int(round(cx)), int(round(cy)))
|
|
162
141
|
axes = (max(1, int(round(3 * a))), max(1, int(round(3 * b))))
|
|
163
|
-
# red ellipse in BGR
|
|
164
142
|
cv2.ellipse(overlay_bgr, center, axes, angle=theta_deg, startAngle=0, endAngle=360,
|
|
165
143
|
color=(0, 0, 255), thickness=1)
|
|
166
144
|
overlay_rgb = cv2.cvtColor(overlay_bgr, cv2.COLOR_BGR2RGB).astype(np.float32) / 255.0
|
|
167
145
|
else:
|
|
168
|
-
# fallback: no ellipses, just the display image
|
|
169
146
|
overlay_rgb = disp.astype(np.float32, copy=False)
|
|
170
147
|
|
|
171
|
-
#
|
|
172
|
-
|
|
173
|
-
xs = sources["x"].astype(np.int32)
|
|
174
|
-
ys = sources["y"].astype(np.int32)
|
|
175
|
-
valid_mask = (xs >= 0) & (xs < w) & (ys >= 0) & (ys < h)
|
|
176
|
-
|
|
148
|
+
# star pixels for WB
|
|
149
|
+
valid_mask = valid
|
|
177
150
|
if not np.any(valid_mask):
|
|
178
151
|
raise ValueError("No stellar samples available for white balance.")
|
|
179
|
-
|
|
152
|
+
|
|
180
153
|
star_pixels = bg_neutral[ys[valid_mask], xs[valid_mask], :].astype(np.float32)
|
|
181
154
|
avg_color = np.mean(star_pixels, axis=0)
|
|
182
155
|
max_val = float(np.max(avg_color))
|
|
183
|
-
# protect against divide-by-zero
|
|
184
156
|
avg_color = np.where(avg_color <= 1e-8, 1e-8, avg_color)
|
|
185
|
-
scaling = max_val / avg_color
|
|
157
|
+
scaling = (max_val / avg_color).astype(np.float32) # (3,)
|
|
186
158
|
|
|
187
|
-
|
|
159
|
+
# ✅ Correct median-locked WB (NO hard floor)
|
|
160
|
+
m = pivot.reshape((1, 1, 3)).astype(np.float32)
|
|
161
|
+
g = scaling.reshape((1, 1, 3)).astype(np.float32)
|
|
188
162
|
|
|
189
|
-
|
|
190
|
-
balanced =
|
|
163
|
+
balanced = (bg_neutral.astype(np.float32) - m) * g + m
|
|
164
|
+
balanced = np.clip(balanced, 0.0, 1.0).astype(np.float32, copy=False)
|
|
191
165
|
|
|
192
|
-
# 6) collect after-WB star samples - optimized vectorized extraction
|
|
193
166
|
after_star_pixels = balanced[ys[valid_mask], xs[valid_mask], :]
|
|
194
167
|
|
|
195
168
|
if return_star_colors:
|
|
196
169
|
return (
|
|
197
|
-
balanced
|
|
170
|
+
balanced,
|
|
198
171
|
int(len(star_pixels)),
|
|
199
172
|
overlay_rgb.astype(np.float32, copy=False),
|
|
200
173
|
np.asarray(raw_star_pixels, dtype=np.float32),
|
|
@@ -202,9 +175,7 @@ def apply_star_based_white_balance(
|
|
|
202
175
|
)
|
|
203
176
|
|
|
204
177
|
return (
|
|
205
|
-
balanced
|
|
178
|
+
balanced,
|
|
206
179
|
int(len(star_pixels)),
|
|
207
180
|
overlay_rgb.astype(np.float32, copy=False),
|
|
208
181
|
)
|
|
209
|
-
|
|
210
|
-
|