File size: 4,472 Bytes
5db43ff
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import cv2
import numpy as np
import torch


def blur_image_by_mask(image, mask, kernel_size=23):
    mask=mask.astype(np.uint8)


    # 对图像和掩码进行位与运算,得到只有目标区域的图像
    masked = image.copy()#cv2.bitwise_and(image, image, mask=mask)

    # 对这个图像进行高斯模糊
    blurred = cv2.GaussianBlur(masked, (kernel_size, kernel_size), 0)

    # 用位或运算将模糊后的图像和原图像合并
    #final = cv2.bitwise_or(image, blurred)
    final = image.copy()
    final[mask>0] = blurred[mask>0]
    return final

def blur_image(image, center, radius):
    # 创建一个和图像大小相同的掩码
    mask = np.zeros(image.shape[:2], dtype="uint8")
    center = center.astype(int)

    # 在掩码上画出想要模糊的区域,例如一个圆形
    #cv2.circle(mask, (center[0], center[1]), int(radius), 255, -1)
    cv2.ellipse(mask, (center[0], center[1]), (int(radius), int(radius*1.5)), 0,0,360, 255, -1)


    # 对图像和掩码进行位与运算,得到只有目标区域的图像
    masked = image.copy()#cv2.bitwise_and(image, image, mask=mask)

    # 对这个图像进行高斯模糊
    blurred = cv2.GaussianBlur(masked, (23, 23), 0)

    # 用位或运算将模糊后的图像和原图像合并
    #final = cv2.bitwise_or(image, blurred)
    final = image.copy()
    final[mask>0] = blurred[mask>0]
    return final

import torchvision.transforms as transforms

def poisson_blend_np(src:np.ndarray,dst:np.ndarray,mask:np.ndarray)->np.ndarray:
    """
        * inputs:
            - input (numpy array, required) shape = (H, W, 3).
            - target (numpy array, required) shape = (H, W, 3).

            - mask (np.bool, required) shape = (H, W).
                    Input mask tensor of Completion Network, whose shape = (N, 1, H, W).
        * returns:
                    Output image numpy of shape (H, W, 3) inpainted with poisson image editing method.
        """
    mask=np.expand_dims(mask,2)
    mask=(np.concatenate([mask,mask,mask],2)*255).astype(np.uint8)
    dstimg = dst
    srcimg = src
    msk=mask
    # compute mask's center
    xs, ys = [], []
    for j in range(msk.shape[0]):
        for k in range(msk.shape[1]):
            if msk[j, k, 0] == 255:
                ys.append(j)
                xs.append(k)
    xmin, xmax = min(xs), max(xs)
    ymin, ymax = min(ys), max(ys)
    center = ((xmax + xmin) // 2, (ymax + ymin) // 2)
    dstimg = cv2.inpaint(dstimg, msk[:, :, 0], 1, cv2.INPAINT_TELEA)
    out = cv2.seamlessClone(srcimg, dstimg, msk, center, cv2.NORMAL_CLONE)
    return out



def poisson_blend(input, output, mask):
    """
    * inputs:
        - input (torch.Tensor, required)
                Input tensor of Completion Network, whose shape = (N, 3, H, W).
        - output (torch.Tensor, required)
                Output tensor of Completion Network, whose shape = (N, 3, H, W).
        - mask (torch.Tensor, required)
                Input mask tensor of Completion Network, whose shape = (N, 1, H, W).
    * returns:
                Output image tensor of shape (N, 3, H, W) inpainted with poisson image editing method.
    """
    input = input.clone().cpu()
    output = output.clone().cpu()
    mask = mask.clone().cpu()
    mask = torch.cat((mask, mask, mask), dim=1)  # convert to 3-channel format
    num_samples = input.shape[0]
    ret = []
    for i in range(num_samples):
        dstimg = transforms.functional.to_pil_image(input[i])
        dstimg = np.array(dstimg)[:, :, [2, 1, 0]]
        srcimg = transforms.functional.to_pil_image(output[i])
        srcimg = np.array(srcimg)[:, :, [2, 1, 0]]
        msk = transforms.functional.to_pil_image(mask[i])
        msk = np.array(msk)[:, :, [2, 1, 0]]
        # compute mask's center
        xs, ys = [], []
        for j in range(msk.shape[0]):
            for k in range(msk.shape[1]):
                if msk[j, k, 0] == 255:
                    ys.append(j)
                    xs.append(k)
        xmin, xmax = min(xs), max(xs)
        ymin, ymax = min(ys), max(ys)
        center = ((xmax + xmin) // 2, (ymax + ymin) // 2)
        dstimg = cv2.inpaint(dstimg, msk[:, :, 0], 1, cv2.INPAINT_TELEA)
        out = cv2.seamlessClone(srcimg, dstimg, msk, center, cv2.NORMAL_CLONE)
        out = out[:, :, [2, 1, 0]]
        out = transforms.functional.to_tensor(out)
        out = torch.unsqueeze(out, dim=0)
        ret.append(out)
    ret = torch.cat(ret, dim=0)
    return ret