Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# Copyright CNRS/Inria/UNS
# Contributor(s): Eric Debreuve (since 2019), Morgane Nadal (2020)
#
# eric.debreuve@cnrs.fr
#
# This software is governed by the CeCILL license under French law and
# abiding by the rules of distribution of free software. You can use,
# modify and/ or redistribute the software under the terms of the CeCILL
# license as circulated by CEA, CNRS and INRIA at the following URL
# "http://www.cecill.info".
#
# As a counterpart to the access to the source code and rights to copy,
# modify and redistribute granted by the license, users are provided only
# with a limited warranty and the software's author, the holder of the
# economic rights, and the successive licensors have only limited
# liability.
#
# In this respect, the user's attention is drawn to the risks associated
# with loading, using, modifying and/or developing or reproducing the
# software by the user in light of its specific status of free software,
# that may mean that it is complicated to manipulate, and that also
# therefore means that it is reserved for developers and experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards their
# requirements in conditions enabling the security of their systems and/or
# data to be ensured and, more generally, to use and operate it in the
# same conditions as regards security.
#
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL license and that you accept its terms.
import math as mt_
import re as re_
import numpy as np_
from PIL import Image
from PIL.ExifTags import TAGS
from brick.general.type import array_t
def FindVoxelDimensionInMicron(
data_path: str, size_voxel_in_micron: list = None
) -> array_t:
"""
Find Voxel dimension in micron from the image metadata.
"""
#
if size_voxel_in_micron is not None:
print("VOXEL DIM: [X Y Z] =", size_voxel_in_micron, "micron.")
return np_.array(size_voxel_in_micron)
else: # TODO if not found, try to make something more general
print("Warning: The size of a voxel is not specified in the parameters.")
try:
# Find the voxels dimensions in micron in the metadata.
# /!\ Very specific to one type of microscope metadata !
with Image.open(data_path) as img:
# Use the exif tags into the image metadata
meta_dict = {TAGS.get(key, "missing"): img.tag[key] for key in img.tag}
# Decode the tags text
metadata = meta_dict["missing"].decode("utf8")
metadata = metadata.replace("\x00", "")
# Initialize the list of voxel size in str
voxel_size = []
for axe in "XYZ":
pattern = (
"Voxel" + axe + ".+\= (\d.+E.\d.)"
) # Regular expression found in metadata
voxel_size.append(re_.findall(pattern, metadata)[0])
voxel_size = np_.array(list(map(float, voxel_size)))
# Conversion meters in micron
voxel_size_micron = 1.0e6 * voxel_size
print("VOXEL DIM: [X Y Z] =", voxel_size_micron, "micron.")
return voxel_size_micron
except Exception as exception:
raise ValueError(
f"{exception}: /!\ Unable to find the voxel dimensions in micron. Specify it in the parameters."
)
def ToPixel(
micron: float,
voxel_size_micron: array_t,
dimension: tuple = (0,),
decimals: int = None,
) -> int:
"""
Dimension correspond to the axis (X,Y,Z) = (0,1,2). Can be used for distance, area and volumes.
"""
# Conversion of micron into pixels.
return round(
micron / (mt_.prod(voxel_size_micron[axis] for axis in dimension)), decimals
)
def ToMicron(
pixel: float, voxel_size_micron: list, dimension: tuple = (0,), decimals: int = None
) -> float:
"""
Dimension correspond to the axis (X,Y,Z) = (0,1,2). Can be used for distance, area and volumes.
"""
# Conversion of pixels into microns
return round(
pixel * (mt_.prod(voxel_size_micron[axis] for axis in dimension)), decimals
)