pingmapper 5.5.1__tar.gz → 5.5.3__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.
- {pingmapper-5.5.1 → pingmapper-5.5.3}/PKG-INFO +1 -1
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/class_rectObj.py +16 -2
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/class_sonObj.py +270 -16
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/class_sonObj_nadirgaptest.py +26 -2
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/default_params.json +4 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/gui_main.py +44 -2
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/main_readFiles.py +19 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/main_rectify.py +16 -0
- pingmapper-5.5.3/pingmapper/version.py +1 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper.egg-info/PKG-INFO +1 -1
- pingmapper-5.5.1/pingmapper/version.py +0 -1
- {pingmapper-5.5.1 → pingmapper-5.5.3}/LICENSE +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/README.md +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/__init__.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/__main__.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/class_mapSubstrateObj.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/class_portstarObj.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/doWork.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/funcs_common.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/funcs_model.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/funcs_rectify.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/main_mapSubstrate.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/nonGUI_batch_main.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/nonGui_main.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/processing_scripts/main_batchDirectory_2024-01-18_0926.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/processing_scripts/main_batchDirectory_2024-01-18_0929.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/scratch/funcs_pyhum_correct.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/scratch/main.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/scratch/main_batchDirectory.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/self_check.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/test_PINGMapper.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/test_cli_self_check.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/test_dq_filter.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/test_time.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/DRAFT_Workflows/avg_predictions_Mussel_WBL.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/DRAFT_Workflows/gen_centerline.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/DRAFT_Workflows/gen_centerline_from_bankline.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/DRAFT_Workflows/gen_centerline_trkpnts_fitspline_DRAFT.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/DRAFT_Workflows/testEXAMPLE_mosaic_logit.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/RawEGN_avg_predictions.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/00_substrate_logits_mosaic_transects.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/00_substrate_shps_mosaic_transects.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/01_gen_centerline_from_coverage.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/02_gen_summary_stamp_shps.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/03_gen_summary_shp.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/04_combine_summary_shp_csv.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/05_gen_summary_shp_plots.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/06_compare_raw-egn_volume.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/08_raw-egn_hardReacheFreq_hist.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/09_raw-egn_PatchSize_density.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/summarize_project_substrate.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/export_coverage.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/main_mosaic_transects.py +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper.egg-info/SOURCES.txt +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper.egg-info/dependency_links.txt +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper.egg-info/requires.txt +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper.egg-info/top_level.txt +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/pyproject.toml +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/setup.cfg +0 -0
- {pingmapper-5.5.1 → pingmapper-5.5.3}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pingmapper
|
|
3
|
-
Version: 5.5.
|
|
3
|
+
Version: 5.5.3
|
|
4
4
|
Summary: Open-source interface for processing recreation-grade side scan sonar datasets and reproducibly mapping benthic habitat
|
|
5
5
|
Author: Cameron Bodine, Daniel Buscombe, Iury T Simoes-Sousa
|
|
6
6
|
Author-email: bodine.cs@gmail.email
|
|
@@ -2724,6 +2724,8 @@ class rectObj(sonObj):
|
|
|
2724
2724
|
img = self.sonDat.copy()
|
|
2725
2725
|
if son:
|
|
2726
2726
|
img = self._reserve_zero_for_nodata(img, preserve_zeros=True)
|
|
2727
|
+
if bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False)):
|
|
2728
|
+
img = self._apply_display_enhancements(img)
|
|
2727
2729
|
apply_post_rect_colormap = use_16bit and self._rect_colormap_selected(son=son)
|
|
2728
2730
|
source_scale_bounds = None
|
|
2729
2731
|
if apply_post_rect_colormap:
|
|
@@ -2747,6 +2749,8 @@ class rectObj(sonObj):
|
|
|
2747
2749
|
out = np.flip(np.flip(np.flip(out,1),0),1)
|
|
2748
2750
|
if use_16bit:
|
|
2749
2751
|
out = out.astype(np.float32)
|
|
2752
|
+
elif bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False)):
|
|
2753
|
+
out = out.astype(np.float32)
|
|
2750
2754
|
else:
|
|
2751
2755
|
out = out.astype('uint8')
|
|
2752
2756
|
|
|
@@ -2780,7 +2784,10 @@ class rectObj(sonObj):
|
|
|
2780
2784
|
out16 = out16_raw
|
|
2781
2785
|
self._write_rect_geotiff(gtiff, out16, epsg, transform, colormap=None)
|
|
2782
2786
|
else:
|
|
2783
|
-
|
|
2787
|
+
if bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False)):
|
|
2788
|
+
out8 = self._convert_son_dat_to_uint8(out)
|
|
2789
|
+
else:
|
|
2790
|
+
out8 = np.clip(out, 0, 255).astype(np.uint8)
|
|
2784
2791
|
self._write_rect_geotiff(gtiff, out8, epsg, transform, colormap=self.son_colorMap)
|
|
2785
2792
|
|
|
2786
2793
|
del out, img
|
|
@@ -2815,6 +2822,8 @@ class rectObj(sonObj):
|
|
|
2815
2822
|
img = self.sonDat
|
|
2816
2823
|
if son:
|
|
2817
2824
|
img = self._reserve_zero_for_nodata(img, preserve_zeros=True)
|
|
2825
|
+
if bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False)):
|
|
2826
|
+
img = self._apply_display_enhancements(img)
|
|
2818
2827
|
apply_post_rect_colormap = son and use_16bit and self._rect_colormap_selected(son=son)
|
|
2819
2828
|
source_scale_bounds = None
|
|
2820
2829
|
if apply_post_rect_colormap:
|
|
@@ -2887,6 +2896,8 @@ class rectObj(sonObj):
|
|
|
2887
2896
|
out = np.flip(np.flip(np.flip(out,1),0),1)
|
|
2888
2897
|
if son and use_16bit:
|
|
2889
2898
|
out = out.astype(np.float32)
|
|
2899
|
+
elif son and (bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False))):
|
|
2900
|
+
out = out.astype(np.float32)
|
|
2890
2901
|
else:
|
|
2891
2902
|
out = out.astype('uint8')
|
|
2892
2903
|
|
|
@@ -2926,7 +2937,10 @@ class rectObj(sonObj):
|
|
|
2926
2937
|
self._write_rect_geotiff(gtiff, out16, epsg, transform, colormap=None)
|
|
2927
2938
|
else:
|
|
2928
2939
|
colormap = self.son_colorMap if son else class_colormap
|
|
2929
|
-
|
|
2940
|
+
if son and (bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False))):
|
|
2941
|
+
out8 = self._convert_son_dat_to_uint8(out)
|
|
2942
|
+
else:
|
|
2943
|
+
out8 = np.clip(out, 0, 255).astype(np.uint8)
|
|
2930
2944
|
self._write_rect_geotiff(gtiff, out8, epsg, transform, colormap=colormap)
|
|
2931
2945
|
|
|
2932
2946
|
del out
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
# SOFTWARE.
|
|
31
31
|
|
|
32
32
|
import os, sys
|
|
33
|
+
from skimage import exposure
|
|
33
34
|
|
|
34
35
|
# Add 'pingmapper' to the path, may not need after pypi package...
|
|
35
36
|
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
@@ -708,10 +709,34 @@ class sonObj(object):
|
|
|
708
709
|
else:
|
|
709
710
|
time_table = pd.read_csv(time_table)
|
|
710
711
|
|
|
712
|
+
if 'start_seconds' not in time_table.columns or 'end_seconds' not in time_table.columns:
|
|
713
|
+
raise ValueError("time_table must contain 'start_seconds' and 'end_seconds' columns.")
|
|
714
|
+
|
|
715
|
+
# Normalize to numeric and drop unusable rows.
|
|
716
|
+
time_table['start_seconds'] = pd.to_numeric(time_table['start_seconds'], errors='coerce')
|
|
717
|
+
time_table['end_seconds'] = pd.to_numeric(time_table['end_seconds'], errors='coerce')
|
|
718
|
+
time_table = time_table.dropna(subset=['start_seconds', 'end_seconds'])
|
|
719
|
+
|
|
720
|
+
if time_table.empty:
|
|
721
|
+
return sonDF
|
|
722
|
+
|
|
723
|
+
son_time = pd.to_numeric(sonDF[time_col], errors='coerce')
|
|
724
|
+
son_min = son_time.min()
|
|
725
|
+
|
|
726
|
+
# Auto-detect relative clip ranges when sonar time is epoch-like and
|
|
727
|
+
# clip-table values are small. This allows 0..N seconds-from-start.
|
|
728
|
+
tt_max = np.nanmax(np.abs(time_table[['start_seconds', 'end_seconds']].to_numpy(dtype=float)))
|
|
729
|
+
use_relative_seconds = np.isfinite(son_min) and son_min > 1e8 and np.isfinite(tt_max) and tt_max < 1e7
|
|
730
|
+
|
|
731
|
+
offset = float(son_min) if use_relative_seconds else 0.0
|
|
732
|
+
|
|
711
733
|
for i, row in time_table.iterrows():
|
|
712
734
|
|
|
713
|
-
start = row['start_seconds']
|
|
714
|
-
end = row['end_seconds']
|
|
735
|
+
start = float(row['start_seconds']) + offset
|
|
736
|
+
end = float(row['end_seconds']) + offset
|
|
737
|
+
|
|
738
|
+
if end < start:
|
|
739
|
+
start, end = end, start
|
|
715
740
|
|
|
716
741
|
# dfFilt = sonDF[(sonDF['time_s'] >= start) & (sonDF['time_s'] <= end)]
|
|
717
742
|
sonDF.loc[(sonDF[time_col] >= start) & (sonDF[time_col] <= end) & (sonDF[filtCol] == True), filtTimeCol] = True
|
|
@@ -1238,6 +1263,19 @@ class sonObj(object):
|
|
|
1238
1263
|
if np.isfinite(wf) and wf > 0:
|
|
1239
1264
|
dat = dat * (2.0 ** (-float(wf)))
|
|
1240
1265
|
|
|
1266
|
+
if bool(getattr(self, '_use_cerulean_power_scale', False)):
|
|
1267
|
+
dat = dat.astype(np.float32, copy=False)
|
|
1268
|
+
if hasattr(self, 'minPwrDb') and hasattr(self, 'maxPwrDb') and i < len(self.minPwrDb) and i < len(self.maxPwrDb):
|
|
1269
|
+
min_db = self.minPwrDb[i]
|
|
1270
|
+
max_db = self.maxPwrDb[i]
|
|
1271
|
+
if np.isfinite(min_db) and np.isfinite(max_db) and (max_db > min_db):
|
|
1272
|
+
# Issue #206: Cerulean pwr_results[] are normalized
|
|
1273
|
+
# uint16 values that must be rescaled with min/max dB.
|
|
1274
|
+
dat_db = float(min_db) + (dat / 65535.0) * (float(max_db) - float(min_db))
|
|
1275
|
+
# Keep values non-negative for downstream intensity
|
|
1276
|
+
# processing while preserving the per-ping dB span.
|
|
1277
|
+
dat = dat_db - float(min_db)
|
|
1278
|
+
|
|
1241
1279
|
n_samples = min(len(dat), sonDat.shape[0])
|
|
1242
1280
|
if n_samples <= 0:
|
|
1243
1281
|
skipped_reads += 1
|
|
@@ -1268,6 +1306,168 @@ class sonObj(object):
|
|
|
1268
1306
|
self.sonDat = self._convert_son_dat_to_uint8(sonDat)
|
|
1269
1307
|
return
|
|
1270
1308
|
|
|
1309
|
+
def _apply_display_enhancements(self, sonDat):
|
|
1310
|
+
"""Optional display-stage intensity transforms before uint8 mapping.
|
|
1311
|
+
|
|
1312
|
+
These transforms are intended to improve perceptual contrast of exported
|
|
1313
|
+
sonograms while keeping the processing pipeline opt-in and backward-
|
|
1314
|
+
compatible by default.
|
|
1315
|
+
"""
|
|
1316
|
+
use_db = bool(getattr(self, 'sonar_db_transform', False))
|
|
1317
|
+
use_clahe = bool(getattr(self, 'sonar_clahe', False))
|
|
1318
|
+
|
|
1319
|
+
if not use_db and not use_clahe:
|
|
1320
|
+
return sonDat
|
|
1321
|
+
|
|
1322
|
+
arr = self._apply_display_db_transform(sonDat)
|
|
1323
|
+
if arr.size == 0:
|
|
1324
|
+
return arr
|
|
1325
|
+
|
|
1326
|
+
valid = arr > 0
|
|
1327
|
+
if not np.any(valid):
|
|
1328
|
+
return arr
|
|
1329
|
+
|
|
1330
|
+
if use_clahe:
|
|
1331
|
+
clip_limit = float(getattr(self, 'sonar_clahe_clip_limit', 0.01))
|
|
1332
|
+
if (not np.isfinite(clip_limit)) or clip_limit <= 0:
|
|
1333
|
+
clip_limit = 0.01
|
|
1334
|
+
|
|
1335
|
+
global_bounds = None
|
|
1336
|
+
if bool(getattr(self, 'sonar_clahe_global', True)):
|
|
1337
|
+
global_bounds = self._ensure_clahe_global_bounds()
|
|
1338
|
+
|
|
1339
|
+
if global_bounds is not None:
|
|
1340
|
+
arr01 = self._normalize_with_bounds(arr, global_bounds[0], global_bounds[1])
|
|
1341
|
+
else:
|
|
1342
|
+
max_val = float(np.nanmax(arr))
|
|
1343
|
+
if not (np.isfinite(max_val) and max_val > 0):
|
|
1344
|
+
return arr
|
|
1345
|
+
arr01 = np.clip(arr / max_val, 0.0, 1.0)
|
|
1346
|
+
|
|
1347
|
+
try:
|
|
1348
|
+
arr01 = exposure.equalize_adapthist(arr01, clip_limit=clip_limit)
|
|
1349
|
+
arr = np.asarray(arr01, dtype=np.float32) * 255.0
|
|
1350
|
+
except MemoryError:
|
|
1351
|
+
arr = self._apply_clahe_chunked(arr01, clip_limit)
|
|
1352
|
+
except np.core._exceptions._ArrayMemoryError:
|
|
1353
|
+
arr = self._apply_clahe_chunked(arr01, clip_limit)
|
|
1354
|
+
|
|
1355
|
+
# Preserve no-data convention for empty samples.
|
|
1356
|
+
arr[~valid] = 0.0
|
|
1357
|
+
return arr
|
|
1358
|
+
|
|
1359
|
+
def _apply_display_db_transform(self, sonDat):
|
|
1360
|
+
arr = np.asarray(sonDat, dtype=np.float32)
|
|
1361
|
+
if arr.size == 0:
|
|
1362
|
+
return arr
|
|
1363
|
+
|
|
1364
|
+
arr[~np.isfinite(arr)] = 0.0
|
|
1365
|
+
arr[arr < 0] = 0.0
|
|
1366
|
+
|
|
1367
|
+
valid = arr > 0
|
|
1368
|
+
if not np.any(valid):
|
|
1369
|
+
return arr
|
|
1370
|
+
|
|
1371
|
+
if bool(getattr(self, 'sonar_db_transform', False)):
|
|
1372
|
+
# Use the smallest positive intensity as the log floor to avoid
|
|
1373
|
+
# collapsing zeros to -inf and to preserve relative low amplitudes.
|
|
1374
|
+
floor = float(np.nanmin(arr[valid]))
|
|
1375
|
+
if (not np.isfinite(floor)) or floor <= 0:
|
|
1376
|
+
floor = 1.0
|
|
1377
|
+
arr = np.maximum(arr, floor)
|
|
1378
|
+
arr = 20.0 * np.log10(arr)
|
|
1379
|
+
arr = arr - np.nanmin(arr)
|
|
1380
|
+
|
|
1381
|
+
arr[~valid] = 0.0
|
|
1382
|
+
return arr
|
|
1383
|
+
|
|
1384
|
+
def _ensure_clahe_global_bounds(self):
|
|
1385
|
+
if not bool(getattr(self, 'sonar_clahe_global', True)):
|
|
1386
|
+
return None
|
|
1387
|
+
|
|
1388
|
+
cache = getattr(self, '_sonar_clahe_global_bounds', None)
|
|
1389
|
+
if isinstance(cache, tuple) and len(cache) == 2:
|
|
1390
|
+
lo, hi = cache
|
|
1391
|
+
if np.isfinite(lo) and np.isfinite(hi) and hi > lo:
|
|
1392
|
+
return cache
|
|
1393
|
+
|
|
1394
|
+
if not hasattr(self, 'sonMetaDF'):
|
|
1395
|
+
self._loadSonMeta()
|
|
1396
|
+
|
|
1397
|
+
if not hasattr(self, 'sonMetaDF') or self.sonMetaDF is None or len(self.sonMetaDF) == 0:
|
|
1398
|
+
return None
|
|
1399
|
+
|
|
1400
|
+
saved_sonDat = getattr(self, 'sonDat', None)
|
|
1401
|
+
saved_sonDat16 = getattr(self, 'sonDat16', None)
|
|
1402
|
+
saved_pingMax = getattr(self, 'pingMax', None)
|
|
1403
|
+
|
|
1404
|
+
chunk_ids = pd.unique(self.sonMetaDF['chunk_id'])
|
|
1405
|
+
sample_cap = int(getattr(self, 'sonar_clahe_global_sample_cap', 200000))
|
|
1406
|
+
if sample_cap <= 0:
|
|
1407
|
+
sample_cap = 200000
|
|
1408
|
+
|
|
1409
|
+
sampled_vals = []
|
|
1410
|
+
for chunk in chunk_ids:
|
|
1411
|
+
self._getScanChunkSingle(int(chunk))
|
|
1412
|
+
arr = self._apply_display_db_transform(self.sonDat)
|
|
1413
|
+
valid = arr > 0
|
|
1414
|
+
if not np.any(valid):
|
|
1415
|
+
continue
|
|
1416
|
+
|
|
1417
|
+
vals = arr[valid].astype(np.float32, copy=False)
|
|
1418
|
+
if vals.size > sample_cap:
|
|
1419
|
+
idx = np.linspace(0, vals.size - 1, sample_cap, dtype=np.int64)
|
|
1420
|
+
vals = vals[idx]
|
|
1421
|
+
sampled_vals.append(vals)
|
|
1422
|
+
|
|
1423
|
+
if len(sampled_vals) == 0:
|
|
1424
|
+
self.sonDat = saved_sonDat
|
|
1425
|
+
self.sonDat16 = saved_sonDat16
|
|
1426
|
+
self.pingMax = saved_pingMax
|
|
1427
|
+
return None
|
|
1428
|
+
|
|
1429
|
+
pooled = np.concatenate(sampled_vals)
|
|
1430
|
+
lo = float(np.nanpercentile(pooled, 1.0))
|
|
1431
|
+
hi = float(np.nanpercentile(pooled, 99.5))
|
|
1432
|
+
if (not np.isfinite(lo)) or (not np.isfinite(hi)) or hi <= lo:
|
|
1433
|
+
lo = float(np.nanmin(pooled))
|
|
1434
|
+
hi = float(np.nanmax(pooled))
|
|
1435
|
+
|
|
1436
|
+
if (not np.isfinite(lo)) or (not np.isfinite(hi)) or hi <= lo:
|
|
1437
|
+
self.sonDat = saved_sonDat
|
|
1438
|
+
self.sonDat16 = saved_sonDat16
|
|
1439
|
+
self.pingMax = saved_pingMax
|
|
1440
|
+
return None
|
|
1441
|
+
|
|
1442
|
+
self._sonar_clahe_global_bounds = (lo, hi)
|
|
1443
|
+
self.sonDat = saved_sonDat
|
|
1444
|
+
self.sonDat16 = saved_sonDat16
|
|
1445
|
+
self.pingMax = saved_pingMax
|
|
1446
|
+
return self._sonar_clahe_global_bounds
|
|
1447
|
+
|
|
1448
|
+
def _apply_clahe_chunked(self, arr01, clip_limit):
|
|
1449
|
+
"""Apply CLAHE in row-wise stripes to reduce peak memory usage."""
|
|
1450
|
+
src = np.asarray(arr01, dtype=np.float32)
|
|
1451
|
+
h, w = src.shape
|
|
1452
|
+
if h == 0 or w == 0:
|
|
1453
|
+
return src
|
|
1454
|
+
|
|
1455
|
+
# Keep per-stripe working set bounded. equalize_adapthist promotes to
|
|
1456
|
+
# float64 internally, so we target moderate stripe sizes.
|
|
1457
|
+
stripe_rows = int(getattr(self, 'sonar_clahe_rows_per_chunk', 512))
|
|
1458
|
+
if stripe_rows <= 0:
|
|
1459
|
+
stripe_rows = 512
|
|
1460
|
+
stripe_rows = min(stripe_rows, h)
|
|
1461
|
+
|
|
1462
|
+
out = np.empty_like(src, dtype=np.float32)
|
|
1463
|
+
for start in range(0, h, stripe_rows):
|
|
1464
|
+
end = min(start + stripe_rows, h)
|
|
1465
|
+
stripe = src[start:end, :]
|
|
1466
|
+
stripe_eq = exposure.equalize_adapthist(stripe, clip_limit=clip_limit)
|
|
1467
|
+
out[start:end, :] = np.asarray(stripe_eq, dtype=np.float32) * 255.0
|
|
1468
|
+
|
|
1469
|
+
return out
|
|
1470
|
+
|
|
1271
1471
|
def _apply_tvg(self, sonDat):
|
|
1272
1472
|
sonDat = np.asarray(sonDat, dtype=np.float32)
|
|
1273
1473
|
|
|
@@ -1979,7 +2179,8 @@ class sonObj(object):
|
|
|
1979
2179
|
k,
|
|
1980
2180
|
imgOutPrefix,
|
|
1981
2181
|
tileFile='.jpg',
|
|
1982
|
-
colormap=False
|
|
2182
|
+
colormap=False,
|
|
2183
|
+
apply_display_enhancement=True):
|
|
1983
2184
|
'''
|
|
1984
2185
|
Using currently saved ping ping returns stored in self.sonDAT,
|
|
1985
2186
|
saves an unrectified image of the sonar echogram.
|
|
@@ -2016,7 +2217,15 @@ class sonObj(object):
|
|
|
2016
2217
|
data = self._prepare_export_uint16(self.sonDat)
|
|
2017
2218
|
data = self._reserve_zero_for_nodata(data)
|
|
2018
2219
|
else:
|
|
2019
|
-
|
|
2220
|
+
arr = self.sonDat
|
|
2221
|
+
if apply_display_enhancement and (bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False))):
|
|
2222
|
+
arr = self._apply_display_enhancements(arr)
|
|
2223
|
+
|
|
2224
|
+
if np.issubdtype(np.asarray(arr).dtype, np.floating):
|
|
2225
|
+
data = self._convert_son_dat_to_uint8(arr)
|
|
2226
|
+
else:
|
|
2227
|
+
data = np.clip(arr, 0, 255).astype(np.uint8)
|
|
2228
|
+
|
|
2020
2229
|
data = self._reserve_zero_for_nodata(data)
|
|
2021
2230
|
|
|
2022
2231
|
# File name zero padding
|
|
@@ -2039,7 +2248,8 @@ class sonObj(object):
|
|
|
2039
2248
|
k,
|
|
2040
2249
|
imgOutPrefix,
|
|
2041
2250
|
tileFile='.jpg',
|
|
2042
|
-
colormap=False
|
|
2251
|
+
colormap=False,
|
|
2252
|
+
apply_display_enhancement=True):
|
|
2043
2253
|
'''
|
|
2044
2254
|
Using currently saved ping ping returns stored in self.sonDAT,
|
|
2045
2255
|
saves an unrectified image of the sonar echogram.
|
|
@@ -2077,7 +2287,15 @@ class sonObj(object):
|
|
|
2077
2287
|
data = self._prepare_export_uint16(self.sonDat)
|
|
2078
2288
|
data = self._reserve_zero_for_nodata(data)
|
|
2079
2289
|
else:
|
|
2080
|
-
|
|
2290
|
+
arr = self.sonDat
|
|
2291
|
+
if apply_display_enhancement and (bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False))):
|
|
2292
|
+
arr = self._apply_display_enhancements(arr)
|
|
2293
|
+
|
|
2294
|
+
if np.issubdtype(np.asarray(arr).dtype, np.floating):
|
|
2295
|
+
data = self._convert_son_dat_to_uint8(arr)
|
|
2296
|
+
else:
|
|
2297
|
+
data = np.clip(arr, 0, 255).astype(np.uint8)
|
|
2298
|
+
|
|
2081
2299
|
data = self._reserve_zero_for_nodata(data)
|
|
2082
2300
|
|
|
2083
2301
|
# File name zero padding
|
|
@@ -2147,40 +2365,44 @@ class sonObj(object):
|
|
|
2147
2365
|
if self.wcp:
|
|
2148
2366
|
# Do speed correction
|
|
2149
2367
|
export_16bit = bool(getattr(self, 'export_16bit', False)) and not bool(getattr(self, 'son8bit', False))
|
|
2150
|
-
|
|
2368
|
+
pre_spd_enhance = (not export_16bit) and (bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False)))
|
|
2369
|
+
self._doSpdCor(chunk, spdCor=spdCor, mask_shdw=mask_shdw, maxCrop=maxCrop, do_egn=self.egn, stretch_wcp=True, integer=not export_16bit, pre_spd_enhance=pre_spd_enhance)
|
|
2151
2370
|
|
|
2152
2371
|
if self.sonDat is not np.nan:
|
|
2153
|
-
self._writeTilesPlot(chunk, imgOutPrefix='wcp', tileFile=tileFile, colormap=True)
|
|
2372
|
+
self._writeTilesPlot(chunk, imgOutPrefix='wcp', tileFile=tileFile, colormap=True, apply_display_enhancement=not pre_spd_enhance)
|
|
2154
2373
|
else:
|
|
2155
2374
|
pass
|
|
2156
2375
|
|
|
2157
2376
|
if self.wcm:
|
|
2158
2377
|
# Do speed correction
|
|
2159
2378
|
export_16bit = bool(getattr(self, 'export_16bit', False)) and not bool(getattr(self, 'son8bit', False))
|
|
2160
|
-
|
|
2379
|
+
pre_spd_enhance = (not export_16bit) and (bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False)))
|
|
2380
|
+
self._doSpdCor(chunk, spdCor=spdCor, mask_shdw=mask_shdw, mask_wc=True, maxCrop=maxCrop, do_egn=self.egn, stretch_wcp=True, integer=not export_16bit, pre_spd_enhance=pre_spd_enhance)
|
|
2161
2381
|
|
|
2162
2382
|
if self.sonDat is not np.nan:
|
|
2163
|
-
self._writeTilesPlot(chunk, imgOutPrefix='wcm', tileFile=tileFile, colormap=True)
|
|
2383
|
+
self._writeTilesPlot(chunk, imgOutPrefix='wcm', tileFile=tileFile, colormap=True, apply_display_enhancement=not pre_spd_enhance)
|
|
2164
2384
|
else:
|
|
2165
2385
|
pass
|
|
2166
2386
|
|
|
2167
2387
|
if self.wcr_src:
|
|
2168
2388
|
# Do speed correction
|
|
2169
2389
|
export_16bit = bool(getattr(self, 'export_16bit', False)) and not bool(getattr(self, 'son8bit', False))
|
|
2170
|
-
|
|
2390
|
+
pre_spd_enhance = (not export_16bit) and (bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False)))
|
|
2391
|
+
self._doSpdCor(chunk, spdCor=spdCor, mask_shdw=mask_shdw, src=True, maxCrop=maxCrop, do_egn=self.egn, stretch_wcp=True, integer=not export_16bit, pre_spd_enhance=pre_spd_enhance)
|
|
2171
2392
|
|
|
2172
2393
|
if self.sonDat is not np.nan:
|
|
2173
|
-
self._writeTilesPlot(chunk, imgOutPrefix='src', tileFile=tileFile, colormap=True)
|
|
2394
|
+
self._writeTilesPlot(chunk, imgOutPrefix='src', tileFile=tileFile, colormap=True, apply_display_enhancement=not pre_spd_enhance)
|
|
2174
2395
|
else:
|
|
2175
2396
|
pass
|
|
2176
2397
|
|
|
2177
2398
|
if self.wco:
|
|
2178
2399
|
# Do speed correction
|
|
2179
2400
|
export_16bit = bool(getattr(self, 'export_16bit', False)) and not bool(getattr(self, 'son8bit', False))
|
|
2180
|
-
|
|
2401
|
+
pre_spd_enhance = (not export_16bit) and (bool(getattr(self, 'sonar_db_transform', False)) or bool(getattr(self, 'sonar_clahe', False)))
|
|
2402
|
+
self._doSpdCor(chunk, spdCor=spdCor, mask_bed=True, maxCrop=maxCrop, do_egn=self.egn, stretch_wcp=True, integer=not export_16bit, pre_spd_enhance=pre_spd_enhance)
|
|
2181
2403
|
|
|
2182
2404
|
if self.sonDat is not np.nan:
|
|
2183
|
-
self._writeTilesPlot(chunk, imgOutPrefix='wco', tileFile=tileFile, colormap=True)
|
|
2405
|
+
self._writeTilesPlot(chunk, imgOutPrefix='wco', tileFile=tileFile, colormap=True, apply_display_enhancement=not pre_spd_enhance)
|
|
2184
2406
|
else:
|
|
2185
2407
|
pass
|
|
2186
2408
|
|
|
@@ -2200,7 +2422,8 @@ class sonObj(object):
|
|
|
2200
2422
|
son=True,
|
|
2201
2423
|
integer=True,
|
|
2202
2424
|
do_egn=False,
|
|
2203
|
-
stretch_wcp=False
|
|
2425
|
+
stretch_wcp=False,
|
|
2426
|
+
pre_spd_enhance=False):
|
|
2204
2427
|
|
|
2205
2428
|
if not hasattr(self, 'sonMetaDF'):
|
|
2206
2429
|
self._loadSonMeta()
|
|
@@ -2248,6 +2471,10 @@ class sonObj(object):
|
|
|
2248
2471
|
|
|
2249
2472
|
sonDat = self.sonDat
|
|
2250
2473
|
|
|
2474
|
+
if pre_spd_enhance and not export_16bit:
|
|
2475
|
+
sonDat = self._apply_display_enhancements(sonDat)
|
|
2476
|
+
self.sonDat = sonDat
|
|
2477
|
+
|
|
2251
2478
|
if spdCor == 0:
|
|
2252
2479
|
# Don't do speed correction
|
|
2253
2480
|
pass
|
|
@@ -2310,7 +2537,12 @@ class sonObj(object):
|
|
|
2310
2537
|
clip=False, preserve_range=True)#.astype('uint8')
|
|
2311
2538
|
|
|
2312
2539
|
if integer:
|
|
2313
|
-
|
|
2540
|
+
if pre_spd_enhance and np.issubdtype(np.asarray(sonDat).dtype, np.floating):
|
|
2541
|
+
# CLAHE outputs 0..1 floats; convert with robust scaling so
|
|
2542
|
+
# display-enhanced data does not collapse to near-black.
|
|
2543
|
+
self.sonDat = self._convert_son_dat_to_uint8(sonDat)
|
|
2544
|
+
else:
|
|
2545
|
+
self.sonDat = sonDat.astype('uint8')
|
|
2314
2546
|
else:
|
|
2315
2547
|
self.sonDat = sonDat
|
|
2316
2548
|
|
|
@@ -2413,6 +2645,12 @@ class sonObj(object):
|
|
|
2413
2645
|
self._use_jsf_weighting = True
|
|
2414
2646
|
self._ensure_jsf_global_scale_max(sonMetaAll)
|
|
2415
2647
|
|
|
2648
|
+
self._use_cerulean_power_scale = False
|
|
2649
|
+
if 'min_pwr_db' in sonMeta.columns and 'max_pwr_db' in sonMeta.columns:
|
|
2650
|
+
self.minPwrDb = pd.to_numeric(sonMeta['min_pwr_db'], errors='coerce').to_numpy(dtype=float)
|
|
2651
|
+
self.maxPwrDb = pd.to_numeric(sonMeta['max_pwr_db'], errors='coerce').to_numpy(dtype=float)
|
|
2652
|
+
self._use_cerulean_power_scale = True
|
|
2653
|
+
|
|
2416
2654
|
# Load chunk's sonar data into memory
|
|
2417
2655
|
self._loadSonChunk()
|
|
2418
2656
|
# Do PPDRC filter
|
|
@@ -2427,7 +2665,12 @@ class sonObj(object):
|
|
|
2427
2665
|
del self.bytesPerSample
|
|
2428
2666
|
if hasattr(self, 'weightingFactor'):
|
|
2429
2667
|
del self.weightingFactor
|
|
2668
|
+
if hasattr(self, 'minPwrDb'):
|
|
2669
|
+
del self.minPwrDb
|
|
2670
|
+
if hasattr(self, 'maxPwrDb'):
|
|
2671
|
+
del self.maxPwrDb
|
|
2430
2672
|
self._use_jsf_weighting = False
|
|
2673
|
+
self._use_cerulean_power_scale = False
|
|
2431
2674
|
|
|
2432
2675
|
return
|
|
2433
2676
|
|
|
@@ -2477,6 +2720,12 @@ class sonObj(object):
|
|
|
2477
2720
|
self._use_jsf_weighting = True
|
|
2478
2721
|
self._ensure_jsf_global_scale_max(sonMetaAll_full)
|
|
2479
2722
|
|
|
2723
|
+
self._use_cerulean_power_scale = False
|
|
2724
|
+
if 'min_pwr_db' in sonMeta.columns and 'max_pwr_db' in sonMeta.columns:
|
|
2725
|
+
self.minPwrDb = pd.to_numeric(sonMeta['min_pwr_db'], errors='coerce').to_numpy(dtype=float)
|
|
2726
|
+
self.maxPwrDb = pd.to_numeric(sonMeta['max_pwr_db'], errors='coerce').to_numpy(dtype=float)
|
|
2727
|
+
self._use_cerulean_power_scale = True
|
|
2728
|
+
|
|
2480
2729
|
# Load chunk's sonar data into memory
|
|
2481
2730
|
self._loadSonChunk()
|
|
2482
2731
|
|
|
@@ -2489,7 +2738,12 @@ class sonObj(object):
|
|
|
2489
2738
|
del self.bytesPerSample
|
|
2490
2739
|
if hasattr(self, 'weightingFactor'):
|
|
2491
2740
|
del self.weightingFactor
|
|
2741
|
+
if hasattr(self, 'minPwrDb'):
|
|
2742
|
+
del self.minPwrDb
|
|
2743
|
+
if hasattr(self, 'maxPwrDb'):
|
|
2744
|
+
del self.maxPwrDb
|
|
2492
2745
|
self._use_jsf_weighting = False
|
|
2746
|
+
self._use_cerulean_power_scale = False
|
|
2493
2747
|
|
|
2494
2748
|
return
|
|
2495
2749
|
|
|
@@ -686,10 +686,34 @@ class sonObj(object):
|
|
|
686
686
|
else:
|
|
687
687
|
time_table = pd.read_csv(time_table)
|
|
688
688
|
|
|
689
|
+
if 'start_seconds' not in time_table.columns or 'end_seconds' not in time_table.columns:
|
|
690
|
+
raise ValueError("time_table must contain 'start_seconds' and 'end_seconds' columns.")
|
|
691
|
+
|
|
692
|
+
# Normalize to numeric and drop unusable rows.
|
|
693
|
+
time_table['start_seconds'] = pd.to_numeric(time_table['start_seconds'], errors='coerce')
|
|
694
|
+
time_table['end_seconds'] = pd.to_numeric(time_table['end_seconds'], errors='coerce')
|
|
695
|
+
time_table = time_table.dropna(subset=['start_seconds', 'end_seconds'])
|
|
696
|
+
|
|
697
|
+
if time_table.empty:
|
|
698
|
+
return sonDF
|
|
699
|
+
|
|
700
|
+
son_time = pd.to_numeric(sonDF[time_col], errors='coerce')
|
|
701
|
+
son_min = son_time.min()
|
|
702
|
+
|
|
703
|
+
# Auto-detect relative clip ranges when sonar time is epoch-like and
|
|
704
|
+
# clip-table values are small. This allows 0..N seconds-from-start.
|
|
705
|
+
tt_max = np.nanmax(np.abs(time_table[['start_seconds', 'end_seconds']].to_numpy(dtype=float)))
|
|
706
|
+
use_relative_seconds = np.isfinite(son_min) and son_min > 1e8 and np.isfinite(tt_max) and tt_max < 1e7
|
|
707
|
+
|
|
708
|
+
offset = float(son_min) if use_relative_seconds else 0.0
|
|
709
|
+
|
|
689
710
|
for i, row in time_table.iterrows():
|
|
690
711
|
|
|
691
|
-
start = row['start_seconds']
|
|
692
|
-
end = row['end_seconds']
|
|
712
|
+
start = float(row['start_seconds']) + offset
|
|
713
|
+
end = float(row['end_seconds']) + offset
|
|
714
|
+
|
|
715
|
+
if end < start:
|
|
716
|
+
start, end = end, start
|
|
693
717
|
|
|
694
718
|
# dfFilt = sonDF[(sonDF['time_s'] >= start) & (sonDF['time_s'] <= end)]
|
|
695
719
|
sonDF.loc[(sonDF[time_col] >= start) & (sonDF[time_col] <= end) & (sonDF[filtCol] == True), filtTimeCol] = True
|
|
@@ -207,7 +207,7 @@ def gui(batch: bool):
|
|
|
207
207
|
tip_speed_min = ml_tip('Minimum vessel speed filter in m/s. 0=no minimum speed filter.')
|
|
208
208
|
tip_speed_max = ml_tip('Maximum vessel speed filter in m/s. 0=no maximum speed filter.')
|
|
209
209
|
tip_aoi = ml_tip('Optional polygon shapefile (.shp) to spatially filter sonar records to area of interest.')
|
|
210
|
-
tip_time_filter = ml_tip('
|
|
210
|
+
tip_time_filter = ml_tip('Filter by start/end time ranges. Use either relative seconds from recording start (e.g., 0-2000) or absolute Unix seconds.')
|
|
211
211
|
# Cropping
|
|
212
212
|
text_crop = sg.Text('Crop Range [m]', size=(22,1))
|
|
213
213
|
in_crop = sg.Input(key='cropRange', default_text=default_params['cropRange'], size=(10,1), tooltip=tip_crop)
|
|
@@ -280,6 +280,9 @@ def gui(batch: bool):
|
|
|
280
280
|
tip_egn_factor = ml_tip('Percent clip amount used by EGN Stretch Factor when Percent Clip is selected.')
|
|
281
281
|
tip_gamma = ml_tip('Tone curve control. <1 brightens mid-tones, >1 darkens mid-tones.')
|
|
282
282
|
tip_gain = ml_tip('Linear brightness multiplier. >1 brightens overall intensity, <1 darkens.')
|
|
283
|
+
tip_db = ml_tip('Apply 20*log10 transform before final 8-bit mapping. Helps reveal low-amplitude detail.')
|
|
284
|
+
tip_clahe = ml_tip('Apply adaptive histogram equalization (CLAHE) after dB transform for local contrast boost.')
|
|
285
|
+
tip_clahe_clip = ml_tip('CLAHE clip limit. Lower values are gentler; higher values increase local contrast.')
|
|
283
286
|
# EGN
|
|
284
287
|
check_egn = sg.Checkbox('Empiracal Gain Normalization (EGN)', key='egn', default=default_params['egn'], tooltip=tip_egn)
|
|
285
288
|
|
|
@@ -306,8 +309,43 @@ def gui(batch: bool):
|
|
|
306
309
|
default_value=float(default_params['tone_gain']),
|
|
307
310
|
tooltip=tip_gain,
|
|
308
311
|
)
|
|
312
|
+
check_sonar_db = sg.Checkbox(
|
|
313
|
+
'Display dB Transform',
|
|
314
|
+
key='sonar_db_transform',
|
|
315
|
+
default=default_params.get('sonar_db_transform', False),
|
|
316
|
+
tooltip=tip_db,
|
|
317
|
+
)
|
|
318
|
+
check_sonar_clahe = sg.Checkbox(
|
|
319
|
+
'Display CLAHE',
|
|
320
|
+
key='sonar_clahe',
|
|
321
|
+
default=default_params.get('sonar_clahe', False),
|
|
322
|
+
tooltip=tip_clahe,
|
|
323
|
+
)
|
|
324
|
+
check_sonar_clahe_global = sg.Checkbox(
|
|
325
|
+
'Global CLAHE reference',
|
|
326
|
+
key='sonar_clahe_global',
|
|
327
|
+
default=default_params.get('sonar_clahe_global', True),
|
|
328
|
+
tooltip='Use one project-wide intensity reference before CLAHE so chunk brightness stays consistent. This adds a prepass, but reduces chunk-to-chunk contrast shifts.',
|
|
329
|
+
)
|
|
330
|
+
text_clahe_clip = sg.Text('CLAHE Clip Limit', size=(20,1))
|
|
331
|
+
in_clahe_clip = sg.Input(
|
|
332
|
+
key='sonar_clahe_clip_limit',
|
|
333
|
+
default_text=default_params.get('sonar_clahe_clip_limit', 0.01),
|
|
334
|
+
size=(10,1),
|
|
335
|
+
tooltip=tip_clahe_clip,
|
|
336
|
+
)
|
|
309
337
|
|
|
310
|
-
col_egn_1 = sg.Column(
|
|
338
|
+
col_egn_1 = sg.Column(
|
|
339
|
+
[
|
|
340
|
+
[text_egn_gamma, slide_egn_gamma],
|
|
341
|
+
[text_egn_gain, slide_egn_gain],
|
|
342
|
+
[check_sonar_db],
|
|
343
|
+
[check_sonar_clahe],
|
|
344
|
+
[check_sonar_clahe_global],
|
|
345
|
+
[text_clahe_clip, in_clahe_clip],
|
|
346
|
+
],
|
|
347
|
+
pad=0,
|
|
348
|
+
)
|
|
311
349
|
col_egn_2 = sg.Column([[check_egn], [text_egn_stretch, combo_egn_stretch], [text_egn_factor, in_egn_factor]], pad=0)
|
|
312
350
|
# Add to layout
|
|
313
351
|
layout.append([sg.HorizontalSeparator()])
|
|
@@ -804,6 +842,10 @@ def gui(batch: bool):
|
|
|
804
842
|
'egn_stretch_factor':float(values['egn_stretch_factor']),
|
|
805
843
|
'tone_gamma':float(values['tone_gamma']),
|
|
806
844
|
'tone_gain':float(values['tone_gain']),
|
|
845
|
+
'sonar_db_transform':values['sonar_db_transform'],
|
|
846
|
+
'sonar_clahe':values['sonar_clahe'],
|
|
847
|
+
'sonar_clahe_global':values['sonar_clahe_global'],
|
|
848
|
+
'sonar_clahe_clip_limit':float(values['sonar_clahe_clip_limit']),
|
|
807
849
|
'wcp':values['wcp'],
|
|
808
850
|
'wcm':values['wcm'],
|
|
809
851
|
'wcr':values['wcr'],
|
|
@@ -718,6 +718,10 @@ def read_master_func(logfilename='',
|
|
|
718
718
|
egn_stretch_factor=1,
|
|
719
719
|
tone_gamma=1.0,
|
|
720
720
|
tone_gain=1.0,
|
|
721
|
+
sonar_db_transform=False,
|
|
722
|
+
sonar_clahe=False,
|
|
723
|
+
sonar_clahe_global=True,
|
|
724
|
+
sonar_clahe_clip_limit=0.01,
|
|
721
725
|
wcp=False,
|
|
722
726
|
wcm=False,
|
|
723
727
|
wcr=False,
|
|
@@ -1038,6 +1042,9 @@ def read_master_func(logfilename='',
|
|
|
1038
1042
|
son.son8bit = sonar_obj.son8bit
|
|
1039
1043
|
if hasattr(sonar_obj, 'sample_dtype'):
|
|
1040
1044
|
son.sample_dtype = sonar_obj.sample_dtype
|
|
1045
|
+
elif file_type == '.svlog':
|
|
1046
|
+
# Cerulean pwr_results are uint16 values in little-endian order.
|
|
1047
|
+
son.sample_dtype = '<u2'
|
|
1041
1048
|
if hasattr(sonar_obj, 'export_raw_16bit'):
|
|
1042
1049
|
son.export_raw_16bit = sonar_obj.export_raw_16bit
|
|
1043
1050
|
if hasattr(son, 'sample_dtype'):
|
|
@@ -1201,6 +1208,12 @@ def read_master_func(logfilename='',
|
|
|
1201
1208
|
son.cropRange = cropRange
|
|
1202
1209
|
son.tone_gamma = tone_gamma
|
|
1203
1210
|
son.tone_gain = tone_gain
|
|
1211
|
+
son.sonar_db_transform = bool(sonar_db_transform)
|
|
1212
|
+
son.sonar_clahe = bool(sonar_clahe)
|
|
1213
|
+
son.sonar_clahe_global = bool(sonar_clahe_global)
|
|
1214
|
+
son.sonar_clahe_clip_limit = float(sonar_clahe_clip_limit)
|
|
1215
|
+
if son.sonar_clahe:
|
|
1216
|
+
son._ensure_clahe_global_bounds()
|
|
1204
1217
|
# Do range crop, if necessary
|
|
1205
1218
|
if cropRange > 0.0:
|
|
1206
1219
|
if file_type == '.xtf' and _is_sidescan_beam(getattr(son, 'beamName', '')):
|
|
@@ -1394,6 +1407,12 @@ def read_master_func(logfilename='',
|
|
|
1394
1407
|
son.wcp = wcp
|
|
1395
1408
|
son.tone_gamma = tone_gamma
|
|
1396
1409
|
son.tone_gain = tone_gain
|
|
1410
|
+
son.sonar_db_transform = bool(sonar_db_transform)
|
|
1411
|
+
son.sonar_clahe = bool(sonar_clahe)
|
|
1412
|
+
son.sonar_clahe_global = bool(sonar_clahe_global)
|
|
1413
|
+
son.sonar_clahe_clip_limit = float(sonar_clahe_clip_limit)
|
|
1414
|
+
if son.sonar_clahe:
|
|
1415
|
+
son._ensure_clahe_global_bounds()
|
|
1397
1416
|
|
|
1398
1417
|
beam = son.beamName
|
|
1399
1418
|
if wcr:
|
|
@@ -126,6 +126,10 @@ def rectify_master_func(logfilename='',
|
|
|
126
126
|
egn_stretch_factor=1,
|
|
127
127
|
tone_gamma=1.0,
|
|
128
128
|
tone_gain=1.0,
|
|
129
|
+
sonar_db_transform=False,
|
|
130
|
+
sonar_clahe=False,
|
|
131
|
+
sonar_clahe_global=True,
|
|
132
|
+
sonar_clahe_clip_limit=0.01,
|
|
129
133
|
wcp=False,
|
|
130
134
|
wcm=False,
|
|
131
135
|
wcr=False,
|
|
@@ -368,6 +372,12 @@ def rectify_master_func(logfilename='',
|
|
|
368
372
|
son.rect_wcr = rect_wcr
|
|
369
373
|
son.export_16bit = bool(export_16bit) and (not bool(getattr(son, 'son8bit', True)))
|
|
370
374
|
son.export_colormap_uint8 = bool(export_colormap_uint8)
|
|
375
|
+
son.sonar_db_transform = bool(sonar_db_transform)
|
|
376
|
+
son.sonar_clahe = bool(sonar_clahe)
|
|
377
|
+
son.sonar_clahe_global = bool(sonar_clahe_global)
|
|
378
|
+
son.sonar_clahe_clip_limit = float(sonar_clahe_clip_limit)
|
|
379
|
+
if son.sonar_clahe:
|
|
380
|
+
son._ensure_clahe_global_bounds()
|
|
371
381
|
|
|
372
382
|
# ############################################################################
|
|
373
383
|
# # Rectify Heading sonar imagery - Pingwise, not Rubbersheeting #
|
|
@@ -462,6 +472,12 @@ def rectify_master_func(logfilename='',
|
|
|
462
472
|
for son in portstar:
|
|
463
473
|
son.rect_wcp = rect_wcp
|
|
464
474
|
son.rect_wcr = rect_wcr
|
|
475
|
+
son.sonar_db_transform = bool(sonar_db_transform)
|
|
476
|
+
son.sonar_clahe = bool(sonar_clahe)
|
|
477
|
+
son.sonar_clahe_global = bool(sonar_clahe_global)
|
|
478
|
+
son.sonar_clahe_clip_limit = float(sonar_clahe_clip_limit)
|
|
479
|
+
if son.sonar_clahe:
|
|
480
|
+
son._ensure_clahe_global_bounds()
|
|
465
481
|
|
|
466
482
|
if (rect_wcp and rubberSheeting) or (rect_wcr and rubberSheeting):
|
|
467
483
|
# Always use COG for rubber sheeting
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '5.5.3'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pingmapper
|
|
3
|
-
Version: 5.5.
|
|
3
|
+
Version: 5.5.3
|
|
4
4
|
Summary: Open-source interface for processing recreation-grade side scan sonar datasets and reproducibly mapping benthic habitat
|
|
5
5
|
Author: Cameron Bodine, Daniel Buscombe, Iury T Simoes-Sousa
|
|
6
6
|
Author-email: bodine.cs@gmail.email
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '5.5.1'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/DRAFT_Workflows/avg_predictions_Mussel_WBL.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/DRAFT_Workflows/testEXAMPLE_mosaic_logit.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pingmapper-5.5.1 → pingmapper-5.5.3}/pingmapper/utils/Substrate_Summaries/03_gen_summary_shp.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|