From a7220a243e2a7851f45d94e11a5b552256d596cf Mon Sep 17 00:00:00 2001
From: monadal <morgane.nadal@inria.fr>
Date: Wed, 11 Mar 2020 10:29:54 +0100
Subject: [PATCH] fct for intensity normalization and find voxel dimension in
 micron + refractoring

---
 brick/processing/input.py | 39 +++++++++++++++++++++++++++++++++------
 nutrimorph.py             |  4 ++++
 2 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/brick/processing/input.py b/brick/processing/input.py
index a9a1a11..56a081f 100644
--- a/brick/processing/input.py
+++ b/brick/processing/input.py
@@ -32,9 +32,11 @@
 from brick.general.type import array_t
 import numpy as np_
 import sys as sy_
+from PIL import Image
+from PIL.ExifTags import TAGS
 
 
-def ImageVerification(image, channel):
+def ImageVerification(image: array_t, channel: str) -> array_t:
     if image.ndim == 3:
         print('Your image has only one color channel.')
         if channel == 'RGB':
@@ -59,6 +61,7 @@ def ImageVerification(image, channel):
         print('The image dimensions are not correct:', image.ndim, ', instead of 3 or 4.')
         sy_.exit(0)
 
+
 # if channel != 'RGB' and image.ndim == 4:
 #     print('The image has multiple color channels. The channel', channel, 'was specified in the parameters.')
 #     for idx, color in enumerate('RGB'):
@@ -70,12 +73,13 @@ def ImageVerification(image, channel):
 
 def IntensityNormalizedImage(image: array_t) -> array_t:
     #
-    print('Relative Intensity Normalization between 0 and 1 (Not a standardization). Need to reevaluate the parameters !!!')
+    print(
+        'Relative Intensity Normalization between 0 and 1 (Not a standardization). Need to reevaluate the parameters !!!')
 
     value_max = image.astype(np_.float32).max()
     value_min = image.astype(np_.float32).min()
 
-    result = (image.astype(np_.float32) - value_min)/(value_max - value_min)
+    result = (image.astype(np_.float32) - value_min) / (value_max - value_min)
 
     return result
 
@@ -92,9 +96,32 @@ def IntensityNormalizedImage(image: array_t) -> array_t:
     #
     # return result
 
-def MetricNormalizedImage(image: array_t) -> array_t:  # TODO
-    #
-    print('Image metric in converted to micrometers.')
+
+def VoxelDimensionInMicrons(data_path: str) -> array_t:
+    # TODO Verify if metadata are in the same format for all the images - if not, add a raise error ?
+
+    with Image.open(data_path) as img:  # Find the voxels dimensions in micron in the metadata.
+        meta_dict = {TAGS.get(key, 'missing'): img.tag[key] for key in
+                     img.tag}  # Use the exif tags into the image metadata
+
+    # Decode the tags text
+    metadata = meta_dict['missing'].decode('utf8')  # Decode the tags text
+    metadata = metadata.replace('\x00', '')
+
+    voxel_size = ['', '', '']  # Initialize the list of voxel size in str
+    for idaxe, axe in enumerate('XYZ'):
+        idvox = metadata.find('dblVoxel' + axe)  # Get the index of the voxel size for the axe X, Y, Z
+        idvox += 15
+        while metadata[idvox] != '\n':
+            voxel_size[idaxe] += metadata[idvox]
+            idvox += 1
+    voxel_size = np_.asarray(list(map(float, voxel_size)))
+    voxel_size_microns = 1.0e6 * voxel_size
+    print('Voxel dimension in the image is [X Y Z] =', voxel_size_microns, 'in microns. WARNING this method highly '
+                                                                           'depends on the format of the metadata.')
+
+    return voxel_size_microns
+
 
 def DijkstraCosts(image: array_t, som_map: array_t, ext_map: array_t) -> array_t:
     #
diff --git a/nutrimorph.py b/nutrimorph.py
index ca15e44..52d993c 100644
--- a/nutrimorph.py
+++ b/nutrimorph.py
@@ -54,6 +54,7 @@ import numpy as np_
 import skimage.io as io_
 import skimage.measure as ms_
 from skimage.segmentation import relabel_sequential
+import exifread as xf_
 
 print(sy_.argv, sy_.argv.__len__())
 
@@ -89,6 +90,9 @@ start_time = tm_.time()
 
 
 # --- Images
+voxel_micron = in_.VoxelDimensionInMicrons(data_path)
+
+
 image = io_.imread(data_path)
 
 # Image size verification - simple version without user interface
-- 
GitLab