faceparser / app.py
leonelhs's picture
parce whit annotations
2475ba1
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#######################################################################################
#
# This project is one of several repositories exploring image segmentation techniques.
# All related projects and interactive demos can be found at:
# https://huggingface.co/spaces/leonelhs/removators
# Self app: https://huggingface.co/spaces/leonelhs/rembg
#
# Source code is based on or inspired by several projects.
# For more details and proper attribution, please refer to the following resources:
#
# - [face-makeup.PyTorch] - [https://github.com/zllrunning/face-makeup.PyTorch]
# - [BiSeNet] [https://github.com/CoinCheung/BiSeNet]
import gradio as gr
import cv2
import torch
import numpy as np
from PIL import Image
from huggingface_hub import hf_hub_download
import torchvision.transforms as transforms
from bisnet import BiSeNet
REPO_ID = "leonelhs/faceparser"
MODEL_NAME = "79999_iter.pth"
model = BiSeNet(n_classes=19)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model_path = hf_hub_download(repo_id=REPO_ID, filename=MODEL_NAME)
model.load_state_dict(torch.load(model_path, map_location=device))
model.eval()
part_colors = [
{"part": "background", "color": [255, 0, 0]},
{"part": "face", "color": [219, 79, 66]},
{"part": "right_brow", "color": [255, 170, 0]},
{"part": "left_brow", "color": [255, 0, 85]},
{"part": "right_eye", "color": [255, 0, 170]},
{"part": "left_eye", "color": [ 0, 255, 0]},
{"part": "glasses", "color": [ 85, 255, 0]},
{"part": "right_ear", "color": [170, 255, 0]},
{"part": "left_ear", "color": [ 0, 255, 85]},
{"part": "earrings", "color": [ 0, 255, 170]},
{"part": "nose", "color": [ 0, 0, 255]},
{"part": "teeth", "color": [ 85, 0, 255]},
{"part": "upper_lip", "color": [170, 0, 255]},
{"part": "lower_lip", "color": [ 0, 85, 255]},
{"part": "neck", "color": [ 0, 170, 255]},
{"part": "collar", "color": [255, 255, 0]},
{"part": "cloths", "color": [255, 255, 85]},
{"part": "hair", "color": [199, 21, 133]},
{"part": "crown", "color": [255, 0, 255]},
{"part": "extra20", "color": [255, 85, 255]},
{"part": "extra21", "color": [255, 170, 255]},
{"part": "extra22", "color": [ 0, 255, 255]},
{"part": "extra23", "color": [ 85, 255, 255]},
{"part": "extra24", "color": [170, 255, 255]},
]
def image_to_tensor(image):
return transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
])(image)
def parse_face(mask):
num_of_class = np.max(mask)
face_parts = []
for index in range(1, num_of_class + 1):
face_part = np.where(mask == index)
canvas = np.full((512, 512, 3), 255, dtype=np.uint8)
canvas[face_part[0], face_part[1], :] = part_colors[index]["color"]
canvas = cv2.cvtColor(canvas, cv2.COLOR_BGR2GRAY)
face_parts.append((canvas, part_colors[index]["part"]))
return face_parts
def predict(image):
with torch.no_grad():
image = image.resize((512, 512), Image.Resampling.BILINEAR)
input_tensor = image_to_tensor(image)
input_tensor = torch.unsqueeze(input_tensor, 0)
if torch.cuda.is_available():
input_tensor = input_tensor.cuda()
mask = model(input_tensor)[0]
mask = mask.squeeze(0).cpu().numpy().argmax(0)
sections = parse_face(mask)
return image, sections
aboutme = r"""
# PyTorch Image Face Parser
Extracts facial features (hair, nose, eyes, etc.) from images using image segmentation.
This project is part of a larger collection of repositories exploring image segmentation techniques.
Related projects and interactive demos are available at: [Removators](https://huggingface.co/spaces/leonelhs/removators)
## Acknowledgments
The source code is based on or inspired by the following projects:
- [face-makeup.PyTorch](https://github.com/zllrunning/face-makeup.PyTorch)
- [BiSeNet](https://github.com/CoinCheung/BiSeNet)
## Contact
For questions, comments, or feedback, please contact:
📧 leonelhs@gmail.com
"""
with gr.Blocks(title="Face Parser") as app:
navbar = gr.Navbar(visible=True, main_page_name="Workspace")
gr.Markdown("## Face Parser Tool")
with gr.Row():
with gr.Column(scale=1):
inp = gr.Image(type="pil", label="Upload Image")
btn_predict = gr.Button("Parse")
with gr.Column(scale=2):
out = gr.AnnotatedImage(label="Face parsed annotated")
btn_predict.click(predict, inputs=[inp], outputs=[out])
with app.route("About this", "/about"):
gr.Markdown(aboutme)
app.launch(share=False, debug=True, show_error=True, mcp_server=True, pwa=True)
app.queue()