Skip to content
Snippets Groups Projects
Commit 1e51888c authored by Harry Carey's avatar Harry Carey
Browse files

added basics of object based analysis

parent 3f0f8df4
No related branches found
No related tags found
No related merge requests found
......@@ -28,7 +28,7 @@ def getCentroidsAndArea(Segmentation, pixelCutOff=0):
# get the area of the objects
area = np.array([label.area for label in labelsInfo])
# get the coordinates for all the pixels in each object
coords = np.array([label.coords for label in labelsInfo])
coords = np.array([label.coords for label in labelsInfo], dtype=object)
return centroids, area, coords
......@@ -79,19 +79,17 @@ def transformToAtlasSpace(anchoring, Y, X, RegHeight, RegWidth):
return (O + XYZU + XYZV).T
# points.append would make list of lists, keeping sections separate.
# related to coordinate extraction
# this function returns an array of points
def FolderToAtlasSpace(
folder, QUINT_alignment, pixelID=[0, 0, 0], nonLinear=True
folder, QUINT_alignment, pixelID=[0, 0, 0], nonLinear=True, method="all"
):
"apply Segmentation to atlas space to all segmentations in a folder"
# this should be loaded above and passed as an argument
slices = loadVisuAlignJson(QUINT_alignment)
segmentationFileTypes = [".png", ".tif", ".tiff", ".jpg", ".jpeg"]
......@@ -100,7 +98,6 @@ def FolderToAtlasSpace(
for file in glob(folder + "/*")
if any([file.endswith(type) for type in segmentationFileTypes])
]
SectionNumbers = number_sections(Segmentations)
# order segmentations and sectionNumbers
# Segmentations = [x for _,x in sorted(zip(SectionNumbers,Segmentations))]
# SectionNumbers.sort()
......@@ -119,6 +116,7 @@ def FolderToAtlasSpace(
nonLinear,
pointsList,
index,
method,
),
)
threads.append(x)
......@@ -135,12 +133,22 @@ def FolderToAtlasSpace(
# related to coordinate extraction
# this function returns an array of points
def SegmentationToAtlasSpace(
slice, SegmentationPath, pixelID="auto", nonLinear=True, pointsList=None, index=None
slice,
SegmentationPath,
pixelID="auto",
nonLinear=True,
pointsList=None,
index=None,
method="per_pixel",
):
"""combines many functions to convert a segmentation to atlas space. It takes care
of deformations"""
Segmentation = cv2.imread(SegmentationPath)
if method in ["per_object", "all"]:
# this function returns the centroids, area and coordinates of all the objects in the segmentation
# right now we only use centroids
centroids, area, coords = getCentroidsAndArea(Segmentation, pixelCutOff=0)
print("number of objects: ", len(centroids))
if pixelID == "auto":
# remove the background from the segmentation
SegmentationNoBackGround = Segmentation[~np.all(Segmentation == 255, axis=2)]
......@@ -166,7 +174,9 @@ def SegmentationToAtlasSpace(
triangulation = triangulate(RegWidth, RegHeight, slice["markers"])
newX, newY = transform_vec(triangulation, scaledX, scaledY)
else:
print(f"no markers found for {slice['filename']}, result for section will be linear")
print(
f"no markers found for {slice['filename']}, result for section will be linear"
)
newX, newY = scaledX, scaledY
else:
newX, newY = scaledX, scaledY
......
......@@ -15,14 +15,14 @@ with open("../test/test5_NOP_s037.json", "r") as f:
# print(input)
# import our function for converting a folder of segmentations to points
from coordinate_extraction import FolderToAtlasSpace, FolderToAtlasSpaceMultiThreaded
from coordinate_extraction import FolderToAtlasSpace, FolderToAtlasSpace
from read_and_write import SaveDataframeasCSV, WritePointsToMeshview, FilesinDirectory
from counting_and_load import PixelCountPerRegion, labelPoints
startTime = datetime.now()
# now we can use our function to convert the folder of segmentations to points
points = FolderToAtlasSpaceMultiThreaded(
points = FolderToAtlasSpace(
input["segmentation_folder"],
input["alignment_json"],
pixelID=input["colour"],
......
......@@ -6,6 +6,7 @@ import json
import pandas as pd
from datetime import datetime
class PyNutil:
def __init__(
self,
......@@ -37,7 +38,7 @@ class PyNutil:
raise ValueError(
f"Atlas {volume_path} not found in config file, valid atlases are: \n{' , '.join(list(self.config['annotation_volumes'].keys()))}"
)
self.segmentation_folder = segmentation_folder
self.alignment_json = alignment_json
self.colour = colour
......@@ -45,7 +46,7 @@ class PyNutil:
# load the metadata json as well as the path to stored data files
def build_quantifier(self):
# do all the expensive computations
# this could potentially be moved into init
atlas_root_path = self.config["annotation_volume_directory"]
current_atlas_path = self.config["annotation_volumes"][self.atlas]["volume"]
print("loading atlas volume")
......@@ -57,48 +58,59 @@ class PyNutil:
print("loading atlas labels")
self.atlas_labels = pd.read_csv(atlas_root_path + atlas_label_path)
print("atlas labels loaded")
def get_coordinates(self, nonLinear=True, method="all"):
if not hasattr(self, "atlas_volume"):
raise ValueError("Please run build_quantifier before running get_coordinates")
raise ValueError(
"Please run build_quantifier before running get_coordinates"
)
if method not in ["per_pixel", "per_object", "all"]:
raise ValueError(f"method {method} not recognised, valid methods are: per_pixel, per_object, or all")
raise ValueError(
f"method {method} not recognised, valid methods are: per_pixel, per_object, or all"
)
print("extracting coordinates")
points = FolderToAtlasSpace(
pixel_points = FolderToAtlasSpace(
self.segmentation_folder,
self.alignment_json,
pixelID=self.colour,
nonLinear=nonLinear
nonLinear=nonLinear,
method=method,
)
self.points = points
self.pixel_points = pixel_points
def quantify_coordinates(self):
if not hasattr(self, "points"):
raise ValueError("Please run get_coordinates before running quantify_coordinates")
if not hasattr(self, "pixel_points"):
raise ValueError(
"Please run get_coordinates before running quantify_coordinates"
)
print("quantifying coordinates")
labeled_points = labelPoints(self.points, self.atlas_volume, scale_factor=2.5)
labeled_points = labelPoints(
self.pixel_points, self.atlas_volume, scale_factor=2.5
)
self.label_df = PixelCountPerRegion(labeled_points, self.atlas_labels)
self.labeled_points = labeled_points
print("quantification complete")
def save_analysis(self, output_folder):
if not hasattr(self, "points"):
if not hasattr(self, "pixel_points"):
raise ValueError("Please run get_coordinates before running save_analysis")
self.label_df.to_csv(
output_folder + "/counts.csv", sep=";", na_rep="", index=False
)
if not hasattr(self, "label_df"):
print("no quantification found so we will only save the coordinates")
print("if you want to save the quantification please run quantify_coordinates")
self.label_df.to_csv(output_folder + '/counts.csv', sep=";", na_rep="", index=False)
print(
"if you want to save the quantification please run quantify_coordinates"
)
else:
self.label_df.to_csv(output_folder + '/counts.csv', sep=";", na_rep="", index=False)
WritePointsToMeshview(
self.points,
self.pixel_points,
self.labeled_points,
output_folder + '/pixels_meshview.json',
self.atlas_labels
output_folder + "/pixels_meshview.json",
self.atlas_labels,
)
print("analysis saved")
......@@ -53,7 +53,8 @@ def WritePointsToMeshview(points, pointNames, filename, infoFile):
regionDict = createRegionDict(points, pointNames)
WritePoints(regionDict, filename, infoFile)
# I think this might not need to be its own function :)
# I think this might not need to be its own function :)
def SaveDataframeasCSV(df_to_save, output_csv):
"""Function for saving a df as a CSV file"""
df_to_save.to_csv(output_csv, sep=";", na_rep="", index=False)
......
from PyNutil import PyNutil
pnt = PyNutil(
settings_file=r"test/test4_2017.json"
)
pnt = PyNutil(settings_file=r"test/test4_2017.json")
pnt.build_quantifier()
pnt.get_coordinates()
pnt.quantify_coordinates()
pnt.save_analysis('outputs/test4_2017')
\ No newline at end of file
pnt.save_analysis("outputs/test4_2017")
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment