hsi-preprocessing-toolkit 2.0.0a2__tar.gz → 2.1.1.dev5__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 (20) hide show
  1. {hsi_preprocessing_toolkit-2.0.0a2 → hsi_preprocessing_toolkit-2.1.1.dev5}/PKG-INFO +34 -29
  2. {hsi_preprocessing_toolkit-2.0.0a2 → hsi_preprocessing_toolkit-2.1.1.dev5}/README.md +27 -22
  3. {hsi_preprocessing_toolkit-2.0.0a2 → hsi_preprocessing_toolkit-2.1.1.dev5}/pyproject.toml +9 -9
  4. hsi_preprocessing_toolkit-2.1.1.dev5/src/hsi_preprocessing_toolkit/__main__.py +55 -0
  5. hsi_preprocessing_toolkit-2.1.1.dev5/src/hsi_preprocessing_toolkit/algorithm.py +86 -0
  6. hsi_preprocessing_toolkit-2.1.1.dev5/src/hsi_preprocessing_toolkit/asset/page/about.en.md +31 -0
  7. hsi_preprocessing_toolkit-2.1.1.dev5/src/hsi_preprocessing_toolkit/asset/page/about.zh.md +33 -0
  8. hsi_preprocessing_toolkit-2.1.1.dev5/src/hsi_preprocessing_toolkit/asset/page/calc_formula.png +0 -0
  9. hsi_preprocessing_toolkit-2.1.1.dev5/src/hsi_preprocessing_toolkit/common.py +159 -0
  10. hsi_preprocessing_toolkit-2.1.1.dev5/src/hsi_preprocessing_toolkit/component/create_logger.py +39 -0
  11. hsi_preprocessing_toolkit-2.1.1.dev5/src/hsi_preprocessing_toolkit/page/about.py +24 -0
  12. hsi_preprocessing_toolkit-2.1.1.dev5/src/hsi_preprocessing_toolkit/page/hsi_preprocessing.py +646 -0
  13. hsi_preprocessing_toolkit-2.1.1.dev5/src/hsi_preprocessing_toolkit/page/scanner_calc.py +56 -0
  14. hsi_preprocessing_toolkit-2.1.1.dev5/src/hsi_preprocessing_toolkit/util.py +31 -0
  15. hsi_preprocessing_toolkit-2.0.0a2/src/hsi_preprocessing_toolkit/__main__.py +0 -615
  16. hsi_preprocessing_toolkit-2.0.0a2/src/hsi_preprocessing_toolkit/algorithm.py +0 -44
  17. hsi_preprocessing_toolkit-2.0.0a2/src/hsi_preprocessing_toolkit/i18n.py +0 -78
  18. hsi_preprocessing_toolkit-2.0.0a2/src/hsi_preprocessing_toolkit/page/scanner_calc.py +0 -54
  19. {hsi_preprocessing_toolkit-2.0.0a2 → hsi_preprocessing_toolkit-2.1.1.dev5}/src/hsi_preprocessing_toolkit/__init__.py +0 -0
  20. {hsi_preprocessing_toolkit-2.0.0a2 → hsi_preprocessing_toolkit-2.1.1.dev5}/src/hsi_preprocessing_toolkit/asset/icon.ico +0 -0
@@ -1,20 +1,20 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hsi-preprocessing-toolkit
3
- Version: 2.0.0a2
3
+ Version: 2.1.1.dev5
4
4
  Summary: HSI Preprocessing Toolkit
5
5
  Author: songyz2023
6
6
  Author-email: songyz2023 <songyz2023dlut@outlook.com>
7
7
  License-Expression: AGPL-3.0-only
8
8
  Classifier: Programming Language :: Python
9
- Classifier: Programming Language :: Python :: 3.12
10
9
  Classifier: Programming Language :: Python :: 3.13
11
10
  Classifier: Programming Language :: Python :: Implementation :: CPython
12
- Requires-Dist: einops>=0.8.1
13
- Requires-Dist: gradio>=5.35.0
14
- Requires-Dist: matplotlib>=3.10.3
15
- Requires-Dist: rasterio>=1.4.3
11
+ Requires-Dist: einops>=0.8.0
12
+ Requires-Dist: gradio>=5.50.0,<6.0.0
13
+ Requires-Dist: matplotlib>=3.10.0
14
+ Requires-Dist: rasterio>=1.4.0
16
15
  Requires-Dist: rs-fusion-datasets>=0.16.0
17
- Requires-Dist: scipy>=1.15.3
16
+ Requires-Dist: scipy>=1.16.0
17
+ Requires-Dist: webui2>=2.5.6
18
18
  Requires-Python: >=3.13
19
19
  Project-URL: Documentation, https://github.com/songyz2019/hsi-preprocessing-toolkit#readme
20
20
  Project-URL: Issues, https://github.com/songyz2019/hsi-preprocessing-toolkit/issues
@@ -23,8 +23,6 @@ Description-Content-Type: text/markdown
23
23
 
24
24
  # HSI Preprocessing Toolkit
25
25
 
26
- ![](asset/screenshot.jpg)
27
-
28
26
 
29
27
  [![PyPI - Version](https://img.shields.io/pypi/v/hsi-preprocessing-toolkit.svg)](https://pypi.org/project/hsi-preprocessing-toolkit)
30
28
  [![PyPI - Downloads](https://img.shields.io/pypi/dm/hsi-preprocessing-toolkit)](https://pypi.org/project/hsi-preprocessing-toolkit)
@@ -32,36 +30,43 @@ Description-Content-Type: text/markdown
32
30
  ![GitHub Created At](https://img.shields.io/github/created-at/songyz2019/hsi-preprocessing-toolkit)
33
31
  ![GitHub License](https://img.shields.io/github/license/songyz2019/hsi-preprocessing-toolkit)
34
32
 
33
+ ![](asset/screenshot.jpg)
35
34
 
36
- A Hyperspectral Preprocessing Toolkit that
35
+ HSI Preprocessing Toolkit (HPT, formerly HDR2MAT) is a hyperspectral image preprocessing toolset that:
37
36
  1. Read the raw data from the HSI camera, and convert it into `.mat` file
38
37
  2. Read the `.mat` file
39
- 3. Preview HSI, and convert it to RGB `.png` file
40
- 4. Crop and rotate the HSI and preview in realtime
38
+ 3. Preview HSI and convert it to RGB `.png` file
39
+ 4. Crop, rotate, transform the HSI and preview in realtime
41
40
  5. Select spectrals of interest visually and save them into a `.mat` file
42
- 6. Mix multiple HSI image with layers. (coming in v2.0.0, now availabe in git)
41
+ 6. Mix multiple HSI images with layers.
42
+ 7. Generate Spectral Profiles for visualization.
43
+ 8. Some other utils
43
44
 
44
45
 
45
46
  ## Usage
47
+ ### Prerequisites
48
+ 1. A Chromium-based browser
49
+ 2. A modern OS
50
+
46
51
  ### Manual
47
- 1. Download from GitHub release
48
- 2. Double click the `start.cmd` file. Make sure you have internet access during the first start.
52
+ 1. Download [hpt.cmd](https://github.com/songyz2019/hsi-preprocessing-toolkit/blob/main/script/hpt.cmd) from GitHub release
53
+ 2. Double click the `hpt.cmd` file.
49
54
 
50
- ### Install with pip
51
- ```sh
52
- pip install hsi-preprocessing-toolkit
53
- hsi_preprocessing_toolkit
54
- ```
55
+ > **TIPS**: Make sure you have internet access during the first start
55
56
 
56
57
  ### Install with uv
57
- ```sh
58
- uvx hsi_preprocessing_toolkit
59
- ```
60
- or install as a tool
61
- ```sh
62
- uv tool install hsi-preprocessing-toolkit
63
- hsi_preprocessing_toolkit
64
- ```
58
+ 1. Install [uv](https://docs.astral.sh/uv/) directly or with pip: `pip install uv`
59
+ 2. Install HPT: `uv tool install hsi-preprocessing-toolkit`
60
+ 3. Start HPT: `hsi_preprocessing_toolkit`
61
+
62
+ ### Install with pip
63
+ 1. Install HPT: `pip install hsi-preprocessing-toolkit`
64
+ 2. Start HPT: `hsi_preprocessing_toolkit`
65
+
66
+ > **TIPS**: It's not recommend to install CLI tools directly with pip, please use [uv tool](https://docs.astral.sh/uv/guides/tools/) or [pipx](https://pipx.pypa.io/) to install python applications in isolated environments.
67
+
68
+
69
+ ## Document
65
70
 
66
71
 
67
72
  ## Credit
@@ -89,4 +94,4 @@ GNU Affero General Public License for more details.
89
94
 
90
95
  You should have received a copy of the GNU Affero General Public License
91
96
  along with this program. If not, see <https://www.gnu.org/licenses/>.
92
- ```
97
+ ```
@@ -1,7 +1,5 @@
1
1
  # HSI Preprocessing Toolkit
2
2
 
3
- ![](asset/screenshot.jpg)
4
-
5
3
 
6
4
  [![PyPI - Version](https://img.shields.io/pypi/v/hsi-preprocessing-toolkit.svg)](https://pypi.org/project/hsi-preprocessing-toolkit)
7
5
  [![PyPI - Downloads](https://img.shields.io/pypi/dm/hsi-preprocessing-toolkit)](https://pypi.org/project/hsi-preprocessing-toolkit)
@@ -9,36 +7,43 @@
9
7
  ![GitHub Created At](https://img.shields.io/github/created-at/songyz2019/hsi-preprocessing-toolkit)
10
8
  ![GitHub License](https://img.shields.io/github/license/songyz2019/hsi-preprocessing-toolkit)
11
9
 
10
+ ![](asset/screenshot.jpg)
12
11
 
13
- A Hyperspectral Preprocessing Toolkit that
12
+ HSI Preprocessing Toolkit (HPT, formerly HDR2MAT) is a hyperspectral image preprocessing toolset that:
14
13
  1. Read the raw data from the HSI camera, and convert it into `.mat` file
15
14
  2. Read the `.mat` file
16
- 3. Preview HSI, and convert it to RGB `.png` file
17
- 4. Crop and rotate the HSI and preview in realtime
15
+ 3. Preview HSI and convert it to RGB `.png` file
16
+ 4. Crop, rotate, transform the HSI and preview in realtime
18
17
  5. Select spectrals of interest visually and save them into a `.mat` file
19
- 6. Mix multiple HSI image with layers. (coming in v2.0.0, now availabe in git)
18
+ 6. Mix multiple HSI images with layers.
19
+ 7. Generate Spectral Profiles for visualization.
20
+ 8. Some other utils
20
21
 
21
22
 
22
23
  ## Usage
24
+ ### Prerequisites
25
+ 1. A Chromium-based browser
26
+ 2. A modern OS
27
+
23
28
  ### Manual
24
- 1. Download from GitHub release
25
- 2. Double click the `start.cmd` file. Make sure you have internet access during the first start.
29
+ 1. Download [hpt.cmd](https://github.com/songyz2019/hsi-preprocessing-toolkit/blob/main/script/hpt.cmd) from GitHub release
30
+ 2. Double click the `hpt.cmd` file.
26
31
 
27
- ### Install with pip
28
- ```sh
29
- pip install hsi-preprocessing-toolkit
30
- hsi_preprocessing_toolkit
31
- ```
32
+ > **TIPS**: Make sure you have internet access during the first start
32
33
 
33
34
  ### Install with uv
34
- ```sh
35
- uvx hsi_preprocessing_toolkit
36
- ```
37
- or install as a tool
38
- ```sh
39
- uv tool install hsi-preprocessing-toolkit
40
- hsi_preprocessing_toolkit
41
- ```
35
+ 1. Install [uv](https://docs.astral.sh/uv/) directly or with pip: `pip install uv`
36
+ 2. Install HPT: `uv tool install hsi-preprocessing-toolkit`
37
+ 3. Start HPT: `hsi_preprocessing_toolkit`
38
+
39
+ ### Install with pip
40
+ 1. Install HPT: `pip install hsi-preprocessing-toolkit`
41
+ 2. Start HPT: `hsi_preprocessing_toolkit`
42
+
43
+ > **TIPS**: It's not recommend to install CLI tools directly with pip, please use [uv tool](https://docs.astral.sh/uv/guides/tools/) or [pipx](https://pipx.pypa.io/) to install python applications in isolated environments.
44
+
45
+
46
+ ## Document
42
47
 
43
48
 
44
49
  ## Credit
@@ -66,4 +71,4 @@ GNU Affero General Public License for more details.
66
71
 
67
72
  You should have received a copy of the GNU Affero General Public License
68
73
  along with this program. If not, see <https://www.gnu.org/licenses/>.
69
- ```
74
+ ```
@@ -1,23 +1,23 @@
1
1
  [project]
2
2
  name = "hsi-preprocessing-toolkit"
3
- version = "2.0.0a2"
3
+ version = "2.1.1.dev5" # 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"
7
7
  dependencies = [
8
- "einops>=0.8.1",
9
- "gradio>=5.35.0",
10
- "matplotlib>=3.10.3",
11
- "rasterio>=1.4.3",
8
+ "einops>=0.8.0",
9
+ "gradio>=5.50.0,<6.0.0",
10
+ "matplotlib>=3.10.0",
11
+ "rasterio>=1.4.0",
12
12
  "rs-fusion-datasets>=0.16.0",
13
- "scipy>=1.15.3",
13
+ "scipy>=1.16.0",
14
+ "webui2>=2.5.6",
14
15
  ]
15
16
  authors = [
16
17
  { name = "songyz2023", email = "songyz2023dlut@outlook.com" },
17
18
  ]
18
19
  classifiers = [
19
20
  "Programming Language :: Python",
20
- "Programming Language :: Python :: 3.12",
21
21
  "Programming Language :: Python :: 3.13",
22
22
  "Programming Language :: Python :: Implementation :: CPython",
23
23
  ]
@@ -33,7 +33,7 @@ url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
33
33
  default = true
34
34
 
35
35
  [build-system]
36
- requires = ["uv_build >= 0.8.0, <0.10.0"]
36
+ requires = ["uv_build >= 0.9.0, <0.10.0"]
37
37
  build-backend = "uv_build"
38
38
 
39
39
  [tool.hatch.build.targets.wheel]
@@ -41,4 +41,4 @@ packages = ["hsi-preprocessing-toolkit/__main__.py"]
41
41
 
42
42
 
43
43
  [project.scripts]
44
- hsi_preprocessing_toolkit = "hsi_preprocessing_toolkit.__main__:main"
44
+ hsi_preprocessing_toolkit = "hsi_preprocessing_toolkit.__main__:main"
@@ -0,0 +1,55 @@
1
+ import matplotlib.pyplot as plt
2
+ import gradio as gr
3
+ import os
4
+
5
+ from .page.scanner_calc import ScannerCalcTab
6
+ from .page.about import AboutTab
7
+ from .page.hsi_preprocessing import HSIProcessingTab
8
+ from .component.create_logger import create_gr_logger
9
+ from .common import i18n, DEBUG, MULTI_USER, LOGGER_MEMORY_HANDLER, APP_NAME, LOGGER
10
+
11
+
12
+
13
+ def main():
14
+ # Global State
15
+ plt.rcParams['font.family'] = 'SimHei'
16
+ theme = gr.themes.Default(primary_hue='cyan').set(
17
+ button_primary_background_fill='#39c5bb',
18
+ button_primary_background_fill_hover="#30A8A0",
19
+ )
20
+
21
+ with gr.Blocks(title=APP_NAME, theme=theme) as demo: # title=i18n("about.title")
22
+ HSIProcessingTab()
23
+ ScannerCalcTab()
24
+ AboutTab()
25
+ if not MULTI_USER:
26
+ create_gr_logger(LOGGER_MEMORY_HANDLER)
27
+
28
+ demo.launch(
29
+ debug=DEBUG,
30
+ prevent_thread_lock=True, # 不阻塞主线程,配合webui/webbrowser
31
+ share=False,
32
+ inbrowser=False,
33
+ i18n=i18n,
34
+ favicon_path="asset/icon.ico"
35
+ )
36
+ try:
37
+ from webui import webui
38
+ window = webui.Window()
39
+ window.show_browser(demo.local_url, webui.browser.ChromiumBased) # 这里的行为有些奇怪,启动成功了但依然会返回false
40
+ LOGGER.info('Launched in webui mode successfully')
41
+ window.set_minimum_size(1024, 768)
42
+ webui.wait() # wait似乎有bug
43
+ input("Running ...") # wait bug的quick dirty fix
44
+ # window.destroy()
45
+ # demo.close()
46
+ # os._exit(0)
47
+ except Exception as err:
48
+ window.destroy()
49
+ LOGGER.warning(f'Fallback to browser mode, {err}')
50
+ import webbrowser
51
+ webbrowser.open_new(demo.local_url)
52
+ input("Running ...") # quick dirty fix
53
+
54
+ if __name__ == "__main__":
55
+ main()
@@ -0,0 +1,86 @@
1
+ from scipy.ndimage import rotate
2
+ import numpy as np
3
+ from copy import deepcopy
4
+ from .common import LOGGER
5
+ import matplotlib
6
+ import matplotlib.pyplot as plt
7
+ import matplotlib.transforms as mtransforms
8
+ import einops
9
+
10
+ # Return A HWC Image, the C should work with both RGB and HSI
11
+ def composite_img(imgs :list[np.ndarray], transforms:list[dict]):
12
+ imgs = deepcopy(imgs)
13
+ # Transform
14
+ LOGGER.info(f"{transforms=}")
15
+ for i, (img,trans) in enumerate(zip(imgs, transforms)):
16
+ rotate_deg = trans['rotation']
17
+ if rotate_deg % 360 != 0:
18
+ img = rotate(img, angle=rotate_deg, axes=(0, 1), reshape=True)
19
+
20
+ # Crop
21
+ crop_top, crop_left, crop_bottom, crop_right = trans['crop']
22
+ if crop_top > 0 or crop_left > 0 or crop_bottom > 0 or crop_right > 0:
23
+ crop_bottom = None if crop_bottom == 0 else -crop_bottom
24
+ crop_right = None if crop_right == 0 else -crop_right
25
+ img = img[crop_top:crop_bottom, crop_left:crop_right, :]
26
+
27
+ imgs[i] = img
28
+
29
+ # Caclate canvas size
30
+ shapes = [x.shape for x in imgs]
31
+ offsets = [ x['location'] for x in transforms ]
32
+ canvas_c = imgs[0].shape[-1]
33
+ sizes = [ ((h+abs(x)),w+abs(y)) for (h,w,_),(x,y) in zip(shapes, offsets)]
34
+ canvas_h, canvas_w = ( max([x[0] for x in sizes]), max([x[1] for x in sizes]) )
35
+ canvas_shape = (canvas_h, canvas_w, canvas_c)
36
+ LOGGER.info(f"{sizes=} {canvas_shape=} {shapes=}")
37
+ canvas = np.zeros(shape=canvas_shape, dtype=imgs[0].dtype)
38
+
39
+ # 合成 Compositing
40
+ for img,trans in zip(imgs, transforms):
41
+ x,y = trans['location']
42
+ h,w,_ = img.shape
43
+ canvas[x:x+h, y:y+w] = img
44
+ return canvas
45
+
46
+ def _min_max_normalize(x :np.ndarray):
47
+ r = x.max()-x.min()
48
+ if r<=np.finfo(x.dtype).eps:
49
+ return np.zeros_like(x, dtype=x.dtype)
50
+ return (x-x.min())/r
51
+
52
+ def compose_spectral_profile(x: np.ndarray) -> np.ndarray:
53
+ '''
54
+ 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
+ '''
57
+ x = x.transpose(1,0) # convert to [C X]
58
+ x = _min_max_normalize(x)
59
+ mapper = matplotlib.colormaps.get_cmap('viridis')
60
+ rgb = mapper(x)
61
+ rgb = (rgb*255).astype('uint8')
62
+ return rgb
63
+
64
+
65
+
66
+
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
70
+
71
+ # top_fig = plt.figure()
72
+ # top_im = plt.imshow(top, cmap='viridis')
73
+ # plt.axis('off')
74
+ # plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0)
75
+ # # top_tr = mtransforms.Affine2D()
76
+ # # top_tr.rotate_deg(45).scale(1, 0.5)
77
+ # # top_im.set_transform(top_tr)
78
+ # # top_im.set_clip_on(False)
79
+
80
+ # right_fig = plt.figure()
81
+ # plt.imshow(right, cmap='viridis')
82
+ # plt.axis('off')
83
+ # plt.margins(0, 0)
84
+
85
+ return compose_spectral_profile(top), compose_spectral_profile(right)
86
+
@@ -0,0 +1,31 @@
1
+ # Hyperspectral Preprocessing Toolkit
2
+
3
+ A Hyperspectral Image Preprocessing Toolkit from HSI Camera to Machine Learning Dataset.
4
+
5
+ ## Help
6
+ - [Homepage](https://github.com/songyz2019/hsi-preprocessing-toolkit)
7
+ - [BUG Report](https://github.com/songyz2019/hsi-preprocessing-toolkit/issues)
8
+ - [Help](https://github.com/songyz2019/hsi-preprocessing-toolkit/wiki)
9
+
10
+ ## Check for update
11
+ ![](https://img.shields.io/badge/Current-v${VERSION}-blue?style=for-the-badge)
12
+ ![](https://img.shields.io/pypi/v/hsi-preprocessing-toolkit?label=Latest&style=for-the-badge)
13
+
14
+
15
+ # License
16
+ ```text
17
+ Copyright (C) 2025 songyz2019
18
+
19
+ This program is free software: you can redistribute it and/or modify
20
+ it under the terms of the GNU Affero General Public License as published by
21
+ the Free Software Foundation, either version 3 of the License, or
22
+ (at your option) any later version.
23
+
24
+ This program is distributed in the hope that it will be useful,
25
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ GNU Affero General Public License for more details.
28
+
29
+ You should have received a copy of the GNU Affero General Public License
30
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
31
+ ```
@@ -0,0 +1,33 @@
1
+ # Hyperspectral Preprocessing Toolkit
2
+
3
+ 高光谱数据处理工具箱
4
+
5
+ ## 帮助
6
+ - [主页](https://github.com/songyz2019/hsi-preprocessing-toolkit)
7
+ - [问题反馈](https://github.com/songyz2019/hsi-preprocessing-toolkit/issues)
8
+ - [帮助文档](https://github.com/songyz2019/hsi-preprocessing-toolkit/wiki)
9
+
10
+ ## 检查更新
11
+ ![](https://img.shields.io/badge/当前版本-v${VERSION}-blue?style=for-the-badge)
12
+ ![](https://img.shields.io/pypi/v/hsi-preprocessing-toolkit?label=%E6%9C%80%E6%96%B0%E7%89%88%E6%9C%AC&style=for-the-badge)
13
+
14
+
15
+ ## 许可
16
+ ```text
17
+ Copyright (C) 2025 songyz2019
18
+
19
+ This program is free software: you can redistribute it and/or modify
20
+ it under the terms of the GNU Affero General Public License as published by
21
+ the Free Software Foundation, either version 3 of the License, or
22
+ (at your option) any later version.
23
+
24
+ This program is distributed in the hope that it will be useful,
25
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ GNU Affero General Public License for more details.
28
+
29
+ You should have received a copy of the GNU Affero General Public License
30
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
31
+ ```
32
+
33
+
@@ -0,0 +1,159 @@
1
+ import gradio as gr
2
+ import logging
3
+ import logging.handlers
4
+ import os
5
+ import importlib.metadata
6
+ import platform
7
+
8
+ # 全局信息
9
+ APP_NAME='hsi-preprocessing-toolkit'
10
+ APP_VERSION = importlib.metadata.version(APP_NAME)
11
+
12
+ # 全局参数
13
+ DEBUG = os.environ.get('HPT_DEBUG','FALSE').upper() in ['1', 'TRUE', 'YES']
14
+ MULTI_USER = os.environ.get('HPT_MULTI_USER','FALSE').upper() in ['1', 'TRUE', 'YES']
15
+
16
+ # I18N
17
+ from importlib import resources
18
+ from string import Template
19
+ def _load_about_md(lang :str):
20
+ if lang.startswith('zh'):
21
+ lang = 'zh'
22
+ else:
23
+ lang = 'en'
24
+ text = resources.files("hsi_preprocessing_toolkit.asset.page").joinpath(f"about.{lang}.md").read_text(encoding="utf-8")
25
+ return Template(text).safe_substitute(
26
+ VERSION=APP_VERSION
27
+ )
28
+
29
+ TRANSLATION = {
30
+ 'en': {
31
+ "about.tab_title": "About",
32
+ "about.title": "HSI Preprocessing Toolkit",
33
+ "about.content": _load_about_md('en'),
34
+
35
+ "hsi_processing.tab_title": "HSI Processing",
36
+ "hsi_processing.load": "Load",
37
+ "hsi_processing.loading": "Loading, this could take minutes...",
38
+ "hsi_processing.loaded": "Loaded",
39
+ "hsi_processing.current_layer": "Selected Layer",
40
+ "hsi_processing.upload_instructions": "**Upload one of the following formats:**\n1. One .hdr file + one raw data file without extension\n2. One .mat file",
41
+ "hsi_processing.input_format": "Input Image Shape Format",
42
+ "hsi_processing.data_files": "Data Files",
43
+ "hsi_processing.manual_normalize": "Manual Normalize (affects preview only)",
44
+ "hsi_processing.normalize_min": "Normalize Min",
45
+ "hsi_processing.normalize_max": "Normalize Max",
46
+ "hsi_processing.wavelength_start": "Wavelength Range Start",
47
+ "hsi_processing.wavelength_end": "Wavelength Range End",
48
+ "hsi_processing.processing": "Processing",
49
+ "hsi_processing.crop": "Crop",
50
+ "hsi_processing.top": "Top",
51
+ "hsi_processing.bottom": "Bottom",
52
+ "hsi_processing.left": "Left",
53
+ "hsi_processing.right": "Right",
54
+ "hsi_processing.rotate": "Rotate",
55
+ "hsi_processing.rotate_degree": "Rotate Degree",
56
+ "hsi_processing.translate_offset": "Traslate",
57
+ "hsi_processing.translate_x": "X",
58
+ "hsi_processing.translate_y": "Y",
59
+ "hsi_processing.preview": "Preview",
60
+ "hsi_processing.apply_processing": "Apply Processing Effects",
61
+ "hsi_processing.mat_data_type": "MAT Data Type",
62
+ "hsi_processing.mat_format": "MAT Image Shape Format",
63
+ "hsi_processing.mat_key": "Key of MAT file",
64
+ "hsi_processing.compress_mat": "Produce Compressed MAT File",
65
+ "hsi_processing.spectral_selection": "Spectral Selection",
66
+ "hsi_processing.spectral_selection_help": "Click on the image to select pixels for spectral data extraction. The selected pixels will be plotted in the spectral plot below.",
67
+ "hsi_processing.spectral_plot": "Spectral Plot",
68
+ "hsi_processing.style": "Style",
69
+ "hsi_processing.clear": "Clear",
70
+ "hsi_processing.download": "Download",
71
+ "hsi_processing.output_results": "Output Results",
72
+ "hsi_processing.mat_file": "MAT File",
73
+ "hsi_processing.info": "Info",
74
+ "hsi_processing.same_as_input": "Same",
75
+ "hsi_processing.auto_detect": "Auto Detect",
76
+ "hsi_processing.applying_transforms": "Applying Transforms...",
77
+ "hsi_processing.applied_transforms": "Transforms Done",
78
+ "hsi_processing.no_converted_data_for_clicking": "No transforms applied data, apply transforms first",
79
+ "hsi_processing.spectral_profiles": "Spectral Profiles",
80
+ "hsi_processing.spectral_profiles.generate": "Generate Spectral Profiles",
81
+ "hsi_processing.spectral_profiles.x_lambda_plane": "x-λ",
82
+ "hsi_processing.spectral_profiles.y_lambda_plane": "y-λ",
83
+
84
+ "scanner_calc.tab_title": "Scanner Parameters",
85
+ },
86
+ 'zh-CN' : {
87
+ "about.tab_title": "关于",
88
+ "about.title": "HPT高光谱处理工具箱",
89
+ "about.content": _load_about_md('zh'),
90
+
91
+ "hsi_processing.tab_title": "高光谱图像处理",
92
+ "hsi_processing.current_layer": "选中图层",
93
+ "hsi_processing.load": "加载",
94
+ "hsi_processing.loading": "加载中,这可能需要几分钟...",
95
+ "hsi_processing.loaded": "加载完成",
96
+ "hsi_processing.upload_instructions": "**应上传以下两种格式中的一种**\n1. 同时上传一个.hdr文件 + 一个无后缀的数据文件\n2. 一个.mat文件",
97
+ "hsi_processing.input_format": "输入数据形状",
98
+ "hsi_processing.data_files": "数据文件",
99
+ "hsi_processing.manual_normalize": "手动归一化(仅影响预览结果)",
100
+ "hsi_processing.normalize_min": "归一化最小值",
101
+ "hsi_processing.normalize_max": "归一化最大值",
102
+ "hsi_processing.wavelength_start": "波长范围起始",
103
+ "hsi_processing.wavelength_end": "波长范围结束",
104
+ "hsi_processing.processing": "处理",
105
+ "hsi_processing.crop": "裁切",
106
+ "hsi_processing.top": "上",
107
+ "hsi_processing.bottom": "下",
108
+ "hsi_processing.left": "左",
109
+ "hsi_processing.right": "右",
110
+ "hsi_processing.rotate": "旋转",
111
+ "hsi_processing.rotate_degree": "旋转角度",
112
+ "hsi_processing.translate_offset": "平移",
113
+ "hsi_processing.translate_x": "X轴",
114
+ "hsi_processing.translate_y": "Y轴",
115
+ "hsi_processing.preview": "预览",
116
+ "hsi_processing.apply_processing": "应用处理效果",
117
+ "hsi_processing.mat_data_type": "mat文件数据类型",
118
+ "hsi_processing.mat_format": "mat文件格式",
119
+ "hsi_processing.mat_key": "mat文件的key",
120
+ "hsi_processing.compress_mat": "启用mat文件压缩",
121
+ "hsi_processing.spectral_selection": "光谱选择",
122
+ "hsi_processing.spectral_selection_help": "点击预览图像图像中的像素进行光谱数据提取。选中的像素将在下方的光谱图中绘制。",
123
+ "hsi_processing.spectral_plot": "光谱图",
124
+ "hsi_processing.style": "样式",
125
+ "hsi_processing.clear": "清空",
126
+ "hsi_processing.download": "下载",
127
+ "hsi_processing.output_results": "输出结果",
128
+ "hsi_processing.mat_file": "MAT文件",
129
+ "hsi_processing.info": "信息",
130
+ "hsi_processing.same_as_input": "与输入相同",
131
+ "hsi_processing.auto_detect": "自动检测",
132
+ "hsi_processing.applying_transforms": "应用变换中...",
133
+ "hsi_processing.applied_transforms": "变换完成",
134
+ "hsi_processing.no_converted_data_for_clicking": "没有应用变换后的数据,请先应用变换",
135
+ "hsi_processing.spectral_profiles": "光谱剖面",
136
+ "hsi_processing.spectral_profiles.generate": "生成光谱剖面",
137
+ "hsi_processing.spectral_profiles.x_lambda_plane": "x-λ剖面",
138
+ "hsi_processing.spectral_profiles.y_lambda_plane": "y-λ剖面",
139
+
140
+ "scanner_calc.tab_title": "推扫仪计算",
141
+ }
142
+ }
143
+ i18n = gr.I18n(**TRANSLATION)
144
+
145
+ # 日志
146
+ LOGGER = logging.getLogger(TRANSLATION['en']['about.title']) # 全局唯一LOGGER
147
+ LOGGER_MEMORY_HANDLER :logging.handlers.MemoryHandler|None = None
148
+ if not MULTI_USER:
149
+ LOGGER_MEMORY_HANDLER = logging.handlers.MemoryHandler(10_000, flushLevel=logging.WARNING) # 用于在UI中显示LOGGING信息
150
+ LOGGER.addHandler(LOGGER_MEMORY_HANDLER)
151
+
152
+ logging.basicConfig(
153
+ level=logging.DEBUG if DEBUG else logging.INFO,
154
+ format='[%(levelname)s %(asctime)s] %(name)s: %(message)s',
155
+ datefmt='%Y-%m-%d %H:%M:%S'
156
+ )
157
+
158
+ # 初始化完成
159
+ LOGGER.info(f"{APP_NAME} v{APP_VERSION} initalized. {DEBUG=} {MULTI_USER=} Gradio=v{gr.__version__} Python=v{platform.python_version()} OS={platform.platform()}")
@@ -0,0 +1,39 @@
1
+ from ..util import records_to_html
2
+ import gradio as gr
3
+ import logging
4
+ # from functools import partial
5
+
6
+ # def _one_timer_tick(handler, state_n_line):
7
+ # n_line = len(handler.buffer)
8
+ # print(f"{n_line=} {state_n_line=}")
9
+ # if n_line == state_n_line:
10
+ # print("SKIP")
11
+ # return gr.skip(), state_n_line
12
+ # else:
13
+ # return gr.update(value=records_to_html(handler.buffer, with_pre_tag=True)), n_line
14
+
15
+ # Gradio 5.50中存在一个BUG,timer.tick中的show_progress="hidden"和gr.skip依然会触发loading动画,通过一个state来workaround
16
+
17
+ def create_gr_logger(handler :logging.handlers.MemoryHandler):
18
+ state_n_line = gr.State(0)
19
+ timer = gr.Timer(value=2)
20
+ html = gr.HTML(
21
+ value="Loading.....",
22
+ label='Logging',
23
+ show_label=True,
24
+ container=True,
25
+ min_height=50,
26
+ max_height=100,
27
+ )
28
+ state_n_line.change(
29
+ fn=lambda: records_to_html(handler.buffer, with_pre_tag=True),
30
+ inputs=[],
31
+ outputs=[html],
32
+ show_progress="hidden"
33
+ )
34
+ timer.tick(
35
+ fn=lambda: len(handler.buffer),
36
+ inputs=[],
37
+ outputs=[state_n_line],
38
+ show_progress="hidden"
39
+ )
@@ -0,0 +1,24 @@
1
+ import gradio as gr
2
+ from ..common import i18n, APP_VERSION
3
+
4
+
5
+
6
+ def AboutTab():
7
+ with gr.Tab(i18n('about.tab_title')):
8
+ # lang_state = gr.State()
9
+
10
+ # gr.HTML(
11
+ # "<script defer>document.querySelector('#language_holder').innerHTML=navigator.language;</script>",
12
+ # elem_id="language_holder",
13
+ # ).change(
14
+ # lambda x:x,
15
+ # outputs=lang_state
16
+ # )
17
+ gr.Markdown(i18n('about.content'))
18
+
19
+ # lang_state.change(
20
+ # fn = load_about_md,
21
+ # inputs=[lang_state],
22
+ # outputs=[about_content]
23
+ # )
24
+