Skip to content

Commit 31190a9

Browse files
Merge pull request #4 from lambda-science/dev
Dev
2 parents 6ecfe65 + 6df17c4 commit 31190a9

File tree

8 files changed

+329
-272
lines changed

8 files changed

+329
-272
lines changed

myoquant/commands/run_sdh.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -164,21 +164,23 @@ def sdh_analysis(
164164
progress.add_task(description="Reading all inputs...", total=None)
165165
image_ndarray_sdh = imread(image_path)
166166

167-
if mask_path is not None:
168-
mask_ndarray = imread(mask_path)
169-
if np.unique(mask_ndarray).shape[0] != 2:
170-
console.print(
171-
"The mask image should be a binary image with only 2 values (0 and 1).",
172-
style="red",
173-
)
174-
raise ValueError
175-
if len(image_ndarray_sdh.shape) > 2:
176-
mask_ndarray = np.repeat(
177-
mask_ndarray.reshape(mask_ndarray.shape[0], mask_ndarray.shape[1], 1),
178-
image_ndarray_sdh.shape[2],
179-
axis=2,
180-
)
181-
image_ndarray_sdh = image_ndarray_sdh * mask_ndarray
167+
if mask_path is not None:
168+
mask_ndarray = imread(mask_path)
169+
if np.unique(mask_ndarray).shape[0] != 2:
170+
console.print(
171+
"The mask image should be a binary image with only 2 values (0 and 1).",
172+
style="red",
173+
)
174+
raise ValueError
175+
if len(image_ndarray_sdh.shape) > 2:
176+
mask_ndarray = np.repeat(
177+
mask_ndarray.reshape(
178+
mask_ndarray.shape[0], mask_ndarray.shape[1], 1
179+
),
180+
image_ndarray_sdh.shape[2],
181+
axis=2,
182+
)
183+
image_ndarray_sdh = image_ndarray_sdh * mask_ndarray
182184
if cellpose_path is not None:
183185
mask_cellpose = imread(cellpose_path)
184186

myoquant/src/ATP_analysis.py

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import pandas as pd
2-
from skimage.measure import regionprops_table
32
from scipy.stats import gaussian_kde
43
from sklearn.mixture import GaussianMixture
5-
4+
from .common_func import extract_single_image, df_from_cellpose_mask
65
import numpy as np
6+
import matplotlib.pyplot as plt
77

88
labels_predict = {1: "fiber type 1", 2: "fiber type 2"}
99
np.random.seed(42)
@@ -12,13 +12,8 @@
1212
def get_all_intensity(image_array, df_cellpose):
1313
all_cell_median_intensity = []
1414
for index in range(len(df_cellpose)):
15-
single_cell_img = image_array[
16-
df_cellpose.iloc[index, 5] : df_cellpose.iloc[index, 7],
17-
df_cellpose.iloc[index, 6] : df_cellpose.iloc[index, 8],
18-
].copy()
15+
single_cell_img = extract_single_image(image_array, df_cellpose, index)
1916

20-
single_cell_mask = df_cellpose.iloc[index, 9].copy()
21-
single_cell_img[~single_cell_mask] = 0
2217
# Calculate median pixel intensity of the cell but ignore 0 values
2318
single_cell_median_intensity = np.median(single_cell_img[single_cell_img > 0])
2419
all_cell_median_intensity.append(single_cell_median_intensity)
@@ -44,6 +39,25 @@ def estimate_threshold(intensity_list):
4439
return threshold
4540

4641

42+
def plot_density(all_cell_median_intensity, intensity_threshold):
43+
if intensity_threshold == 0:
44+
intensity_threshold = estimate_threshold(all_cell_median_intensity)
45+
fig, ax = plt.subplots(figsize=(10, 5))
46+
density = gaussian_kde(all_cell_median_intensity)
47+
density.covariance_factor = lambda: 0.25
48+
density._compute_covariance()
49+
50+
# Create a vector of 256 values going from 0 to 256:
51+
xs = np.linspace(0, 255, 256)
52+
density_xs_values = density(xs)
53+
ax.plot(xs, density_xs_values, label="Estimated Density")
54+
ax.axvline(x=intensity_threshold, color="red", label="Threshold")
55+
ax.set_xlabel("Pixel Intensity")
56+
ax.set_ylabel("Density")
57+
ax.legend()
58+
return fig
59+
60+
4761
def predict_all_cells(histo_img, cellpose_df, intensity_threshold):
4862
all_cell_median_intensity = get_all_intensity(histo_img, cellpose_df)
4963
if intensity_threshold is None:
@@ -76,19 +90,7 @@ def paint_full_image(image_atp, df_cellpose, class_predicted_all):
7690

7791

7892
def run_atp_analysis(image_array, mask_cellpose, intensity_threshold=None):
79-
props_cellpose = regionprops_table(
80-
mask_cellpose,
81-
properties=[
82-
"label",
83-
"area",
84-
"centroid",
85-
"eccentricity",
86-
"bbox",
87-
"image",
88-
"perimeter",
89-
],
90-
)
91-
df_cellpose = pd.DataFrame(props_cellpose)
93+
df_cellpose = df_from_cellpose_mask(mask_cellpose)
9294
class_predicted_all, intensity_all = predict_all_cells(
9395
image_array, df_cellpose, intensity_threshold
9496
)

myoquant/src/HE_analysis.py

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,27 @@
11
import numpy as np
22
import pandas as pd
33
from skimage.draw import line
4-
from skimage.measure import regionprops_table
5-
6-
from .draw_line import *
4+
from .common_func import (
5+
extract_single_image,
6+
df_from_cellpose_mask,
7+
df_from_stardist_mask,
8+
)
9+
from .draw_line import (
10+
line_equation,
11+
calculate_intersection,
12+
calculate_closest_point,
13+
calculate_distance,
14+
)
15+
import matplotlib.pyplot as plt
716

817

918
def extract_ROIs(histo_img, index, cellpose_df, mask_stardist):
10-
single_cell_img = histo_img[
11-
cellpose_df.iloc[index, 5] : cellpose_df.iloc[index, 7],
12-
cellpose_df.iloc[index, 6] : cellpose_df.iloc[index, 8],
13-
].copy()
14-
nucleus_single_cell_img = mask_stardist[
15-
cellpose_df.iloc[index, 5] : cellpose_df.iloc[index, 7],
16-
cellpose_df.iloc[index, 6] : cellpose_df.iloc[index, 8],
17-
].copy()
19+
single_cell_img = extract_single_image(histo_img, cellpose_df, index)
20+
nucleus_single_cell_img = extract_single_image(mask_stardist, cellpose_df, index)
1821
single_cell_mask = cellpose_df.iloc[index, 9]
19-
single_cell_img[~single_cell_mask] = 0
20-
nucleus_single_cell_img[~single_cell_mask] = 0
21-
22-
props_nuc_single = regionprops_table(
23-
nucleus_single_cell_img,
24-
intensity_image=single_cell_img,
25-
properties=[
26-
"label",
27-
"area",
28-
"centroid",
29-
"eccentricity",
30-
"bbox",
31-
"image",
32-
"perimeter",
33-
"feret_diameter_max",
34-
],
22+
df_nuc_single = df_from_stardist_mask(
23+
nucleus_single_cell_img, intensity_image=single_cell_img
3524
)
36-
df_nuc_single = pd.DataFrame(props_nuc_single)
3725
return single_cell_img, nucleus_single_cell_img, single_cell_mask, df_nuc_single
3826

3927

@@ -45,14 +33,22 @@ def single_cell_analysis(
4533
y_fiber,
4634
cell_label,
4735
internalised_threshold=0.75,
36+
draw_and_return=False,
4837
):
38+
if draw_and_return:
39+
fig_size = (5, 5)
40+
f, ax = plt.subplots(figsize=fig_size)
41+
ax.scatter(x_fiber, y_fiber, color="white")
42+
4943
n_nuc, n_nuc_intern, n_nuc_periph = 0, 0, 0
5044
new_row_lst = []
5145
new_col_names = df_nuc_single.columns.tolist()
5246
new_col_names.append("internalised")
5347
new_col_names.append("score_eccentricity")
5448
new_col_names.append("cell label")
5549
for _, value in df_nuc_single.iterrows():
50+
if draw_and_return:
51+
ax.scatter(value[3], value[2], color="red")
5652
n_nuc += 1
5753
value = value.tolist()
5854
# Extend line and find closest point
@@ -68,6 +64,21 @@ def single_cell_analysis(
6864
m, b, (single_cell_img.shape[0], single_cell_img.shape[1])
6965
)
7066
border_point = calculate_closest_point(value[3], value[2], intersections_lst)
67+
if draw_and_return:
68+
ax.plot(
69+
(x_fiber, border_point[0]),
70+
(y_fiber, border_point[1]),
71+
"ro--",
72+
linewidth=1,
73+
markersize=1,
74+
)
75+
ax.plot(
76+
(x_fiber, value[3]),
77+
(y_fiber, value[2]),
78+
"go--",
79+
linewidth=1,
80+
markersize=1,
81+
)
7182
rr, cc = line(
7283
int(y_fiber),
7384
int(x_fiber),
@@ -95,6 +106,8 @@ def single_cell_analysis(
95106
value.append(ratio_dist)
96107
value.append(cell_label)
97108
new_row_lst.append(value)
109+
if draw_and_return:
110+
ax.scatter(coords[1], coords[0], color="red", s=10)
98111
break
99112
except IndexError:
100113
coords = list(zip(rr, cc))[index3 - 1]
@@ -114,8 +127,13 @@ def single_cell_analysis(
114127
value.append(ratio_dist)
115128
value.append(cell_label)
116129
new_row_lst.append(value)
130+
if draw_and_return:
131+
ax.scatter(coords[1], coords[0], color="red", s=10)
132+
ax.axis("off")
117133
break
118134
df_nuc_single_stats = pd.DataFrame(new_row_lst, columns=new_col_names)
135+
if draw_and_return:
136+
return n_nuc, n_nuc_intern, n_nuc_periph, df_nuc_single_stats, ax
119137
return n_nuc, n_nuc_intern, n_nuc_periph, df_nuc_single_stats
120138

121139

@@ -172,20 +190,7 @@ def paint_histo_img(histo_img, cellpose_df, prediction_df):
172190

173191

174192
def run_he_analysis(image_ndarray, mask_cellpose, mask_stardist, eccentricity_thresh):
175-
props_cellpose = regionprops_table(
176-
mask_cellpose,
177-
properties=[
178-
"label",
179-
"area",
180-
"centroid",
181-
"eccentricity",
182-
"bbox",
183-
"image",
184-
"perimeter",
185-
"feret_diameter_max",
186-
],
187-
)
188-
df_cellpose = pd.DataFrame(props_cellpose)
193+
df_cellpose = df_from_cellpose_mask(mask_cellpose)
189194
df_nuc_analysis, all_nuc_df_stats = predict_all_cells(
190195
image_ndarray, df_cellpose, mask_stardist, eccentricity_thresh
191196
)

myoquant/src/SDH_analysis.py

Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44

55
import pandas as pd
66
import tensorflow as tf
7-
from rich.progress import track
8-
from skimage.measure import regionprops_table
9-
7+
from .common_func import extract_single_image, df_from_cellpose_mask
108
from .gradcam import make_gradcam_heatmap, save_and_display_gradcam
119
import numpy as np
1210

@@ -32,14 +30,7 @@ def resize_batch_cells(histo_img, cellpose_df):
3230
img_array_full = np.empty((len(cellpose_df), 256, 256, 3))
3331
# for index in track(range(len(cellpose_df)), description="Resizing cells"):
3432
for index in range(len(cellpose_df)):
35-
single_cell_img = histo_img[
36-
cellpose_df.iloc[index, 5] : cellpose_df.iloc[index, 7],
37-
cellpose_df.iloc[index, 6] : cellpose_df.iloc[index, 8],
38-
].copy()
39-
40-
single_cell_mask = cellpose_df.iloc[index, 9].copy()
41-
single_cell_img[~single_cell_mask] = 0
42-
33+
single_cell_img = extract_single_image(histo_img, cellpose_df, index)
4334
img_array_full[index] = tf.image.resize(single_cell_img, (256, 256))
4435
return img_array_full
4536

@@ -54,7 +45,9 @@ def predict_all_cells(histo_img, cellpose_df, _model_SDH):
5445
predicted_class_array[index_counter] = prediction_result.argmax()
5546
predicted_proba_array[index_counter] = np.amax(prediction_result)
5647
index_counter += 1
57-
return predicted_class_array, predicted_proba_array
48+
cellpose_df["class_predicted"] = predicted_class_array
49+
cellpose_df["proba_predicted"] = predicted_proba_array
50+
return cellpose_df
5851

5952

6053
def paint_full_image(image_sdh, df_cellpose, class_predicted_all):
@@ -78,43 +71,28 @@ def paint_full_image(image_sdh, df_cellpose, class_predicted_all):
7871

7972

8073
def run_sdh_analysis(image_array, model_SDH, mask_cellpose):
81-
props_cellpose = regionprops_table(
82-
mask_cellpose,
83-
properties=[
84-
"label",
85-
"area",
86-
"centroid",
87-
"eccentricity",
88-
"bbox",
89-
"image",
90-
"perimeter",
91-
],
92-
)
93-
df_cellpose = pd.DataFrame(props_cellpose)
94-
class_predicted_all, proba_predicted_all = predict_all_cells(
95-
image_array, df_cellpose, model_SDH
96-
)
97-
df_cellpose["class_predicted"] = class_predicted_all
98-
df_cellpose["proba_predicted"] = proba_predicted_all
99-
count_per_label = np.unique(class_predicted_all, return_counts=True)
100-
class_and_proba_df = pd.DataFrame(
101-
list(zip(class_predicted_all, proba_predicted_all)),
102-
columns=["class", "proba"],
103-
)
74+
df_cellpose = df_from_cellpose_mask(mask_cellpose)
75+
76+
df_cellpose = predict_all_cells(image_array, df_cellpose, model_SDH)
77+
count_per_label = np.unique(df_cellpose["class_predicted"], return_counts=True)
10478

10579
# Result table dict
10680
headers = ["Feature", "Raw Count", "Proportion (%)"]
10781
data = []
108-
data.append(["Muscle Fibers", len(class_predicted_all), 100])
82+
data.append(["Muscle Fibers", len(df_cellpose["class_predicted"]), 100])
10983
for elem in count_per_label[0]:
11084
data.append(
11185
[
11286
labels_predict[int(elem)],
11387
count_per_label[1][int(elem)],
114-
100 * count_per_label[1][int(elem)] / len(class_predicted_all),
88+
100
89+
* count_per_label[1][int(elem)]
90+
/ len(df_cellpose["class_predicted"]),
11591
]
11692
)
11793
result_df = pd.DataFrame(columns=headers, data=data)
11894
# Paint The Full Image
119-
full_label_map = paint_full_image(image_array, df_cellpose, class_predicted_all)
95+
full_label_map = paint_full_image(
96+
image_array, df_cellpose, df_cellpose["class_predicted"]
97+
)
12098
return result_df, full_label_map, df_cellpose

0 commit comments

Comments
 (0)