File size: 4,848 Bytes
3dacec1
 
 
e4fb230
3dacec1
 
e4fb230
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3dacec1
 
 
 
 
 
 
 
 
 
 
 
 
e4fb230
2578b1e
3dacec1
 
 
 
e4e8de7
 
79c6687
3dacec1
e4fb230
3dacec1
 
 
 
 
5e8f5b8
76e529a
 
 
 
 
5e8f5b8
3dacec1
 
5e8f5b8
 
76e529a
79c6687
76e529a
79c6687
76e529a
5e8f5b8
 
 
3dacec1
 
 
8d43198
3dacec1
 
 
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
import numpy as np
import gradio as gr
from segmentation import get_mask,replace_sofa
from styleTransfer import create_styledSofa
from PIL import Image

def resize_sofa(img):
    """
    This function adds padding to make the orignal image square and 640by640.
    It also returns the orignal ratio of the image, such that it can be reverted later.
    Parameters:
        img = original image
    Return:
        im1 = squared image
        box = parameters to later crop the image to it original ratio
    """
    width, height = img.size 
    idx = np.argmin([width,height])
    newsize = (640, 640) # parameters from test script

    if idx==0:
        img1 = Image.new(img.mode, (height, height), (255, 255, 255))
        img1.paste(img, ((height-width)//2, 0))
        box = ( newsize[0]*(1-width/height)//2,
                0, 
                newsize[0]-newsize[0]*(1-width/height)//2,
                newsize[1])
    else:
        img1 = Image.new(img.mode, (width, width), (255, 255, 255))
        img1.paste(img, (0, (width-height)//2)) 
        box = (0, 
                newsize[1]*(1-height/width)//2, 
                newsize[0], 
                newsize[1]-newsize[1]*(1-height/width)//2)
    im1 = img1.resize(newsize)
    return im1,box

def resize_style(img):
    """
    This function generates a zoomed out version of the style image and resizes it to a 640by640 square.
    Parameters:
        img = image containing the style/pattern
    Return:
        dst = a zoomed-out and resized version of the pattern
    """
    width, height = img.size
    idx = np.argmin([width,height])

    # Makes the image square by cropping
    if idx==0:
        top= (height-width)//2
        bottom= height-(height-width)//2
        left = 0
        right= width
    else:
        left = (width-height)//2
        right = width - (width-height)//2
        top = 0
        bottom = height
    newsize = (640, 640) # parameters from test script
    im1 = img.crop((left, top, right, bottom))

    # Constructs a zoomed-out version
    copies = 8
    resize = (newsize[0]//copies,newsize[1]//copies)
    dst = Image.new('RGB', (resize[0]*copies,resize[1]*copies))
    im2 = im1.resize((resize))
    for row in range(copies):
        im2 = im2.transpose(Image.FLIP_LEFT_RIGHT)
        for column in range(copies):
            im2 = im2.transpose(Image.FLIP_TOP_BOTTOM)
            dst.paste(im2, (resize[0]*row, resize[1]*column))
    dst = dst.resize((newsize))
    return dst

def style_sofa(input_img: np.ndarray, style_img: np.ndarray):
    """
    Styles (all) the sofas in the image to the given style.
    This function uses a transformer to combine the image with the desired style according 
    to a generated mask of the sofas in the image.
    Input:
        input_img = image containing a sofa
        style_img = image containing a style
    Return:
        new_sofa  = image containing the styled sofa
    """
    
    # preprocess input images to be (640,640) squares to fit requirements of the segmentation model
    input_img,style_img = Image.fromarray(input_img),Image.fromarray(style_img)
    resized_img,box = resize_sofa(input_img)
    resized_style = resize_style(style_img)
    # generate mask for image
    mask = get_mask(resized_img)
    styled_sofa = create_styledSofa(resized_img,resized_style)
    print(type(styled_sofa))
    print(styled_sofa.shape)
    # postprocess the final image
    new_sofa = replace_sofa(resized_img,mask,styled_sofa)
    new_sofa = new_sofa.crop(box)
    return new_sofa

image = gr.inputs.Image()
style = gr.inputs.Image()

# Examples
example1 = ['sofa_example1.jpg','style_example1.jpg']
example2 = ['sofa_example1.jpg','style_example2.jpg']
example3 = ['sofa_example1.jpg','style_example3.jpg']
example4 = ['sofa_example1.jpg','style_example4.jpg']
example5 = ['sofa_example1.jpg','style_example5.jpg']

demo = gr.Interface(
    style_sofa,
    inputs = [image,style],
    outputs = 'image',
    examples= [example1, example2, example3 ,example4 ,example5],
    title="πŸ›‹ Style your sofa πŸ›‹ ",
    description="Customize your sofa to your 🌈 wildest dreams 🌈!\
                \nProvide a picture of your sofa and a desired pattern\
                 or choose one of the examples below. ⬇️",
    # article="**References**\n\n"
    # "<a href='https://www.tensorflow.org/hub/tutorials/tf2_arbitrary_image_stylization' target='_blank'>1. Tutorial to implement Fast Neural Style Transfer using the pretrained model from TensorFlow Hub</a>  \n"
    # "<a href='https://huggingface.co/spaces/luca-martial/neural-style-transfer' target='_blank'>2. The idea to build a neural style transfer application was inspired from this Hugging Face Space </a>"
)

if __name__ == "__main__":
    demo.launch()


#https://github.com/dhawan98/Post-Processing-of-Image-Segmentation-using-CRF