Spaces:
Runtime error
Runtime error
File size: 4,439 Bytes
1a79cb6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
import cv2
import numpy as np
import scipy.sparse
def mask_from_points(size, points):
""" Create a mask of supplied size from supplied points
:param size: tuple of output mask size
:param points: array of [x, y] points
:returns: mask of values 0 and 255 where
255 indicates the convex hull containing the points
"""
radius = 10 # kernel size
kernel = np.ones((radius, radius), np.uint8)
mask = np.zeros(size, np.uint8)
cv2.fillConvexPoly(mask, cv2.convexHull(points), 255)
mask = cv2.erode(mask, kernel)
return mask
def overlay_image(foreground_image, mask, background_image):
""" Overlay foreground image onto the background given a mask
:param foreground_image: foreground image points
:param mask: [0-255] values in mask
:param background_image: background image points
:returns: image with foreground where mask > 0 overlaid on background image
"""
foreground_pixels = mask > 0
background_image[..., :3][foreground_pixels] = foreground_image[..., :3][foreground_pixels]
return background_image
def apply_mask(img, mask):
""" Apply mask to supplied image
:param img: max 3 channel image
:param mask: [0-255] values in mask
:returns: new image with mask applied
"""
masked_img = np.copy(img)
num_channels = 3
for c in range(num_channels):
masked_img[..., c] = img[..., c] * (mask / 255)
return masked_img
def weighted_average(img1, img2, percent=0.5):
if percent <= 0:
return img2
elif percent >= 1:
return img1
else:
return cv2.addWeighted(img1, percent, img2, 1-percent, 0)
def alpha_feathering(src_img, dest_img, img_mask, blur_radius=15):
mask = cv2.blur(img_mask, (blur_radius, blur_radius))
mask = mask / 255.0
result_img = np.empty(src_img.shape, np.uint8)
for i in range(3):
result_img[..., i] = src_img[..., i] * mask + dest_img[..., i] * (1-mask)
return result_img
def poisson_blend(img_source, dest_img, img_mask, offset=(0, 0)):
# http://opencv.jp/opencv2-x-samples/poisson-blending
img_target = np.copy(dest_img)
import pyamg
# compute regions to be blended
region_source = (
max(-offset[0], 0),
max(-offset[1], 0),
min(img_target.shape[0] - offset[0], img_source.shape[0]),
min(img_target.shape[1] - offset[1], img_source.shape[1]))
region_target = (
max(offset[0], 0),
max(offset[1], 0),
min(img_target.shape[0], img_source.shape[0] + offset[0]),
min(img_target.shape[1], img_source.shape[1] + offset[1]))
region_size = (region_source[2] - region_source[0],
region_source[3] - region_source[1])
# clip and normalize mask image
img_mask = img_mask[region_source[0]:region_source[2],
region_source[1]:region_source[3]]
# create coefficient matrix
coff_mat = scipy.sparse.identity(np.prod(region_size), format='lil')
for y in range(region_size[0]):
for x in range(region_size[1]):
if img_mask[y, x]:
index = x + y * region_size[1]
coff_mat[index, index] = 4
if index + 1 < np.prod(region_size):
coff_mat[index, index + 1] = -1
if index - 1 >= 0:
coff_mat[index, index - 1] = -1
if index + region_size[1] < np.prod(region_size):
coff_mat[index, index + region_size[1]] = -1
if index - region_size[1] >= 0:
coff_mat[index, index - region_size[1]] = -1
coff_mat = coff_mat.tocsr()
# create poisson matrix for b
poisson_mat = pyamg.gallery.poisson(img_mask.shape)
# for each layer (ex. RGB)
for num_layer in range(img_target.shape[2]):
# get subimages
t = img_target[region_target[0]:region_target[2],
region_target[1]:region_target[3], num_layer]
s = img_source[region_source[0]:region_source[2],
region_source[1]:region_source[3], num_layer]
t = t.flatten()
s = s.flatten()
# create b
b = poisson_mat * s
for y in range(region_size[0]):
for x in range(region_size[1]):
if not img_mask[y, x]:
index = x + y * region_size[1]
b[index] = t[index]
# solve Ax = b
x = pyamg.solve(coff_mat, b, verb=False, tol=1e-10)
# assign x to target image
x = np.reshape(x, region_size)
x[x > 255] = 255
x[x < 0] = 0
x = np.array(x, img_target.dtype)
img_target[region_target[0]:region_target[2],
region_target[1]:region_target[3], num_layer] = x
return img_target
|