hsi-preprocessing-toolkit 2.1.1.dev5__tar.gz → 2.2.1__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 (16) hide show
  1. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/PKG-INFO +3 -2
  2. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/README.md +1 -1
  3. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/pyproject.toml +2 -1
  4. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/algorithm.py +54 -10
  5. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/common.py +3 -0
  6. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/page/hsi_preprocessing.py +11 -6
  7. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/__init__.py +0 -0
  8. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/__main__.py +0 -0
  9. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/asset/icon.ico +0 -0
  10. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/asset/page/about.en.md +0 -0
  11. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/asset/page/about.zh.md +0 -0
  12. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/asset/page/calc_formula.png +0 -0
  13. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/component/create_logger.py +0 -0
  14. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/page/about.py +0 -0
  15. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/page/scanner_calc.py +0 -0
  16. {hsi_preprocessing_toolkit-2.1.1.dev5 → hsi_preprocessing_toolkit-2.2.1}/src/hsi_preprocessing_toolkit/util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hsi-preprocessing-toolkit
3
- Version: 2.1.1.dev5
3
+ Version: 2.2.1
4
4
  Summary: HSI Preprocessing Toolkit
5
5
  Author: songyz2023
6
6
  Author-email: songyz2023 <songyz2023dlut@outlook.com>
@@ -11,6 +11,7 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
11
11
  Requires-Dist: einops>=0.8.0
12
12
  Requires-Dist: gradio>=5.50.0,<6.0.0
13
13
  Requires-Dist: matplotlib>=3.10.0
14
+ Requires-Dist: opencv-python>=4.13.0.90
14
15
  Requires-Dist: rasterio>=1.4.0
15
16
  Requires-Dist: rs-fusion-datasets>=0.16.0
16
17
  Requires-Dist: scipy>=1.16.0
@@ -33,7 +34,7 @@ Description-Content-Type: text/markdown
33
34
  ![](asset/screenshot.jpg)
34
35
 
35
36
  HSI Preprocessing Toolkit (HPT, formerly HDR2MAT) is a hyperspectral image preprocessing toolset that:
36
- 1. Read the raw data from the HSI camera, and convert it into `.mat` file
37
+ 1. Read the raw data directly from HSI cameras, and convert it into `.mat` file
37
38
  2. Read the `.mat` file
38
39
  3. Preview HSI and convert it to RGB `.png` file
39
40
  4. Crop, rotate, transform the HSI and preview in realtime
@@ -10,7 +10,7 @@
10
10
  ![](asset/screenshot.jpg)
11
11
 
12
12
  HSI Preprocessing Toolkit (HPT, formerly HDR2MAT) is a hyperspectral image preprocessing toolset that:
13
- 1. Read the raw data from the HSI camera, and convert it into `.mat` file
13
+ 1. Read the raw data directly from HSI cameras, and convert it into `.mat` file
14
14
  2. Read the `.mat` file
15
15
  3. Preview HSI and convert it to RGB `.png` file
16
16
  4. Crop, rotate, transform the HSI and preview in realtime
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "hsi-preprocessing-toolkit"
3
- version = "2.1.1.dev5" # This will be changed by dunami according to git tag when releasing.
3
+ version = "2.2.1" # This will be changed by dunami according to git tag when releasing.
4
4
  description = "HSI Preprocessing Toolkit"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -8,6 +8,7 @@ dependencies = [
8
8
  "einops>=0.8.0",
9
9
  "gradio>=5.50.0,<6.0.0",
10
10
  "matplotlib>=3.10.0",
11
+ "opencv-python>=4.13.0.90",
11
12
  "rasterio>=1.4.0",
12
13
  "rs-fusion-datasets>=0.16.0",
13
14
  "scipy>=1.16.0",
@@ -6,6 +6,7 @@ import matplotlib
6
6
  import matplotlib.pyplot as plt
7
7
  import matplotlib.transforms as mtransforms
8
8
  import einops
9
+ import cv2
9
10
 
10
11
  # Return A HWC Image, the C should work with both RGB and HSI
11
12
  def composite_img(imgs :list[np.ndarray], transforms:list[dict]):
@@ -52,21 +53,67 @@ def _min_max_normalize(x :np.ndarray):
52
53
  def compose_spectral_profile(x: np.ndarray) -> np.ndarray:
53
54
  '''
54
55
  x: a [H C] or [W C] array, any dtype
55
- return: HW4 RGBA Uint8 Image (0~225), x (as row direction) is height or width, y (as col direction) is spectral
56
+ return: HC4 RGB Uint8 Image (0~225), x (as row direction) is height or width, y (as col direction) is spectral
56
57
  '''
57
- x = x.transpose(1,0) # convert to [C X]
58
58
  x = _min_max_normalize(x)
59
59
  mapper = matplotlib.colormaps.get_cmap('viridis')
60
- rgb = mapper(x)
60
+ rgb = mapper(x)[:,:,:3]
61
61
  rgb = (rgb*255).astype('uint8')
62
62
  return rgb
63
63
 
64
+ def generate_oblique_cube(front, top, right):
65
+ """
66
+ 符号说明:
67
+ w, h, d : 原长方体的宽、高、深
68
+ W, H : 合成画布(Canvas)的宽、高
69
+ a : 投影偏移量 (d * 0.5 * sin(45°))
70
+ """
71
+ # top: w d 3
72
+ # right: h d 3
73
+ # front: h w 3
74
+ top = top[:,::-1,:] # dirty fix
75
+ h, w = front.shape[:2]
76
+ d = top.shape[1]
77
+ assert d==right.shape[1]
78
+ assert h==right.shape[0]
79
+ assert w== top.shape[0]
64
80
 
81
+ a = int(d * 0.5 * 0.7071)
82
+ W, H = w + a, h + a
83
+ canvas = np.zeros((H, W, 3), dtype=np.uint8)
65
84
 
85
+ # 加减1是为了防止出现缝隙,这也算是一种off by one了...
86
+ canvas_r = cv2.warpAffine(right,
87
+ cv2.getAffineTransform(
88
+ np.array([[0, 0], [0, h], [d, 0]], dtype=np.float32),
89
+ np.array([[w, a], [w, H], [W, 0]], dtype=np.float32)),
90
+ (W, H), flags=cv2.INTER_LANCZOS4)
91
+ canvas_t = cv2.warpAffine(top,
92
+ cv2.getAffineTransform(
93
+ np.array([[0, 0], [0, w], [d, 0]], dtype=np.float32),
94
+ np.array([[a, 0], [W, 0], [0, a]], dtype=np.float32)),
95
+ (W, H), flags=cv2.INTER_LANCZOS4)
96
+ canvas[a:H, 0:w] = front
66
97
 
67
- def compose_bread_edge(hsi: np.ndarray) -> (np.ndarray, np.ndarray): # input HWC, output HWC
68
- top = _min_max_normalize(hsi[:,0,:]) # H C
69
- right = _min_max_normalize(hsi[0,:,:]) # W C
98
+ m_r = np.any(canvas_r > 0, axis=-1)
99
+ m_t = np.any(canvas_t > 0, axis=-1)
100
+ canvas[m_r] = canvas_r[m_r]
101
+ canvas[m_t] = canvas_t[m_t]
102
+ return canvas
103
+
104
+ def compose_hsi_cube(hsi: np.ndarray, front: np.ndarray) -> (np.ndarray, np.ndarray, np.ndarray):
105
+ '''
106
+ input HWC,HW3(u8)
107
+ output HWC,HWC,HWC
108
+ '''
109
+ top = _min_max_normalize(hsi[0,:,:]) # W C, 有宽度W和深度,是侧面
110
+ right = _min_max_normalize(hsi[:,0,:]) # H C
111
+ top = compose_spectral_profile(top) # W C 3
112
+ right = compose_spectral_profile(right) # H C 3
113
+
114
+ cube = generate_oblique_cube(front, top, right)
115
+
116
+ return cube, einops.rearrange(top, 'H C c -> C H c'), einops.rearrange(right, 'H C c -> C H c')
70
117
 
71
118
  # top_fig = plt.figure()
72
119
  # top_im = plt.imshow(top, cmap='viridis')
@@ -80,7 +127,4 @@ def compose_bread_edge(hsi: np.ndarray) -> (np.ndarray, np.ndarray): # input HWC
80
127
  # right_fig = plt.figure()
81
128
  # plt.imshow(right, cmap='viridis')
82
129
  # plt.axis('off')
83
- # plt.margins(0, 0)
84
-
85
- return compose_spectral_profile(top), compose_spectral_profile(right)
86
-
130
+ # plt.margins(0, 0)
@@ -80,6 +80,8 @@ TRANSLATION = {
80
80
  "hsi_processing.spectral_profiles.generate": "Generate Spectral Profiles",
81
81
  "hsi_processing.spectral_profiles.x_lambda_plane": "x-λ",
82
82
  "hsi_processing.spectral_profiles.y_lambda_plane": "y-λ",
83
+ "hsi_processing.spectral_profiles.hsi_cube": "HSI Cube",
84
+
83
85
 
84
86
  "scanner_calc.tab_title": "Scanner Parameters",
85
87
  },
@@ -136,6 +138,7 @@ TRANSLATION = {
136
138
  "hsi_processing.spectral_profiles.generate": "生成光谱剖面",
137
139
  "hsi_processing.spectral_profiles.x_lambda_plane": "x-λ剖面",
138
140
  "hsi_processing.spectral_profiles.y_lambda_plane": "y-λ剖面",
141
+ "hsi_processing.spectral_profiles.hsi_cube": "光谱立方体",
139
142
 
140
143
  "scanner_calc.tab_title": "推扫仪计算",
141
144
  }
@@ -12,7 +12,7 @@ import gradio.utils
12
12
  from rs_fusion_datasets.util.hsi2rgb import _hsi2rgb, hsi2rgb
13
13
  from jaxtyping import Float
14
14
  from enum import Enum
15
- from ..algorithm import composite_img, compose_bread_edge
15
+ from ..algorithm import composite_img, compose_hsi_cube
16
16
  from ..common import i18n, LOGGER, TRANSLATION, DEBUG
17
17
  import logging
18
18
 
@@ -511,6 +511,10 @@ def HSIProcessingTab():
511
511
  )
512
512
 
513
513
  with gr.Accordion(i18n('hsi_processing.spectral_profiles'),visible=False) as spectral_profile_panel:
514
+ hsi_cube_image = gr.Image(
515
+ label=i18n('hsi_processing.spectral_profiles.hsi_cube'),
516
+ format="png", height="auto", width="auto", interactive=False
517
+ )
514
518
  x_lambda_image = gr.Image(
515
519
  label=i18n('hsi_processing.spectral_profiles.x_lambda_plane'),
516
520
  format="png", height="auto", width="auto", interactive=False
@@ -522,11 +526,7 @@ def HSIProcessingTab():
522
526
  generate_spectral_profiles = gr.Button(
523
527
  i18n('hsi_processing.spectral_profiles.generate')
524
528
  )
525
- generate_spectral_profiles.click(
526
- fn=compose_bread_edge,
527
- inputs=[state_processed_data],
528
- outputs=[y_lambda_plane, x_lambda_image]
529
- )
529
+
530
530
 
531
531
 
532
532
  with gr.Column(scale=2):
@@ -540,6 +540,11 @@ def HSIProcessingTab():
540
540
  )
541
541
 
542
542
  # 回调函数
543
+ generate_spectral_profiles.click(
544
+ fn=compose_hsi_cube,
545
+ inputs=[state_processed_data, preview_img],
546
+ outputs=[hsi_cube_image, y_lambda_plane, x_lambda_image]
547
+ )
543
548
  reload_btn.click(
544
549
  fn=gr_load,
545
550
  inputs=[state_current_layer_index, state_transforms, state_original_rgb, state_original_data, state_data_path, dat_files, input_format, input_mat_key, manual_normalize, normalize_min, normalize_max, wavelength_from, wavelength_to],