Akjava commited on
Commit
7bede24
·
1 Parent(s): 9985495
Files changed (1) hide show
  1. app.py +77 -17
app.py CHANGED
@@ -3,6 +3,8 @@ import gradio as gr
3
  import subprocess
4
  from PIL import Image,ImageEnhance,ImageFilter
5
  import json
 
 
6
 
7
  import mp_box
8
  '''
@@ -20,6 +22,12 @@ Bacause this is part of getting-landmark program and need control face edge.
20
  So I don't know which one is better.never compare these.
21
  '''
22
 
 
 
 
 
 
 
23
  def select_box(boxes,box_type):
24
  if box_type == "type-3":
25
  box = boxes[2]
@@ -34,11 +42,12 @@ def select_box(boxes,box_type):
34
  box = mp_box.xywh_to_xyxy(box)
35
  return box,box_width,box_height
36
 
37
- def process_images(image,replace_image=None,replace_image_need_crop=False,box_type="type-3",fill_color_mode=False,fill_color="black",custom_color="rgba(255,255,255,1)",image_size=1024,filter_image=False,filter_value="Sharpen",progress=gr.Progress(track_tqdm=True)):
38
  if image == None:
39
  raise gr.Error("Need Image")
40
 
41
  # choose box
 
42
  boxes,mp_image,face_landmarker_result = mp_box.mediapipe_to_box(image)
43
  box,box_width,box_height = select_box(boxes,box_type)
44
 
@@ -50,22 +59,52 @@ def process_images(image,replace_image=None,replace_image_need_crop=False,box_ty
50
  replace_boxes,mp_image,face_landmarker_result = mp_box.mediapipe_to_box(replace_image)
51
  replace_box,replace_box_width,replace_box_height = select_box(replace_boxes,box_type)
52
 
 
53
  if fill_color_mode:
54
  if replace_image_need_crop:
55
  cropped = replace_image.crop(replace_box)
56
- cropped.resize(box_width,box_height)
57
  else:
58
  cropped = replace_image.crop(box)
 
 
 
 
59
  image.paste(cropped,[box[0],box[1]])
60
  return image
61
  else:#scale mode
 
 
 
 
 
 
 
 
 
 
 
 
62
  if replace_image_need_crop:
63
  replace_image = replace_image.crop(replace_box)
64
  replace_resized = replace_image.resize((box_width,box_height),Image.Resampling.LANCZOS)
 
 
 
65
  image.paste(replace_resized,[box[0],box[1]])
66
  return image
67
 
68
 
 
 
 
 
 
 
 
 
 
 
69
  # crop-mode
70
  if fill_color_mode:
71
  # choose color
@@ -93,12 +132,16 @@ def process_images(image,replace_image=None,replace_image_need_crop=False,box_ty
93
  #scale up mode
94
  cropped = image.crop(box)
95
  resized = resize_image_by_max_dimension(cropped,image_size)
 
96
  filter_map={
 
97
  "Blur":ImageFilter.BLUR,"Smooth More":ImageFilter.SMOOTH_MORE,"Smooth":ImageFilter.SMOOTH,"Sharpen":ImageFilter.SHARPEN,"Edge Enhance":ImageFilter.EDGE_ENHANCE,"Edge Enhance More":ImageFilter.EDGE_ENHANCE_MORE
98
  }
 
99
  if filter_value not in filter_map:
100
  raise gr.Error(f"filter {filter_value} not found")
101
- if filter_image:
 
102
 
103
  #resized = resized.filter(ImageFilter.SHARPEN)
104
  #Gimp's weak 0.1-0.2?
@@ -161,15 +204,20 @@ css="""
161
  #css=css,
162
  def update_button_label(image):
163
  if image == None:
164
- return gr.Button(visible=bool(0)),gr.Button(visible=bool(1))
 
165
  else:
166
- return gr.Button(visible=bool(1)),gr.Row(visible=bool(0))
167
 
168
- def update_visible(fill_color_mode):
 
 
 
169
  if fill_color_mode:
170
- return gr.Row(visible=bool(0)),gr.Row(visible=bool(1))
171
  else:
172
- return gr.Row(visible=bool(1)),gr.Row(visible=bool(0))
 
173
  with gr.Blocks(css=css, elem_id="demo-container") as demo:
174
  with gr.Column():
175
  gr.HTML(read_file("demo_header.html"))
@@ -185,13 +233,23 @@ with gr.Blocks(css=css, elem_id="demo-container") as demo:
185
 
186
  replace_image = gr.Image(sources=['upload','clipboard'],image_mode='RGB',elem_id="replace_upload", type="pil", label="replace image")
187
  replace_image_need_crop = gr.Checkbox(label="Replace image need crop",value=False)
188
- replace_image.change(update_visible,replace_image,[btn1,btn2])
189
  with gr.Accordion(label="Advanced Settings", open=False):
190
- fill_color_mode = gr.Checkbox(label="Fill Color Mode",value=False)
 
 
 
 
 
 
 
 
 
 
 
191
  row1 = gr.Row(equal_height=True)
192
  row2 = gr.Row(equal_height=True,visible=False)
193
- fill_color_mode.change(update_visible,fill_color_mode,[row1,row2])
194
-
195
  with row1:
196
  image_size = gr.Slider(
197
  label="Image Size",info = "cropped face size",
@@ -201,14 +259,16 @@ with gr.Blocks(css=css, elem_id="demo-container") as demo:
201
  value=1024,
202
  interactive=True)
203
 
204
- filter_image = gr.Checkbox(label="Filter image")
205
- filter_value = gr.Dropdown(label="Filter",value="Sharpen",choices=["Blur","Smooth More","Smooth","Sharpen","Edge Enhance","Edge Enhance More"])
 
 
206
  with row2:
207
 
208
- fill_color = gr.Dropdown(label="fill color",choices=["black","white","red","brown","pink","custom"])
209
  custom_color = gr.ColorPicker(label="custom color",value="rgba(250, 218, 205, 1)")
210
 
211
-
212
  with gr.Column():
213
  image_out = gr.Image(label="Output", elem_id="output-img")
214
 
@@ -219,7 +279,7 @@ with gr.Blocks(css=css, elem_id="demo-container") as demo:
219
 
220
  gr.on(
221
  [btn1.click,btn2.click],
222
- fn=process_images, inputs=[image,replace_image,replace_image_need_crop,box_type,fill_color_mode,fill_color,custom_color,image_size,filter_image,filter_value], outputs =[image_out], api_name='infer'
223
  )
224
  gr.Examples(
225
  examples =["examples/00004200.jpg"],
 
3
  import subprocess
4
  from PIL import Image,ImageEnhance,ImageFilter
5
  import json
6
+ import numpy as np
7
+ from skimage.exposure import match_histograms
8
 
9
  import mp_box
10
  '''
 
22
  So I don't know which one is better.never compare these.
23
  '''
24
 
25
+ def color_match(base_image,cropped_image):
26
+ reference = np.array(base_image)
27
+ target =np.array(cropped_image)
28
+ matched = match_histograms(target, reference,channel_axis=-1)
29
+ return Image.fromarray(matched)
30
+
31
  def select_box(boxes,box_type):
32
  if box_type == "type-3":
33
  box = boxes[2]
 
42
  box = mp_box.xywh_to_xyxy(box)
43
  return box,box_width,box_height
44
 
45
+ def process_images(image,replace_image=None,replace_image_need_crop=False,box_type="type-3",fill_color_mode=False,fill_color="black",custom_color="rgba(255,255,255,1)",image_size=1024,margin_percent=0,filter_value="None",match_color=True,progress=gr.Progress(track_tqdm=True)):
46
  if image == None:
47
  raise gr.Error("Need Image")
48
 
49
  # choose box
50
+ image_width,image_height = image.size
51
  boxes,mp_image,face_landmarker_result = mp_box.mediapipe_to_box(image)
52
  box,box_width,box_height = select_box(boxes,box_type)
53
 
 
59
  replace_boxes,mp_image,face_landmarker_result = mp_box.mediapipe_to_box(replace_image)
60
  replace_box,replace_box_width,replace_box_height = select_box(replace_boxes,box_type)
61
 
62
+ # this is for fill_color_mode exported image
63
  if fill_color_mode:
64
  if replace_image_need_crop:
65
  cropped = replace_image.crop(replace_box)
66
+ cropped.resize((box_width,box_height))
67
  else:
68
  cropped = replace_image.crop(box)
69
+
70
+ if match_color:
71
+ cropped = color_match(image.crop(box),cropped)
72
+ #just paste base-face area
73
  image.paste(cropped,[box[0],box[1]])
74
  return image
75
  else:#scale mode
76
+ # box expand by margin
77
+ if margin_percent>0:
78
+ h_margin = int(box_width*margin_percent/100)
79
+ v_margin = int(box_height*margin_percent/100)
80
+
81
+ box[0] = max(0,box[0]-h_margin)
82
+ box[1] = max(0,box[1]-v_margin)
83
+ box[2] = min(image_width-1,box[2]+h_margin)
84
+ box[3] = min(image_height-1,box[3]+v_margin)
85
+ box_width = box[2]-box[0]
86
+ box_height = box[3]-box[1]
87
+
88
  if replace_image_need_crop:
89
  replace_image = replace_image.crop(replace_box)
90
  replace_resized = replace_image.resize((box_width,box_height),Image.Resampling.LANCZOS)
91
+ if match_color:
92
+ replace_resized = color_match(image.crop(box),replace_resized)
93
+
94
  image.paste(replace_resized,[box[0],box[1]])
95
  return image
96
 
97
 
98
+ # box expand by margin
99
+ if margin_percent>0:
100
+ h_margin = int(box_width*margin_percent/100)
101
+ v_margin = int(box_height*margin_percent/100)
102
+
103
+ box[0] = max(0,box[0]-h_margin)
104
+ box[1] = max(0,box[1]-v_margin)
105
+ box[2] = min(image_width-1,box[2]+h_margin)
106
+ box[3] = min(image_height-1,box[3]+v_margin)
107
+
108
  # crop-mode
109
  if fill_color_mode:
110
  # choose color
 
132
  #scale up mode
133
  cropped = image.crop(box)
134
  resized = resize_image_by_max_dimension(cropped,image_size)
135
+
136
  filter_map={
137
+ "None":None,
138
  "Blur":ImageFilter.BLUR,"Smooth More":ImageFilter.SMOOTH_MORE,"Smooth":ImageFilter.SMOOTH,"Sharpen":ImageFilter.SHARPEN,"Edge Enhance":ImageFilter.EDGE_ENHANCE,"Edge Enhance More":ImageFilter.EDGE_ENHANCE_MORE
139
  }
140
+
141
  if filter_value not in filter_map:
142
  raise gr.Error(f"filter {filter_value} not found")
143
+
144
+ if filter_value != "None":
145
 
146
  #resized = resized.filter(ImageFilter.SHARPEN)
147
  #Gimp's weak 0.1-0.2?
 
204
  #css=css,
205
  def update_button_label(image):
206
  if image == None:
207
+ print("none replace")
208
+ return gr.Button(visible=True),gr.Button(visible=False),gr.Row(visible=True),gr.Row(visible=True)
209
  else:
210
+ return gr.Button(visible=False),gr.Button(visible=True),gr.Row(visible=False),gr.Row(visible=False)
211
 
212
+ def update_visible(fill_color_mode,image):
213
+ if image != None:
214
+ return gr.Row(visible=False),gr.Row(visible=False)
215
+
216
  if fill_color_mode:
217
+ return gr.Row(visible=False),gr.Row(visible=True)
218
  else:
219
+ return gr.Row(visible=True),gr.Row(visible=False)
220
+
221
  with gr.Blocks(css=css, elem_id="demo-container") as demo:
222
  with gr.Column():
223
  gr.HTML(read_file("demo_header.html"))
 
233
 
234
  replace_image = gr.Image(sources=['upload','clipboard'],image_mode='RGB',elem_id="replace_upload", type="pil", label="replace image")
235
  replace_image_need_crop = gr.Checkbox(label="Replace image need crop",value=False)
236
+
237
  with gr.Accordion(label="Advanced Settings", open=False):
238
+ with gr.Row(equal_height=True):
239
+ fill_color_mode = gr.Checkbox(label="Fill Color Mode/No Resize",value=False)
240
+ match_color = gr.Checkbox(label="Match Color",value=True)
241
+ margin_percent = gr.Slider(
242
+ label="Margin percent",info = "add extra space",
243
+ minimum=0,
244
+ maximum=200,
245
+ step=1,
246
+ value=0,
247
+ interactive=True)
248
+
249
+
250
  row1 = gr.Row(equal_height=True)
251
  row2 = gr.Row(equal_height=True,visible=False)
252
+ fill_color_mode.change(update_visible,[fill_color_mode,replace_image],[row1,row2])
 
253
  with row1:
254
  image_size = gr.Slider(
255
  label="Image Size",info = "cropped face size",
 
259
  value=1024,
260
  interactive=True)
261
 
262
+
263
+
264
+ #filter_image = gr.Checkbox(label="Filter image")
265
+ filter_value = gr.Dropdown(label="Filter",value="None",choices=["Blur","Smooth More","Smooth","None","Sharpen","Edge Enhance","Edge Enhance More"])
266
  with row2:
267
 
268
+ fill_color = gr.Dropdown(label="fill color",choices=["black","white","red","brown","pink","custom"],value="pink")
269
  custom_color = gr.ColorPicker(label="custom color",value="rgba(250, 218, 205, 1)")
270
 
271
+ replace_image.change(update_button_label,replace_image,[btn1,btn2,row1,row2])#margin_percent
272
  with gr.Column():
273
  image_out = gr.Image(label="Output", elem_id="output-img")
274
 
 
279
 
280
  gr.on(
281
  [btn1.click,btn2.click],
282
+ fn=process_images, inputs=[image,replace_image,replace_image_need_crop,box_type,fill_color_mode,fill_color,custom_color,image_size,margin_percent,filter_value,match_color], outputs =[image_out], api_name='infer'
283
  )
284
  gr.Examples(
285
  examples =["examples/00004200.jpg"],