Untitled
unknown
plain_text
a year ago
8.2 kB
13
Indexable
#######################################################################
# Part 1 - numpy
def get_highest_weight_loss_participant(training_data, participant_names):
"""
:param training_data: a numpy matrix of shape (n_participants, n_months) .
:param participant_names: a list of strings, each string represents a participant.
:return: the highest weight loss participant's name.
"""
diff = training_data[:,0] - training_data[:,-1]
return participant_names[np.argmax(np.abs(diff))]
def get_diff_data(training_data):
"""
:param training_data: a numpy matrix of shape (n_participants, n_months).
:return: a numpy matrix of shape (n_participants, n_months-1) representing the difference between each pair of consecutive months.
"""
return training_data[:, 1:] - training_data[:, :-1]
def get_highest_change_month(training_data, study_months):
"""
:param training_data: a numpy matrix of shape (n_participants, n_months).
:param study_months: a list of strings, each string represents a month in the study.
:return: the month with the highest change across participants.
"""
diff = np.abs(training_data[:, 1:] - training_data[:, :-1])
total_changes = np.sum(diff, axis=0)
return study_months[np.argmax(total_changes)]
def get_inconsistent_participants(training_data, participant_names):
"""
:param training_data: a numpy matrix of shape (n_participants, n_months).
:param participant_names: a list of strings, each string represents a participant.
:return: a list of participant names that didn't lose weight consistently every month throughout the study.
If there are no such participants, the function will return an empty list.
"""
diff = get_diff_data(training_data)
pos = np.any(diff >= 0, axis=1)
return list(np.array(participant_names)[pos])
#######################################################################
# Part 2 - numpy image processing
def read_image(img_path, mode='L'):
"""
:param img_path: path of an image to read
:param mode: (for bonus) the mode of the image to be read, 'L' for grayscale (default), 'RGB' for RGB.
:return: a uint8 numpy array representing the image, with values between 0 and 255.
will return an array shaped (h,w) (bonus: if mode == 'L', or (h,w,3) if mode == 'RGB'.)
"""
read_img = imread(img_path, mode=mode)
if read_img.dtype != np.uint8:
read_img = read_img.astype(np.uint8)
return read_img
def naive_blending(img1, img2, mask):
"""
:param img1: a uint8 numpy array representing an image
:param img2: a uint8 numpy array representing an image
:param mask: a uint8 numpy array representing a boolean image in equal size of im1 and im2, that defines how the two images should be blended.
:return: a blended image where img_1 pixels are used for the white areas of the mask, and img_2 pixels are used for the black areas.
"""
n_msk = mask / 255
blend = img1 * n_msk + img2* (1- n_msk)
return blend.astype(np.uint8)
def get_nbhd(img, x, y, nb_size):
return img[max(x-nb_size,0):min(x+nb_size+1,img.shape[0]), max(y-nb_size,0):min(y+nb_size+1,img.shape[1])]
def blur(img, nb_size):
blurry_img = np.zeros_like(img, dtype=np.uint8)
for i in range (img.shape[0]):
for j in range (img.shape[1]):
blurry_img[i,j] = np.mean(get_nbhd(img, i, j, nb_size))
return blurry_img.astype(np.uint8)
def blur_and_downsample(img, nb_size=5):
"""
A function that blurs the given image, and then reduces its resolution by 2 (both width and length) by choosing
every second pixel in every second row.
:param img: a uint8 numpy array representing an image
:param nb_size: The neighborhood size to be used for blurring
:return: the reduced and blurred image
"""
blurry_img_n = blur(img, nb_size)
blurry_img_n = blurry_img_n[::2, ::2]
return blurry_img_n
def build_gaussian_pyramid(img, max_levels, nb_size=5):
"""
A function that builds a gaussian pyramid of the given image, by sequentially blurring and down-sampling the current
image until reaching max_levels.
:param img: a uint8 numpy array representing an image.
:param max_levels: The maximal depth levels that should be constructed.
:param nb_size: The neighborhood size to be used for blurring.
:return: a list representing the image's gaussian pyramid, each entry is the previous image down-sampled to half the
resolution of the previous one.
"""
pyramid = [img]
for i in range(1, max_levels):
prev_func = blur_and_downsample(pyramid[-1], nb_size)
if prev_func.shape[0] < 2 or prev_func.shape[1] < 2:
break
pyramid.append(prev_func)
return pyramid
def upsample_and_blur(img, nb_size=5):
"""
A function that doubles the size of the given image, and blurs it.
:param img: a uint8 numpy array representing an image.
:param nb_size: The neighborhood size to be used for blurring.
:return: a numpy array representing the expanded blurred image.
"""
new_row_col = np.repeat(np.repeat(img, 2, axis = 0), 2 ,axis = 1)
return blur(new_row_col, nb_size = 5)
def build_laplacian_pyramid(img, max_levels, nb_size=5):
"""
A function that builds a laplacian pyramid of the given image, by sequentially up-sampling the next level gaussian
image and subtracting it from the current level gaussian image, until reaching max_levels.
:param img: a uint8 numpy array representing an image.
:param max_levels: The maximal depth levels that should be constructed
:param nb_size: The neighborhood size to be used for blurring.
:return: a list representing a laplacian pyramid of the given image.
"""
pyramid = build_gaussian_pyramid(img, max_levels, nb_size)
laplacian = []
for i in range(len(pyramid) - 1):
upsampled = upsample_and_blur(pyramid[i + 1], nb_size)
if upsampled.shape != pyramid[i].shape:
upsampled = upsampled[:pyramid[i].shape[0], :pyramid[i].shape[1]]
laplacian.append(pyramid[i] - upsampled)
laplacian.append(pyramid[-1])
return laplacian
def laplacian_pyramid_to_image(laplacian_pyramid, nb_size=5):
"""
A function that reconstructs an image from the given laplacian pyramid, by iteratively combining all laplacian
images after up-sampling.
:param laplacian_pyramid: a list representing a laplacian pyramid.
:param nb_size: The neighborhood size to be used for blurring.
:return: The reconstructed image.
"""
reverse_img = laplacian_pyramid[-1]
for i in range(len(laplacian_pyramid)-2, -1, -1):
upsampled = upsample_and_blur(reverse_img, nb_size)
upsampled = upsampled[:upsampled.shape[0], :upsampled.shape[1]]
reverse_img = laplacian_pyramid[i] + upsampled
return reverse_img
def pyramid_blending(img1, img2, mask, max_levels, nb_size=5):
"""
A function that blends two images using pyramids.
:param img1: a uint8 numpy array representing a grayscale image that will compose the white parts of the mask.
:param img2: a uint8 numpy array representing a grayscale image that will compose the black parts of the mask.
:param mask: a uint8 numpy array representing a boolean image in equal size of im1 and im2, that defines how the two images should be blended
:param max_levels: The max depth of the pyramids used in this function
:param nb_size: The neighborhood size to be used for blurring.
:return: The blended image
"""
img11 = build_laplacian_pyramid(img1,max_levels, nb_size)
img22 = build_laplacian_pyramid(img2,max_levels, nb_size)
maskk = build_gaussian_pyramid(mask, max_levels, nb_size)
for i in range(len(maskk)):
for row in range(maskk[i].shape[0]):
for col in range(maskk[i].shape[1]):
if maskk[i][row][col] != 0:
maskk[i][row][col] = 255
new_pyramid = []
for i in range(max_levels):
blender = naive_blending(img11[i], img22[i], maskk[i])
new_pyramid.append(blender)
final_image = laplacian_pyramid_to_image(new_pyramid, nb_size)
return final_image
Editor is loading...
Leave a Comment