|
import spaces |
|
import gradio as gr |
|
import subprocess |
|
from PIL import Image |
|
import json |
|
import os |
|
import time |
|
import mp_box |
|
import draw_landmarks68 |
|
|
|
''' |
|
Face landmark detection based Face Detection. |
|
https://ai.google.dev/edge/mediapipe/solutions/vision/face_landmarker |
|
from model card |
|
https://storage.googleapis.com/mediapipe-assets/MediaPipe%20BlazeFace%20Model%20Card%20(Short%20Range).pdf |
|
Licensed Apache License, Version 2.0 |
|
Train with google's dataset(more detail see model card) |
|
|
|
''' |
|
|
|
dir_name ="files" |
|
passed_time = 60*60 |
|
def clear_old_files(dir,passed_time): |
|
try: |
|
files = os.listdir(dir) |
|
current_time = time.time() |
|
for file in files: |
|
file_path = os.path.join(dir,file) |
|
|
|
ctime = os.stat(file_path).st_ctime |
|
diff = current_time - ctime |
|
|
|
if diff > passed_time: |
|
os.remove(file_path) |
|
except: |
|
print("maybe still gallery using error") |
|
|
|
def picker_color_to_rgba(picker_color): |
|
color_value = picker_color.strip("rgba()").split(",") |
|
color_value[0] = int(float(color_value[0])) |
|
color_value[1] = int(float(color_value[1])) |
|
color_value[2] = int(float(color_value[2])) |
|
color_value[3] = int(float(color_value[3])) |
|
return color_value |
|
|
|
|
|
def process_images(image,draw_number,font_scale,text_color_text,dot_size,dot_color_text,line_size,line_color_text,box_size,box_color_text,json_format,draw_mesh=False,progress=gr.Progress(track_tqdm=True)): |
|
|
|
if not os.path.exists(dir_name): |
|
os.mkdir(dir_name) |
|
clear_old_files(dir_name,passed_time) |
|
|
|
if image == None: |
|
raise gr.Error("Need Image") |
|
|
|
progress(0, desc="Start Mediapipe") |
|
|
|
|
|
boxes,mp_image,face_landmarker_result = mp_box.mediapipe_to_box(image) |
|
|
|
text_color = picker_color_to_rgba(text_color_text) |
|
line_color = picker_color_to_rgba(line_color_text) |
|
dot_color = picker_color_to_rgba(dot_color_text) |
|
box_color = picker_color_to_rgba(box_color_text) |
|
|
|
if draw_mesh: |
|
image=Image.fromarray(mp_box.draw_landmarks_on_image(face_landmarker_result,image)) |
|
|
|
annotated_image,bbox,landmark_points = draw_landmarks68.draw_landmarks_on_image(image,face_landmarker_result,draw_number,font_scale,text_color, |
|
dot_size,dot_color,line_size,line_color, |
|
box_size,box_color) |
|
|
|
|
|
if json_format=="raw": |
|
jsons = landmark_points |
|
else: |
|
jsons=draw_landmarks68.convert_to_landmark_group_json(landmark_points) |
|
|
|
|
|
formatted_json = json.dumps(jsons) |
|
json_path=create_json_download(formatted_json) |
|
|
|
return annotated_image,jsons,json_path |
|
|
|
|
|
def write_file(file_path,text): |
|
with open(file_path, 'w', encoding='utf-8') as f: |
|
f.write(text) |
|
|
|
def read_file(file_path): |
|
"""read the text of target file |
|
""" |
|
with open(file_path, 'r', encoding='utf-8') as f: |
|
content = f.read() |
|
|
|
return content |
|
|
|
css=""" |
|
#col-left { |
|
margin: 0 auto; |
|
max-width: 640px; |
|
} |
|
#col-right { |
|
margin: 0 auto; |
|
max-width: 640px; |
|
} |
|
.grid-container { |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
gap:10px |
|
} |
|
|
|
.image { |
|
width: 128px; |
|
height: 128px; |
|
object-fit: cover; |
|
} |
|
|
|
.text { |
|
font-size: 16px; |
|
} |
|
""" |
|
|
|
|
|
|
|
import hashlib |
|
|
|
def text_to_sha256(text): |
|
text_bytes = text.encode('utf-8') |
|
hash_object = hashlib.sha256() |
|
hash_object.update(text_bytes) |
|
sha256_hex = hash_object.hexdigest() |
|
return sha256_hex |
|
|
|
|
|
def create_json_download(text): |
|
file_id = f"{dir_name}/landmark_{text_to_sha256(text)[:32]}.json" |
|
write_file(file_id,text) |
|
|
|
return file_id |
|
|
|
with gr.Blocks(css=css, elem_id="demo-container") as demo: |
|
with gr.Column(): |
|
gr.HTML(read_file("demo_header.html")) |
|
gr.HTML(read_file("demo_tools.html")) |
|
with gr.Row(): |
|
with gr.Column(): |
|
image = gr.Image(height=800,sources=['upload','clipboard'],image_mode='RGB',elem_id="image_upload", type="pil", label="Upload") |
|
with gr.Row(elem_id="prompt-container", equal_height=False): |
|
with gr.Row(): |
|
btn = gr.Button("Extract Landmark 68", elem_id="run_button",variant="primary") |
|
|
|
with gr.Accordion(label="Advanced Settings", open=False): |
|
with gr.Row( equal_height=True): |
|
draw_number = gr.Checkbox(label="draw Number",value=True) |
|
|
|
font_scale = gr.Slider( |
|
label="Font Scale", |
|
minimum=0.1, |
|
maximum=2, |
|
step=0.1, |
|
value=0.5) |
|
|
|
text_color = gr.ColorPicker(value="rgba(200,200,200,1)",label="text color") |
|
|
|
with gr.Row( equal_height=True): |
|
|
|
line_color = gr.ColorPicker(value="rgba(0,0,255,1)",label="line color") |
|
line_size = gr.Slider( |
|
label="Line Size", |
|
minimum=0, |
|
maximum=20, |
|
step=1, |
|
value=1) |
|
with gr.Row( equal_height=True): |
|
dot_color = gr.ColorPicker(value="rgba(255,0,0,1)",label="dot color") |
|
dot_size = gr.Slider( |
|
label="Dot Size", |
|
minimum=0, |
|
maximum=40, |
|
step=1, |
|
value=3) |
|
with gr.Row( equal_height=True): |
|
box_color = gr.ColorPicker(value="rgba(200,200,200,1)",label="box color") |
|
box_size = gr.Slider( |
|
label="Box Size", |
|
minimum=0, |
|
maximum=20, |
|
step=1, |
|
value=1) |
|
with gr.Row( equal_height=True): |
|
json_format = gr.Radio(choices=["raw","face-detection"],value="face-detection",label="json-output format") |
|
draw_mesh = gr.Checkbox(value=True,label="draw mesh",info="draw mediapipe mesh") |
|
|
|
with gr.Column(): |
|
image_out = gr.Image(label="Output", elem_id="output-img") |
|
text_out = gr.TextArea(label="JSON-Output") |
|
download_button = gr.DownloadButton(label="Download JSON" ) |
|
|
|
|
|
|
|
btn.click(fn=process_images, inputs=[image,draw_number,font_scale,text_color, |
|
dot_size,dot_color,line_size,line_color, |
|
box_size,box_color,json_format,draw_mesh], outputs =[image_out,text_out,download_button], api_name='infer') |
|
gr.Examples( |
|
examples =["examples/00003245_00.jpg","examples/00004200.jpg","examples/00005259.jpg","examples/00018022.jpg","examples/img-above.jpg","examples/img-below.jpg","examples/img-side.jpg"], |
|
inputs=[image] |
|
) |
|
gr.HTML(read_file("demo_footer.html")) |
|
|
|
if __name__ == "__main__": |
|
demo.launch() |
|
|