image_output_1.png
import cv2

import matplotlib.pyplot as plt

import numpy as np

import os

import pandas as pd

import staintools

imaging_measurements = {'hpa': {'pixel_size': {'kidney': 0.4, 'prostate': 0.4, 'largeintestine': 0.4, 'spleen': 0.4, 'lung': 0.4}, 'tissue_thickness': {'kidney': 4, 'prostate': 4, 'largeintestine': 4, 'spleen': 4, 'lung': 4}}, 'hubmap': {'pixel_size': {'kidney': 0.5, 'prostate': 6.263, 'largeintestine': 0.229, 'spleen': 0.4945, 'lung': 0.7562}, 'tissue_thickness': {'kidney': 10, 'prostate': 5, 'largeintestine': 8, 'spleen': 4, 'lung': 5}}}

import staintools
target = cv2.imread('/kaggle/input/hubmap-organ-segmentation/test_images/10078.tiff')
target = staintools.LuminosityStandardizer.standardize(target)
normalizer = staintools.StainNormalizer(method='vahadane')
normalizer.fit(target)

OUT_TRAIN = './hubmap_images'
os.makedirs(OUT_TRAIN, exist_ok=False)
MASKS = '../input/hubmap-organ-segmentation/train.csv'
DATA = '../input/hubmap-organ-segmentation/train_images'

def augment_image(image, domain_pixel_size, target_pixel_size, domain_tissue_thickness, target_tissue_thickness, alpha=0.15):
    """
    Visualize raw and augmented images 
    Parameters
    ----------
    image (numpy.ndarray of shape (height, width, 3)): Image array
    domain_pixel_size (float): Pixel size of the domain images in micrometers
    target_pixel_size (float): Pixel size of the target images in micrometers
    domain_tissue_thickness (float): Tissue thickness of the domain images in micrometers
    target_tissue_thickness (float): Tissue thickness of the target images in micrometers
    alpha (float): Multiplier to control saturation and value scale
    """
    tissue_thickness_scale_factor = target_tissue_thickness - domain_tissue_thickness
    image_hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV).astype(np.float32)
    image_hsv[:, :, 1] *= 1 + alpha * tissue_thickness_scale_factor
    image_hsv[:, :, 2] *= 1 - alpha * tissue_thickness_scale_factor
    image_hsv = image_hsv.astype(np.uint8)
    image_scaled = cv2.cvtColor(image_hsv, cv2.COLOR_HSV2RGB)
    image_scaled = staintools.LuminosityStandardizer.standardize(image_scaled)
    pixel_size_scale_factor = domain_pixel_size / target_pixel_size
    image_resized = cv2.resize(image_scaled, dsize=None, fx=pixel_size_scale_factor, fy=pixel_size_scale_factor, interpolation=cv2.INTER_CUBIC)
    image_resized = cv2.resize(image_resized, dsize=(image.shape[1], image.shape[0]), interpolation=cv2.INTER_CUBIC)
    image = staintools.LuminosityStandardizer.standardize(image)
    image_augmented = staintools.LuminosityStandardizer.standardize(image_resized)
    image_augmented = normalizer.transform(image_augmented)
    return (image, image_augmented)

df_train = pd.read_csv(MASKS)
df_masks = df_train.reset_index(drop=True)
for idx, row in df_masks.iterrows():
    image = cv2.imread(os.path.join(DATA, str(row['id']) + '.tiff'))
    image, image_augmented = augment_image(image=image, domain_pixel_size=imaging_measurements['hpa']['pixel_size'][row['organ']], target_pixel_size=imaging_measurements['hubmap']['pixel_size'][row['organ']], domain_tissue_thickness=imaging_measurements['hpa']['tissue_thickness'][row['organ']], target_tissue_thickness=imaging_measurements['hubmap']['tissue_thickness'][row['organ']], alpha=0.15)
    rimage = cv2.resize(image_augmented, (1024, 1024), interpolation=cv2.INTER_LINEAR)
    cv2.imwrite(os.path.join(OUT_TRAIN, str(row['id']) + '.png'), rimage)

def visualize_augmentation(image, image_augmented, metadata, path=None):

    """
    Visualize raw and augmented images 
    
    Parameters
    ----------
    image (numpy.ndarray of shape (height, width, 3)): Raw image array
    image_augmented (numpy.ndarray of shape (height, width, 3)): Augmented image array
    metadata (dict): Dictionary of image metadata
    path (path-like str or None): Path of the output file or None (if path is None, plot is displayed with selected backend)
    """

    fig, axes = plt.subplots(figsize=(36, 20), ncols=2)
    
    axes[0].imshow(image)
    axes[1].imshow(image_augmented)

    for i in range(2):
        axes[i].set_xlabel('')
        axes[i].set_ylabel('')
        axes[i].tick_params(axis='x', labelsize=15, pad=10)
        axes[i].tick_params(axis='y', labelsize=15, pad=10)

    axes[0].set_title(f'Raw Image\nMean: {np.mean(image):.4f} - Std: {np.std(image):.4f} - Min: {np.min(image)} - Max: {np.max(image)}', size=25, pad=15)
    axes[1].set_title(f'Augmented Image\nMean: {np.mean(image_augmented):.4f} - Std: {np.std(image_augmented):.4f} - Min: {np.min(image_augmented)} - Max: {np.max(image_augmented)}', size=25, pad=15)

    fig.suptitle(
        f'''
        Image ID {metadata["id"]} - {metadata["organ"]} - {metadata["data_source"]} - {metadata["age"]} - {metadata["sex"]}
        Raw Image Shape: {metadata["img_height"]}x{metadata["img_width"]} - Pixel Size: {metadata["pixel_size"]}µm - Tissue Thickness: {metadata["tissue_thickness"]}µm
        Augmented Image Shape: {metadata["img_height"]}x{metadata["img_width"]} - Pixel Size: {imaging_measurements["hubmap"]["pixel_size"][metadata["organ"]]}µm - Tissue Thickness: {imaging_measurements["hubmap"]["tissue_thickness"][metadata["organ"]]}µm
        ''',
        fontsize=50,
        y=1.05
    )

    if path is None:
        plt.show()
    else:
        plt.savefig(path)
        plt.close(fig)

visualize_augmentation(image=image, image_augmented=image_augmented, metadata=row.to_dict())