Skip to content

Commit

Permalink
update name for the measurment
Browse files Browse the repository at this point in the history
notebook update + new test_Data

Update README.md

fix error .json serialization... in Moprhology_main.py

Update README.md

remove cpython-38.pyc

remove __pycache
  • Loading branch information
Thibault Tabarin committed Jun 30, 2022
1 parent d4b0e1d commit 8d60573
Show file tree
Hide file tree
Showing 13 changed files with 1,865 additions and 69 deletions.
31 changes: 28 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ img_seg = tc.segmented_image("image_segmented.png")

## 4- Input and Output
The main script is Morphology_main.py The usage is python Morphology_main.py input_file.png metadata.json measure.json landmark.json presence.json image_lm.png
Code to test using the data provided in [/Test_Data/]()
```
Morphology_main.py Test_Data/INHS_FISH_18609_segmented.png Test_Data/INHS_FISH_18609.js
on Test_Data/INHS_FISH_18609_measure.json Test_Data/INHS_FISH_18609_landmark.json Test_Data/INHS_FISH_18609_presence.json Test_Data/INHS_FISH_18609_image_lm.png
```

+ input_file.png : segmented fish image generated by [Maruf code](), [example here](https://github.com/thibaulttabarin/Morphology-analysis/blob/main/Test_Data/INHS_FISH_000742_segmented.png)
+ metadata.json : generated by [drexel]() [example here](https://github.com/thibaulttabarin/Morphology-analysis/blob/main/Test_Data/INHS_FISH_000742.json)
Expand All @@ -120,6 +125,26 @@ You will need to use [Morphology_env.yml](https://github.com/thibaulttabarin/Mor
We use github action to create a container what run the main script [Morphology_main.py](https://github.com/thibaulttabarin/Morphology-analysis/blob/main/Scripts/Morphology_main.py).
1. The workflow to build the container is defined [here](https://github.com/thibaulttabarin/Morphology-analysis/blob/main/.github/workflows/Deploy_Morpholgy.yml).
2. The Dockerfile definition is [here](https://github.com/thibaulttabarin/Morphology-analysis/blob/main/Dockerfile)
3. Pull command : docker pull ghcr.io/thibaulttabarin/morphology-analysis/morphology:0.0.2 or singularity pull My_morphology_name.sif
4. To access the instruction Run : "singularity run My_morphology_name.sif" or
5. Usage : singularity exec My_morphology_name.sif Morphology_main.py <input_file> <metadata.json> <measure.json> <landmark.json> <presence.json> <image_lm.png>
3. Pull command :
```
docker pull ghcr.io/thibaulttabarin/morphology-analysis/morphology:latest
#or
singularity pull My_morphology_name.sif docker://ghcr.io/thibaulttabarin/morphology-analysis/morphology:latest
```
4. To access the instruction Run : "
```
singularity run My_morphology_name.sif
```
5. Usage :
```
singularity exec My_morphology_name.sif Morphology_main.py <input_file> <metadata.json> <measure.json> <landmark.json> <presence.json> <image_lm.png>
# test with
singularity exec My_morphology_name.sif Morphology_main.py Test_Data/INHS_FISH_18609_segmented.png Test_Data/INHS_FISH_18609.json Test_Data/INHS_FISH_18609_measure.json Test_Data/INHS_FISH_18609_landmark.json Test_Data/INHS_FISH_18609_presence.json Test_Data/INHS_FISH_18609_image_lm.png
```
## 7- Development tricks

If you want to test neww version of Morphology_main.py (upudated version on your local computer) you can use the container by bind the local folder (here, Scripts/) containing the updated version of Morphology_main.py and /pipeline/Morphology is where Morphology_main.py is expected to be in the container.
```
singularity exec --bind Scripts/:/pipeline/Morphology morpho.sif Morphology_main.py Test_Data/INHS_FISH_18609_segmented.png Test_Data/INHS_FISH_18609.json Test_Data/INHS_FISH_18609_measure.json Test_Data/INHS_FISH_18609_landmark.json Test_Data/INHS_FISH_18609_presence.json Test_Data/INHS_FISH_18609_image_lm.png
```
1,063 changes: 1,063 additions & 0 deletions Scripts/.ipynb_checkpoints/Morphology_dev-checkpoint.ipynb

Large diffs are not rendered by default.

754 changes: 706 additions & 48 deletions Scripts/Morphology_dev.ipynb

Large diffs are not rendered by default.

16 changes: 15 additions & 1 deletion Scripts/Morphology_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""
import Traits_class as tc
import json, sys
import numpy as np

def get_scale(metadata_file):

Expand All @@ -27,6 +28,18 @@ def get_scale(metadata_file):
unit =[None]
return scale , unit

# this class is used by json.dump to control that every value as the right format
# particular problem encounter with np.int64 value type
class NpEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, np.integer):
return int(obj)
if isinstance(obj, np.floating):
print(obj)
return float(obj)
if isinstance(obj, np.ndarray):
return obj.tolist()
return json.JSONEncoder.default(self, obj)

def main(input_file, metadata_file, output_measure, output_landmark, output_presence,
output_lm_image=None):
Expand All @@ -43,8 +56,9 @@ def main(input_file, metadata_file, output_measure, output_landmark, output_pres
measurement['unit'] = unit

# Save the dictionnaries in json file
# use NpEncoder to convert the value to correct type (np.int64 -> int)
with open(output_measure, 'w') as f:
json.dump(measurement, f)
json.dump(measurement, f, cls=NpEncoder)

with open(output_landmark, 'w') as f:
json.dump(landmark, f)
Expand Down
66 changes: 49 additions & 17 deletions Scripts/Traits_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,27 +362,47 @@ def all_landmark(self):

# reorder the key
new_landmark={}
list_order = [str(i) for i in range(1,19)]
list_order = [str(i) for i in range(1,16)]
for key in list_order:
new_landmark[key] = landmark[key]

return new_landmark


def measure_eye_area(self):
'''
Calculate eye area after cleaning and filing hole
'''
mask = self.mask
eye_region = self.clean_trait_region(mask['eye'])

return eye_region.area

def measure_head_area(self):
'''
Calculate head area after cleaning and filing hole
'''
mask = self.mask
head_region = self.clean_trait_region(mask['head'])

return head_region.area

def measure_eye_head_ratio(self):
'''
Create eye head area ratio
1- Area head after cleaning and filling hole
2- Area eye after cleaning and filing hole
3- ratio
'''
mask = self.mask
head_region = self.clean_trait_region(mask['head'])
eye_region = self.clean_trait_region(mask['eye'])
eye_areaa = measure_eye_area()
head_area = measure_head_area()

eye_head_ratio = eye_region.area/head_region.area
eye_head_ratio = eye_area/head_area

return eye_head_ratio
return eye_head_ratio


def measure_eye_diameter(self):
'''
Expand All @@ -392,7 +412,7 @@ def measure_eye_diameter(self):
mask = self.mask
eye_region = self.clean_trait_region(mask['eye'])

eq_diameter = (eye_region.area/math.pi)**0.5
eq_diameter = eye_region.equivalent_diameter_area

return eq_diameter

Expand All @@ -407,6 +427,19 @@ def measure_head_length(self):

return head_length

def calculate_triangle_area(self, point_1, point_2, point_3):

# calculate the semi-perimeter
a = self.get_distance(point_1, point_2)
b = self.get_distance(point_2, point_3)
c = self.get_distance(point_3, point_1)

s = (a + b + c) / 2

# calculate the area
area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
return area

def measure_head_depth(self):
'''
Measure vertical length of the head passing by the center of the eye
Expand All @@ -433,16 +466,15 @@ def all_measure(self):
landmark = self.landmark
measure={}
# Standard length body length
measure['A'] = self.get_distance(landmark['1'],landmark['6'])
measure['B'] = self.measure_eye_head_ratio()
measure['C'] = self.measure_eye_diameter()
measure['D'] = self.measure_head_depth()
# Head length landmark 2 to 15
measure['E'] = self.get_distance(landmark['2'],landmark['15'])
#
measure['F'] = self.get_distance(landmark['1'],landmark['14'])
#
measure['G'] = self.get_distance(landmark['1'],landmark['6'])
measure['SL'] = self.get_distance(landmark['1'],landmark['6'])
measure['EA'] = int(self.measure_eye_area())
measure['HAt'] = self.calculate_triangle_area(landmark['1'],landmark['2'],landmark['13'])
measure['HAp'] = self.measure_head_area()
measure['HCL'] = "WIP"
measure['ED'] = self.measure_eye_diameter()
measure['HL'] = self.get_distance(landmark['1'],landmark['12'])
measure['HD'] = self.get_distance(landmark['2'],landmark['13'])
measure['pOD'] = self.get_distance(landmark['1'],landmark['14'])
return measure

def visualize_landmark(self):
Expand Down
Binary file removed Scripts/__pycache__/Traits_class.cpython-37.pyc
Binary file not shown.
Binary file removed Scripts/__pycache__/Traits_class.cpython-38.pyc
Binary file not shown.
1 change: 1 addition & 0 deletions Test_Data/INHS_FISH_18609.json

Large diffs are not rendered by default.

Binary file added Test_Data/INHS_FISH_18609_image_lm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions Test_Data/INHS_FISH_18609_landmark.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"1": [98, 38], "2": [51, 147], "3": [38, 326], "4": [71, 439], "5": [107, 599], "6": [138, 621], "7": [162, 586], "8": [163, 498], "9": [176, 416], "10": [172, 319], "11": [122, 188], "12": [100, 189], "13": [139, 120], "14": [80, 77], "15": [80, 120]}
1 change: 1 addition & 0 deletions Test_Data/INHS_FISH_18609_measure.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"SL": 584.3706015877253, "EA": 1134, "HAt": 4161.499999999999, "HAp": 9397, "HCL": "WIP", "ED": 37.99807421080277, "HL": 151.0132444522665, "HD": 92.04890004774636, "pOD": 42.95346318982906, "scale": 390.423, "unit": "cm"}
1 change: 1 addition & 0 deletions Test_Data/INHS_FISH_18609_presence.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"dorsal_fin": {"number": 1, "percentage": 1.0}, "adipos_fin": {"number": 0, "percentage": 0}, "caudal_fin": {"number": 1, "percentage": 1.0}, "anal_fin": {"number": 1, "percentage": 1.0}, "pelvic_fin": {"number": 2, "percentage": 0.9156065777226187}, "pectoral_fin": {"number": 1, "percentage": 1.0}, "head": {"number": 1, "percentage": 1.0}, "eye": {"number": 1, "percentage": 1.0}, "caudal_fin_ray": {"number": 0, "percentage": 0}, "alt_fin_ray": {"number": 0, "percentage": 0}, "trunk": {"number": 2, "percentage": 0.9499680160833409}}
Binary file added Test_Data/INHS_FISH_18609_segmented.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8d60573

Please sign in to comment.