Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/vlab4mic/analysis/_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ def sns_heatmap_pivots(
f, axes = plt.subplots(nconditions, 2, figsize=figsize, squeeze = False)
plot_num = 0
if cmaps_range == "same":
# min and max here correspond to SSIM
hist_params = dict(vmin=0, vmax=1)
elif cmaps_range == "each":
hist_params = dict()
Expand Down
106 changes: 104 additions & 2 deletions src/vlab4mic/analysis/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,89 @@
from skimage.feature import peak_local_max
from scipy.stats import pearsonr
import cv2
import copy

def match_image_sizes(
reference_image = None,
reference_image_pixelsize_nm = None,
reference_image_mask = None,
simulated_image = None,
simulated_image_pixelsize_nm = None,
simulated_image_mask = None
):
union_mask = None
if reference_image_pixelsize_nm and simulated_image_pixelsize_nm:
reference_interpolated, simulated_image_interpolated = resize_images_interpolation(
img1=reference_image,
img2=simulated_image,
px_size_im1=reference_image_pixelsize_nm,
px_size_im2=simulated_image_pixelsize_nm,
)
if reference_image_mask is not None and simulated_image_mask is not None:
reference_mask_interpolated, simulated_image_mask_interpolated = resize_images_interpolation(
img1=reference_image_mask,
img2=simulated_image_mask,
px_size_im1=reference_image_pixelsize_nm,
px_size_im2=simulated_image_pixelsize_nm,
interpolation_order=0 # becauese they are masks
)
union_mask = np.logical_or(
reference_mask_interpolated,
simulated_image_mask_interpolated)
#masks_interpolated["reference_mask"] = reference_mask_interpolated
#masks_interpolated["query_mask"] = simulated_image_mask_interpolated
#masks_interpolated["union_mask"] = union_mask
return reference_interpolated, simulated_image_interpolated, union_mask


def structural_similarity(
reference_image = None,
reference_image_pixelsize_nm = None,
reference_image_mask = None,
simulated_image = None,
simulated_image_pixelsize_nm = None,
simulated_image_mask = None
):
reference_interpolated, simulated_image_interpolated, union_mask = match_image_sizes(
reference_image = reference_image,
reference_image_pixelsize_nm = reference_image_pixelsize_nm,
reference_image_mask = reference_image_mask,
simulated_image = simulated_image,
simulated_image_pixelsize_nm = simulated_image_pixelsize_nm,
simulated_image_mask = simulated_image_mask
)
similarity = ssim(
reference_interpolated[union_mask],
simulated_image_interpolated[union_mask],
data_range=simulated_image_interpolated[union_mask].max() - simulated_image_interpolated[union_mask].min()
)
return similarity


def pearson_correlation(
reference_image = None,
reference_image_pixelsize_nm = None,
reference_image_mask = None,
simulated_image = None,
simulated_image_pixelsize_nm = None,
simulated_image_mask = None
):
reference_interpolated, simulated_image_interpolated, union_mask = match_image_sizes(
reference_image = reference_image,
reference_image_pixelsize_nm = reference_image_pixelsize_nm,
reference_image_mask = reference_image_mask,
simulated_image = simulated_image,
simulated_image_pixelsize_nm = simulated_image_pixelsize_nm,
simulated_image_mask = simulated_image_mask
)
pearson_correlation, pval = pearsonr(
reference_interpolated[union_mask].flatten(),
simulated_image_interpolated[union_mask].flatten()
)
return pearson_correlation


def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_mask = None, query_mask = None, **kwargs):
def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_mask = None, query_mask = None, custom_metrics = None, **kwargs):
"""
Compare two images using specified similarity metrics.

Expand Down Expand Up @@ -34,8 +115,14 @@ def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_
query : numpy.ndarray
(Possibly resized) query image.
"""
reference_image = ref.copy()
query_image = query.copy()
ref_pixelsize = None
query_pixelsize = None
if force_match:
if 'ref_pixelsize' in kwargs and 'modality_pixelsize' in kwargs:
ref_pixelsize = copy.copy(kwargs['ref_pixelsize'])
query_pixelsize = copy.copy(kwargs['modality_pixelsize'])
ref, query = resize_images_interpolation(
img1=ref,
img2=query,
Expand Down Expand Up @@ -66,14 +153,29 @@ def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_
zoom_in=zoom_in
)
similarity_vector = []

for method in metric:
if method == "ssim":
similarity = ssim(ref[union_mask], query[union_mask], data_range=query[union_mask].max() - query[union_mask].min())
similarity_vector.append(similarity)
elif method == "pearson":
similarity, pval = pearsonr(ref[union_mask].flatten(), query[union_mask].flatten())
similarity_vector.append(similarity)
elif method in custom_metrics.keys():
custom_measurement = custom_metrics[method](
reference_image = reference_image,
reference_image_pixelsize_nm = ref_pixelsize,
simulated_image = query_image,
simulated_image_pixelsize_nm = query_pixelsize,
image_mask = union_mask,
resized_reference_image = ref,
resized_simulated_image = query,
**kwargs
)
#custom_measurement = metric_calculator.run_metric()
if isinstance(custom_measurement, float):
similarity_vector.append(custom_measurement)
else:
similarity_vector.append(None)
return similarity_vector, ref, query, masks_used


Expand Down
102 changes: 35 additions & 67 deletions src/vlab4mic/analysis/sweep.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,51 +503,6 @@ def generate_global_reference_modality(
return reference_output[modality]["ch0"], reference_parameters, reference_output_mask


def analyse_image_sweep(
img_outputs, img_params, reference, analysis_case_params=None
):
"""
Analyse a sweep of images against a reference image.

Parameters
----------
img_outputs : dict
Dictionary of simulated image outputs.
img_params : dict
Dictionary of image parameters.
reference : numpy.ndarray
Reference image.
analysis_case_params : dict, optional
Additional parameters for analysis.

Returns
-------
measurement_vectors : list
List of measurement results for each image.
inputs : dict
Dictionary of input images and used references.
"""
measurement_vectors = []
# ref_pixelsize = analysis_case_params["ref_pixelsize"]
inputs = dict()
for params_id in img_params.keys():
inputs[params_id] = dict()
rep_number = 0
mod_name = img_params[params_id][5] # 5th item corresponds to Modality
for img_r in img_outputs[params_id]:
im1 = img_r[0]
im_ref = reference[0]
rep_measurement, ref_used, qry_used_, masks_used = metrics.img_compare(
im_ref, im1, **analysis_case_params[mod_name]
)
measurement_vectors.append(
[params_id, rep_number, rep_measurement]
)
inputs[params_id][rep_number] = [qry_used, im1]
rep_number += 1
return measurement_vectors, inputs


def analyse_sweep_single_reference(
img_outputs,
img_outputs_masks,
Expand All @@ -556,9 +511,8 @@ def analyse_sweep_single_reference(
reference_image_mask,
reference_params,
zoom_in=0,
metrics_list: list = [
"ssim",
],
metrics: dict = None,
#custom_metrics = None,
**kwargs,
):
"""
Expand Down Expand Up @@ -600,26 +554,39 @@ def analyse_sweep_single_reference(
modality_pixelsize = img_params[params_id][6]["pixelsize"]
for img_r, img_mask in zip(img_outputs[params_id], img_outputs_masks[params_id]):
im1 = img_r[0]
im1_mask = img_mask
#print(f"query: {im1.shape},{im1_mask.shape}")
im_ref = reference_image
rep_measurement, ref_used, qry_used, masks_used = metrics.img_compare(
ref = im_ref,
ref_mask=reference_image_mask,
query=im1,
query_mask=im1_mask,
modality_pixelsize=modality_pixelsize,
ref_pixelsize=reference_params["ref_pixelsize"],
force_match=True,
zoom_in=zoom_in,
metric=metrics_list,
)
r_vector = list([params_id, rep_number]) + list([*rep_measurement])
measurement_vectors.append(r_vector)
# measurement_vectors = measurement_vectors + rep_measurement[0]
inputs[params_id][rep_number] = [qry_used, im1, ref_used, masks_used]
#im1_mask = img_mask
#im_ref = reference_image
similarity_vector = []
metrics_names_list = []
for metric_name, metric in metrics.items():
#metrics_names_list.append(metric_name)
similarity_vector.append(metric(
reference_image = reference_image,
reference_image_pixelsize_nm = reference_params["ref_pixelsize"],
reference_image_mask = reference_image_mask,
simulated_image = im1,
simulated_image_pixelsize_nm = modality_pixelsize,
simulated_image_mask = img_mask,
)
)
#rep_measurement, ref_used, qry_used, masks_used = metrics.img_compare(
# ref = im_ref,
# ref_mask=reference_image_mask,
# query=im1,
# query_mask=im1_mask,
# modality_pixelsize=modality_pixelsize,
# ref_pixelsize=reference_params["ref_pixelsize"],
# force_match=True,
# zoom_in=zoom_in,
# metrics = metrics
#)
# each image as its ID, a replica number and the metrics associated to it
replicaID_repN_metrics = list([params_id, rep_number]) + list([*similarity_vector])
measurement_vectors.append(replicaID_repN_metrics)
# for methods that require image resizing
#inputs[params_id][rep_number] = [qry_used, im1, ref_used, masks_used]
rep_number += 1
return measurement_vectors, inputs, metrics_list
return measurement_vectors, inputs, metrics_names_list


def measurements_dataframe(
Expand Down Expand Up @@ -683,6 +650,7 @@ def measurements_dataframe(
nmetrics = len(metric_names)
metrics_dictionary = dict()
for metric_number in range(nmetrics):
# first two indices are ID and replica number, then one value per metric
metricvector = measurement_array[:, 2 + metric_number]
metrics_dictionary[metric_names[metric_number]] = np.array(
metricvector, dtype=np.float64
Expand Down
Loading