Rakhi-2025's picture
Upload 95 files
911c613 verified
# ------------------------------------------------------------ #
#
# file : utils/learning/patch/extraction.py
# author : CM
# Function to extract patch from input dataset
#
# ------------------------------------------------------------ #
import sys
from random import randint
import numpy as np
from keras.utils import to_categorical
# ----- Patch Extraction -----
# -- Single Patch
# exctract a patch from an image
def extractPatch(d, patch_size_x, patch_size_y, patch_size_z, x, y, z):
patch = d[x:x+patch_size_x,y:y+patch_size_y,z:z+patch_size_z]
return patch
# extract a patch from an image. The patch can be out of the image (0 padding)
def extractPatchOut(d, patch_size_x, patch_size_y, patch_size_z, x_, y_, z_):
patch = np.zeros((patch_size_x, patch_size_y, patch_size_z), dtype='float16')
for x in range(0,patch_size_x):
for y in range(0, patch_size_y):
for z in range(0, patch_size_z):
if(x+x_ >= 0 and x+x_ < d.shape[0] and y+y_ >= 0 and y+y_ < d.shape[1] and z+z_ >= 0 and z+z_ < d.shape[2]):
patch[x,y,z] = d[x+x_,y+y_,z+z_]
return patch
# create random patch for an image
def generateRandomPatch(d, patch_size_x, patch_size_y, patch_size_z):
x = randint(0, d.shape[0]-patch_size_x)
y = randint(0, d.shape[1]-patch_size_y)
z = randint(0, d.shape[2]-patch_size_z)
data = extractPatch(d, patch_size_x, patch_size_y, patch_size_z, x, y, z)
return data
# -- Multiple Patchs
# create random patchs for an image
def generateRandomPatchs(d, patch_size_x, patch_size_y, patch_size_z, patch_number):
# max_patch_nb = (d.shape[0]-patch_size_x)*(d.shape[1]-patch_size_y)*(d.shape[2]-patch_size_z)
data = np.empty((patch_number, patch_size_x, patch_size_y, patch_size_z), dtype='float16')
for i in range(0,patch_number):
data[i] = generateRandomPatch(d, patch_size_x, patch_size_y, patch_size_z)
return data
# divide the full image into patchs
# todo : missing data if shape%patch_size is not 0
def generateFullPatchs(d, patch_size_x, patch_size_y, patch_size_z):
patch_nb = int((d.shape[0]/patch_size_x)*(d.shape[1]/patch_size_y)*(d.shape[2]/patch_size_z))
data = np.empty((patch_nb, patch_size_x, patch_size_y, patch_size_z), dtype='float16')
i = 0
for x in range(0,d.shape[0], patch_size_x):
for y in range(0, d.shape[1], patch_size_y):
for z in range(0,d.shape[2], patch_size_z):
data[i] = extractPatch(d, patch_size_x, patch_size_y, patch_size_z, x, y, z)
i = i+1
return data
def generateFullPatchsPlus(d, patch_size_x, patch_size_y, patch_size_z, dx, dy, dz):
patch_nb = int((d.shape[0]/dx)*(d.shape[1]/dy)*(d.shape[2]/dz))
data = np.empty((patch_nb, patch_size_x, patch_size_y, patch_size_z), dtype='float16')
i = 0
for x in range(0,d.shape[0]-dx, dx):
for y in range(0, d.shape[1]-dy, dy):
for z in range(0,d.shape[2]-dz, dz):
data[i] = extractPatch(d, patch_size_x, patch_size_y, patch_size_z, x, y, z)
i = i+1
return data
def noNeg(x):
if(x>0):
return x
else:
return 0
def generateFullPatchsCentered(d, patch_size_x, patch_size_y, patch_size_z):
patch_nb = int(2*(d.shape[0]/patch_size_x)*2*(d.shape[1]/patch_size_y)*2*(d.shape[2]/patch_size_z))
data = np.zeros((patch_nb, patch_size_x, patch_size_y, patch_size_z), dtype='float16')
i = 0
psx = int(patch_size_x/2)
psy = int(patch_size_y/2)
psz = int(patch_size_z/2)
for x in range(-int(patch_size_x/4),d.shape[0]-3*int(patch_size_x/4)+1, psx):
for y in range(-int(patch_size_y/4), d.shape[1]-3*int(patch_size_y/4)+1, psy):
for z in range(-int(patch_size_z/4),d.shape[2]-3*int(patch_size_z/4)+1, psz):
# patch = np.zeros((psx,psy,psz), dtype='float16')
# patch = d[noNeg(x):noNeg(x)+patch_size_x,noNeg(y):noNeg(y)+patch_size_y,noNeg(z):noNeg(z)+patch_size_z]
patch = extractPatchOut(d,patch_size_x, patch_size_y, patch_size_z, x, y, z)
data[i] = patch
i = i+1
return data
# ----- Patch Extraction Generator -----
# Generator of random patchs of size 32*32*32
def generatorRandomPatchs(features, labels, batch_size, patch_size_x, patch_size_y, patch_size_z):
batch_features = np.zeros((batch_size, patch_size_x, patch_size_y, patch_size_z, features.shape[4]), dtype='float16')
batch_labels = np.zeros((batch_size, patch_size_x, patch_size_y, patch_size_z, labels.shape[4]), dtype='float16')
while True:
for i in range(batch_size):
id = randint(0,features.shape[0]-1)
x = randint(0, features.shape[1]-patch_size_x)
y = randint(0, features.shape[2]-patch_size_y)
z = randint(0, features.shape[3]-patch_size_z)
batch_features[i] = extractPatch(features[id], patch_size_x, patch_size_y, patch_size_z, x, y, z)
batch_labels[i] = extractPatch(labels[id], patch_size_x, patch_size_y, patch_size_z, x, y, z)
yield batch_features, batch_labels
# Generator of random patchs of size 32*32*32 and 16*16*16
def generatorRandomPatchs3216(features, labels, batch_size):
batch_features = np.zeros((batch_size, 32, 32, 32, features.shape[4]), dtype='float16')
batch_labels = np.zeros((batch_size, 16, 16, 16, labels.shape[4]), dtype='float16')
while True:
for i in range(batch_size):
id = randint(0,features.shape[0]-1)
x = randint(0, features.shape[1]-32)
y = randint(0, features.shape[2]-32)
z = randint(0, features.shape[3]-32)
batch_features[i] = extractPatch(features[id], 32, 32, 32, x, y, z)
batch_labels[i] = extractPatch(labels[id], 16, 16, 16, x+16, y+16, z+16)
yield batch_features, batch_labels
def generatorRandomPatchsLabelCentered(features, labels, batch_size, patch_size_x, patch_size_y, patch_size_z):
patch_centered_size_x = int(patch_size_x/2)
patch_centered_size_y = int(patch_size_y/2)
patch_centered_size_z = int(patch_size_z/2)
batch_features = np.zeros((batch_size, patch_size_x, patch_size_y, patch_size_z, features.shape[4]), dtype=features.dtype)
batch_labels = np.zeros((batch_size, patch_centered_size_x, patch_centered_size_y, patch_centered_size_z,
labels.shape[4]), dtype=labels.dtype)
while True:
for i in range(batch_size):
id = randint(0,features.shape[0]-1)
x = randint(0, features.shape[1]-patch_size_x)
y = randint(0, features.shape[2]-patch_size_y)
z = randint(0, features.shape[3]-patch_size_z)
batch_features[i] = extractPatch(features[id], patch_size_x, patch_size_y, patch_size_z, x, y, z)
batch_labels[i] = extractPatch(labels[id], patch_centered_size_x, patch_centered_size_y, patch_centered_size_z,
int(x+patch_size_x/4), int(y+patch_size_y/4), int(z+patch_size_z/4))
yield batch_features, batch_labels
def generatorRandomPatchsDolz(features, labels, batch_size, patch_size_x, patch_size_y, patch_size_z):
batch_features = np.zeros((batch_size, patch_size_x, patch_size_y, patch_size_z, features.shape[4]), dtype=features.dtype)
batch_labels = np.zeros((batch_size, int(patch_size_x / 2) * int(patch_size_y / 2) * int(patch_size_z / 2), 2), dtype=labels.dtype)
while True:
for i in range(batch_size):
id = randint(0,features.shape[0]-1)
x = randint(0, features.shape[1]-patch_size_x)
y = randint(0, features.shape[2]-patch_size_y)
z = randint(0, features.shape[3]-patch_size_z)
batch_features[i] = extractPatch(features[id], patch_size_x, patch_size_y, patch_size_z, x, y, z)
tmpPatch = extractPatch(labels[id], int(patch_size_x/2), int(patch_size_y/2), int(patch_size_z/2),
int(x+patch_size_x/4), int(y+patch_size_y/4), int(z+patch_size_z/4))
batch_labels[i] = to_categorical(tmpPatch.flatten(),2)
"""
count = 0
for x in range(0, tmpPatch.shape[0]):
for y in range(0, tmpPatch.shape[1]):
for z in range(0, tmpPatch.shape[2]):
if(tmpPatch[x,y,z,0] == 1):
batch_labels[i,count,1] = 1
else:
batch_labels[i,count,0] = 1
count += 1
"""
yield batch_features, batch_labels
from scipy.ndimage import zoom, rotate
# Generate random patchs with random linear transformation
# translation (random position) rotation, scale
# Preconditions : patch_features_ % patch_labels_ = 0
# patch_features_ >= patch_labels_
# todo : scale
def generatorRandomPatchsLinear(features, labels, patch_features_x, patch_features_y, patch_features_z,
patch_labels_x, patch_labels_y, patch_labels_z):
patch_features = np.zeros((1, patch_features_x, patch_features_y, patch_features_z, features.shape[4]), dtype=features.dtype)
patch_labels = np.zeros((1, patch_labels_x, patch_labels_y, patch_labels_z, labels.shape[4]), dtype=labels.dtype)
if(patch_features_x % patch_labels_x != 0 or patch_features_y % patch_labels_y != 0 or patch_features_z % patch_labels_z != 0):
sys.exit(0x00F0)
if(patch_features_x < patch_labels_x or patch_features_y < patch_labels_y or patch_features_z < patch_labels_z):
sys.exit(0x00F1)
# middle of patch
mx = int(patch_features_x/2)
my = int(patch_features_y/2)
mz = int(patch_features_z/2)
# patch label size/2
sx = int(patch_labels_x / 2)
sy = int(patch_labels_y / 2)
sz = int(patch_labels_z / 2)
while True:
id = randint(0, features.shape[0]-1)
x = randint(0, features.shape[1]-patch_features_x)
y = randint(0, features.shape[2]-patch_features_y)
z = randint(0, features.shape[3]-patch_features_z)
# todo : check time consumtion and rotation directly on complete image
r0 = randint(0, 360)-180
r1 = randint(0, 360)-180
r2 = randint(0, 360)-180
rot_features = rotate(input=features[0], angle=r0, axes=(0, 1), reshape=False)
rot_features = rotate(input=rot_features, angle=r1, axes=(1, 2), reshape=False)
rot_features = rotate(input=rot_features, angle=r2, axes=(2, 0), reshape=False)
rot_labels = rotate(input=labels[0], angle=r0, axes=(0, 1), reshape=False)
rot_labels = rotate(input=rot_labels, angle=r1, axes=(1, 2), reshape=False)
rot_labels = rotate(input=rot_labels, angle=r2, axes=(2, 0), reshape=False)
patch_features[0] = extractPatch(rot_features, patch_features_x, patch_features_y, patch_features_z, x, y, z)
patch_labels[0] = extractPatch(rot_labels, patch_labels_x, patch_labels_y, patch_labels_z,
x + mx - sx, y + my - sy, z + mz - sz)
yield patch_features, patch_labels
def randomPatchsAugmented(in_dataset, gd_dataset, patch_number, patch_in_size, patch_gd_size):
patchs_in = np.zeros((patch_number, patch_in_size[0], patch_in_size[1], patch_in_size[2]), dtype=in_dataset.dtype)
patchs_gd = np.zeros((patch_number, patch_gd_size[0], patch_gd_size[1], patch_gd_size[2]), dtype=gd_dataset.dtype)
if(patch_in_size[0] % patch_gd_size[0] != 0 or patch_in_size[1] % patch_gd_size[1] != 0 or patch_in_size[2] % patch_gd_size[2] != 0):
sys.exit("ERROR : randomPatchsAugmented patchs size error 1")
if(patch_in_size[0] < patch_gd_size[0] or patch_in_size[1] < patch_gd_size[1] or patch_in_size[2] < patch_gd_size[2]):
sys.exit("ERROR : randomPatchsAugmented patchs size error 2")
# middle of patch
mx = int(patch_in_size[0] / 2)
my = int(patch_in_size[1] / 2)
mz = int(patch_in_size[2] / 2)
# patch label size/2
sx = int(patch_gd_size[0] / 2)
sy = int(patch_gd_size[1] / 2)
sz = int(patch_gd_size[2] / 2)
for count in range(patch_number):
id = randint(0, in_dataset.shape[0]-1)
x = randint(0, in_dataset.shape[1]-patch_in_size[0])
y = randint(0, in_dataset.shape[2]-patch_in_size[1])
z = randint(0, in_dataset.shape[3]-patch_in_size[2])
r0 = randint(0, 3)
r1 = randint(0, 3)
r2 = randint(0, 3)
patchs_in[count] = extractPatch(in_dataset[id], patch_in_size[0], patch_in_size[1], patch_in_size[2], x, y, z)
patchs_gd[count] = extractPatch(gd_dataset[id], patch_gd_size[0], patch_gd_size[1], patch_gd_size[2], x + mx - sx, y + my - sy, z + mz - sz)
patchs_in[count] = np.rot90(patchs_in[count], r0, (0, 1))
patchs_in[count] = np.rot90(patchs_in[count], r1, (1, 2))
patchs_in[count] = np.rot90(patchs_in[count], r2, (2, 0))
patchs_gd[count] = np.rot90(patchs_gd[count], r0, (0, 1))
patchs_gd[count] = np.rot90(patchs_gd[count], r1, (1, 2))
patchs_gd[count] = np.rot90(patchs_gd[count], r2, (2, 0))
return patchs_in.reshape(patchs_in.shape[0], patchs_in.shape[1], patchs_in.shape[2], patchs_in.shape[3], 1),\
patchs_gd.reshape(patchs_gd.shape[0], patchs_gd.shape[1], patchs_gd.shape[2], patchs_gd.shape[3], 1)
def generatorRandomPatchsAugmented(in_dataset, gd_dataset, patch_number, patch_in_size, patch_gd_size):
while True:
yield randomPatchsAugmented(in_dataset, gd_dataset, patch_number, patch_in_size, patch_gd_size)