Skip to content

Commit 943ed52

Browse files
authored
Merge pull request #59 from gsun1729/master
Updated scripts and requirements for python3.12 upgrade
2 parents d5b636c + 18d4e98 commit 943ed52

311 files changed

Lines changed: 6266 additions & 3774 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,60 @@
11
/Recipes/__pycache__
2-
/Utilities/__pycache__
2+
/Utilities/__pycache__
3+
**/outputs/*.tif
4+
**/outputs/*.tiff
5+
**/outputs/*.aiviaexperiment
6+
7+
8+
# These are some examples of commonly ignored file patterns.
9+
# You should customize this list as applicable to your project.
10+
# Learn more about .gitignore:
11+
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore
12+
13+
# Node artifact files
14+
node_modules/
15+
dist/
16+
17+
# Compiled Java class files
18+
*.class
19+
20+
# Compiled Python bytecode
21+
*.py[cod]
22+
23+
# Log files
24+
*.log
25+
26+
# Package files
27+
*.jar
28+
29+
# Maven
30+
target/
31+
dist/
32+
33+
# JetBrains IDE
34+
.idea/
35+
36+
# Unit test reports
37+
TEST*.xml
38+
39+
# Generated by MacOS
40+
.DS_Store
41+
42+
# Generated by Windows
43+
Thumbs.db
44+
45+
# Applications
46+
*.app
47+
*.exe
48+
*.war
49+
50+
# Large media files
51+
*.mp4
52+
*.avi
53+
*.flv
54+
*.mov
55+
*.wmv
56+
*.csv
57+
*.db
58+
59+
# python files
60+
*.pyc
-44.6 KB
Binary file not shown.
-16.9 KB
Binary file not shown.

PythonEnvForAivia/FirstTimeSetup.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ def run(params):
2828
env_dir.mkdir(parents=False, exist_ok=True)
2929
subprocess.check_call([str(Path(sys.executable).parent / 'Scripts/virtualenv.exe'), f'{env_dir}'])
3030

31-
# copy essential python packages(python39.zip) to virtual environment
31+
# copy essential python packages(python312.zip) to virtual environment
3232
# see https://github.com/pypa/virtualenv/issues/1185
33-
if not os.path.exists(env_dir/'Scripts/python39.zip'):
34-
copyfile(Path(sys.executable).parent / 'python39.zip', env_dir/'Scripts/python39.zip')
33+
if not os.path.exists(env_dir/'Scripts/python312.zip'):
34+
copyfile(Path(sys.executable).parent / 'python312.zip', env_dir/'Scripts/python312.zip')
3535

3636
# install requirements
3737
mess = 'Python packages will now be installed. An internet connection is needed.\n\n' \
@@ -41,6 +41,8 @@ def run(params):
4141

4242
pip_path = env_dir / 'Scripts' / 'pip.exe'
4343
requirement_dir = pathlib.Path(os.path.dirname(os.path.realpath(__file__)))
44+
# subprocess.check_call(
45+
# [str(pip_path), 'install', 'setuptools==70.0.0'])
4446
subprocess.check_call(
4547
[str(pip_path), 'install', '-r', str(requirement_dir/'requirements.txt')])
4648

PythonEnvForAivia/README.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Python virtual Environment For Aivia
1+
# Python Virtual Environment for Aivia
22

33
## General Information
44

5-
The FirstTimeSetup.py script will ensure a virtual environment is created to run the python recipes for Aivia with the appropriate packages.
5+
The [`FirstTimeSetup.py`](/PythonEnvForAivia/FirstTimeSetup.py) script will ensure a virtual environment is created to run the python recipes for Aivia with the appropriate packages.
66
No further install should be needed. Hence, the script is run once only.
77

88
The recipes are then containing some code to:
@@ -13,8 +13,7 @@ The recipes are then containing some code to:
1313

1414
## Requirements
1515

16-
* Python 3.9 - comes with Aivia
17-
16+
* Python 3.12 - comes with Aivia
1817
* Accept the risks that come from running Python Scripts you download from the internet. These scripts are provided to you to use at your own risk.
1918

2019
## Installation
@@ -33,16 +32,16 @@ The tree structure of the folder is as follow
3332
└───Recipes
3433
└───[category subfolders]
3534
└───... .py
35+
3636
```
3737

3838
## Execution
3939

40-
1. Load `FirstTimeSetup.py` in Aivia by "File>Open" or drag-and-drop
41-
40+
1. Load [`FirstTimeSetup.py`](/PythonEnvForAivia/FirstTimeSetup.py) in Aivia by "File>Open" or drag-and-drop
4241
2. Load any 2D image in Aivia
43-
4442
3. Click on "Start" button and wait for "Process Completed" message at the bottom of the recipe console
4543
1. Please make sure that you have the Internet connection and wait if bandwidth is slow.
44+
2. At the end of this step, a new folder called `env` should be created in the `PythonEnvForAivia` folder. This will be the folder that contains a virtual environment identical to Aivia's embedded python that all future Recipes will run off of.
4645

4746

4847
## Returns

Recipes/CollectImageMetrics/CalculateIntersectionOverUnion.py renamed to PythonEnvForAivia/Recipes/CollectImageMetrics/CalculateIntersectionOverUnion.py

File renamed without changes.

Recipes/CollectImageMetrics/ImageComparisonMetrics.py renamed to PythonEnvForAivia/Recipes/CollectImageMetrics/ImageComparisonMetrics.py

Lines changed: 103 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,103 @@
1-
import os.path
2-
import numpy as np
3-
from skimage.io import imread, imsave
4-
from skimage.metrics import mean_squared_error, structural_similarity
5-
from skimage.exposure import match_histograms, rescale_intensity
6-
import ctypes
7-
8-
"""
9-
Calculates SSIM map as a result of the comparison of 2 channels and metrics values (in the log file).
10-
11-
For the output image, it is highly recommended to use LUT color mapping to better see the variations in the SSIM values
12-
All real SSIM values (ranging from 0 to 1) can be retrieved from the map doing the following: divide intensities by 255 if image is 8-bit, or by 65535 if 16-bit.
13-
14-
Side note: MSE and mean SSIM (and NRMSE, PSNR) values are output in the log
15-
To be able to see the printed info in the log file, set:
16-
File > Options > Logging > Verbosity = everything
17-
18-
Sources:
19-
https://scikit-image.org/docs/dev/api/skimage.metrics.html?highlight=structural#skimage.metrics.structural_similarity
20-
https://scikit-image.org/docs/dev/auto_examples/color_exposure/plot_histogram_matching.html#sphx-glr-auto-examples-color-exposure-plot-histogram-matching-py
21-
22-
23-
Requirements
24-
------------
25-
numpy (comes with Aivia installer)
26-
scikit-image (comes with Aivia installer)
27-
28-
Parameters
29-
----------
30-
First input: image to compare (e.g.Deep Learning restored image)
31-
Second input: reference (e.g. Ground Truth image), the one adjusted by histogram matching.
32-
IMPORTANT: Input channels need to have the same bit depth
33-
34-
Returns
35-
-------
36-
First output: calculated SSIM map
37-
Second output: reference image transformed with histogram matching
38-
39-
"""
40-
41-
# [INPUT Name:inputGTImagePath Type:string DisplayName:'Input Ground Truth Image']
42-
# [INPUT Name:inputRTImagePath Type:string DisplayName:'Input Restored Image']
43-
# [OUTPUT Name:resultPathAdj Type:string DisplayName:'GT Hist match image']
44-
# [OUTPUT Name:resultPath Type:string DisplayName:'SSIM image']
45-
def run(params):
46-
RTimageLocation = params['inputRTImagePath']
47-
GTimageLocation = params['inputGTImagePath']
48-
resultLocation = params['resultPath']
49-
resultLocationAdj = params['resultPathAdj']
50-
51-
# Checking existence of temporary files (individual channels)
52-
if not os.path.exists(RTimageLocation):
53-
print(f'Error: {RTimageLocation} does not exist')
54-
return;
55-
if not os.path.exists(GTimageLocation):
56-
print(f'Error: {GTimageLocation} does not exist')
57-
return;
58-
59-
# Loading input images
60-
RTData = imread(RTimageLocation)
61-
GTData = imread(GTimageLocation)
62-
print(f'Dimensions of Restored image: {RTData.shape}')
63-
print(f'Dimensions of GT image: {GTData.shape}')
64-
65-
# Checking dtype is the same for both input channels
66-
if GTData.dtype != RTData.dtype:
67-
error_mes = "The bit depth of your input channels is not the same. Convert one of them and retry."
68-
ctypes.windll.user32.MessageBoxW(0, error_mes, 'Error', 0)
69-
sys.exit(error_mes)
70-
71-
# Histogram matching
72-
matched_GTData = match_histograms(GTData, RTData).astype(RTData.dtype)
73-
74-
# MSE measurement
75-
# valMSE = skimage.measure.compare_mse(RTData, GTData) # deprecated in scikit-image 0.18
76-
valMSE = mean_squared_error(RTData, matched_GTData)
77-
print(f'___ MSE = {valMSE} ___') # Value appears in the log if Verbosity option is set to 'Everything'
78-
79-
# SSIM measurement
80-
outFullSSIM = structural_similarity(RTData, matched_GTData, full=True)
81-
82-
# Extracting mean value (first item)
83-
outMeanSSIM = outFullSSIM[0]
84-
print(f'___ Mean SSIM = {outMeanSSIM} ___')
85-
86-
# Extracting map (second item)
87-
outSSIM = outFullSSIM[1]
88-
print(f'Bit depth of SSIM array: {outSSIM.dtype}')
89-
90-
# Convert output array whose range is [0-1] to adjusted bit range (8- or 16-bit) if necessary
91-
if RTData.dtype != np.dtype('float64') and RTData.dtype != np.dtype('float32'):
92-
outputData = rescale_intensity(outSSIM, in_range=(0, 1), out_range=(0, np.iinfo(RTData.dtype).max))
93-
outputData = outputData.astype(RTData.dtype)
94-
else:
95-
outputData = outSSIM
96-
97-
imsave(resultLocation, outputData)
98-
imsave(resultLocationAdj, matched_GTData)
1+
import os.path
2+
import numpy as np
3+
from skimage.io import imread, imsave
4+
from skimage.metrics import mean_squared_error, structural_similarity
5+
from skimage.exposure import match_histograms, rescale_intensity
6+
import ctypes
7+
8+
"""
9+
Calculates SSIM map as a result of the comparison of 2 channels and metrics values (in the log file).
10+
11+
For the output image, it is highly recommended to use LUT color mapping to better see the variations in the SSIM values
12+
All real SSIM values (ranging from 0 to 1) can be retrieved from the map doing the following: divide intensities by 255 if image is 8-bit, or by 65535 if 16-bit.
13+
14+
Side note: MSE and mean SSIM (and NRMSE, PSNR) values are output in the log
15+
To be able to see the printed info in the log file, set:
16+
File > Options > Logging > Verbosity = everything
17+
18+
Sources:
19+
https://scikit-image.org/docs/dev/api/skimage.metrics.html?highlight=structural#skimage.metrics.structural_similarity
20+
https://scikit-image.org/docs/dev/auto_examples/color_exposure/plot_histogram_matching.html#sphx-glr-auto-examples-color-exposure-plot-histogram-matching-py
21+
22+
23+
Requirements
24+
------------
25+
numpy (comes with Aivia installer)
26+
scikit-image (comes with Aivia installer)
27+
28+
Parameters
29+
----------
30+
First input: image to compare (e.g.Deep Learning restored image)
31+
Second input: reference (e.g. Ground Truth image), the one adjusted by histogram matching.
32+
IMPORTANT: Input channels need to have the same bit depth
33+
34+
Returns
35+
-------
36+
First output: calculated SSIM map
37+
Second output: reference image transformed with histogram matching
38+
39+
"""
40+
41+
# [INPUT Name:inputGTImagePath Type:string DisplayName:'Input Ground Truth Image']
42+
# [INPUT Name:inputRTImagePath Type:string DisplayName:'Input Restored Image']
43+
# [OUTPUT Name:resultPathAdj Type:string DisplayName:'GT Hist match image']
44+
# [OUTPUT Name:resultPath Type:string DisplayName:'SSIM image']
45+
def run(params):
46+
RTimageLocation = params['inputRTImagePath']
47+
GTimageLocation = params['inputGTImagePath']
48+
resultLocation = params['resultPath']
49+
resultLocationAdj = params['resultPathAdj']
50+
channel_axis=params.get('channel_axis')
51+
if channel_axis == "None":
52+
channel_axis = None
53+
else:
54+
channel_axis = int(channel_axis)
55+
56+
# Checking existence of temporary files (individual channels)
57+
if not os.path.exists(RTimageLocation):
58+
print(f'Error: {RTimageLocation} does not exist')
59+
return;
60+
if not os.path.exists(GTimageLocation):
61+
print(f'Error: {GTimageLocation} does not exist')
62+
return;
63+
64+
# Loading input images
65+
RTData = imread(RTimageLocation)
66+
GTData = imread(GTimageLocation)
67+
print(f'Dimensions of Restored image: {RTData.shape}')
68+
print(f'Dimensions of GT image: {GTData.shape}')
69+
70+
# Checking dtype is the same for both input channels
71+
if GTData.dtype != RTData.dtype:
72+
error_mes = "The bit depth of your input channels is not the same. Convert one of them and retry."
73+
ctypes.windll.user32.MessageBoxW(0, error_mes, 'Error', 0)
74+
sys.exit(error_mes)
75+
76+
# Histogram matching
77+
matched_GTData = match_histograms(GTData, RTData).astype(RTData.dtype)
78+
79+
# MSE measurement
80+
# valMSE = skimage.measure.compare_mse(RTData, GTData) # deprecated in scikit-image 0.18
81+
valMSE = mean_squared_error(RTData, matched_GTData)
82+
print(f'___ MSE = {valMSE} ___') # Value appears in the log if Verbosity option is set to 'Everything'
83+
84+
# SSIM measurement
85+
outFullSSIM = structural_similarity(RTData, matched_GTData, full=True, channel_axis=channel_axis)
86+
87+
# Extracting mean value (first item)
88+
outMeanSSIM = outFullSSIM[0]
89+
print(f'___ Mean SSIM = {outMeanSSIM} ___')
90+
91+
# Extracting map (second item)
92+
outSSIM = outFullSSIM[1]
93+
print(f'Bit depth of SSIM array: {outSSIM.dtype}')
94+
95+
# Convert output array whose range is [0-1] to adjusted bit range (8- or 16-bit) if necessary
96+
if RTData.dtype != np.dtype('float64') and RTData.dtype != np.dtype('float32'):
97+
outputData = rescale_intensity(outSSIM, in_range=(0, 1), out_range=(0, np.iinfo(RTData.dtype).max))
98+
outputData = outputData.astype(RTData.dtype)
99+
else:
100+
outputData = outSSIM
101+
102+
imsave(resultLocation, outputData)
103+
imsave(resultLocationAdj, matched_GTData)

0 commit comments

Comments
 (0)