|
|
import gradio as gr |
|
|
import os |
|
|
import requests |
|
|
from PIL import Image |
|
|
import json |
|
|
|
|
|
|
|
|
API_BASE_URL = os.getenv("API_BASE_URL") |
|
|
|
|
|
def face_compare(frame1, frame2, request: gr.Request = None): |
|
|
"""Face comparison with enhanced result display""" |
|
|
try: |
|
|
url = f"{API_BASE_URL}" |
|
|
|
|
|
|
|
|
files = {} |
|
|
if frame1: |
|
|
files['image1'] = open(frame1, 'rb') |
|
|
if frame2: |
|
|
files['image2'] = open(frame2, 'rb') |
|
|
|
|
|
if not files: |
|
|
return "<div class='error-message'>Please upload both images</div>" |
|
|
|
|
|
|
|
|
response = requests.post(url=url, files=files) |
|
|
result = response.json() |
|
|
|
|
|
|
|
|
for file in files.values(): |
|
|
file.close() |
|
|
|
|
|
|
|
|
return format_face_comparison_result(result, frame1, frame2) |
|
|
|
|
|
except Exception as e: |
|
|
return f"<div class='error-message'>Error processing request: {str(e)}</div>" |
|
|
|
|
|
def format_face_comparison_result(result, img1_path, img2_path): |
|
|
"""Format face comparison results with professional styling""" |
|
|
|
|
|
detections = result.get("detections", []) |
|
|
matches = result.get("match", []) |
|
|
|
|
|
|
|
|
html = "<div class='result-content'>" |
|
|
|
|
|
|
|
|
if detections: |
|
|
for i, detection in enumerate(detections): |
|
|
face_image = detection.get("face", "") |
|
|
first_face_index = detection.get("firstFaceIndex") |
|
|
second_face_index = detection.get("secondFaceIndex") |
|
|
|
|
|
|
|
|
if matches: |
|
|
html += """ |
|
|
<div class="matching-section"> |
|
|
<div class="matches-table"> |
|
|
<table> |
|
|
<thead> |
|
|
<tr> |
|
|
<th>First Image Face</th> |
|
|
<th>Second Image Face</th> |
|
|
<th>Similarity Score</th> |
|
|
<th>Result</th> |
|
|
</tr> |
|
|
</thead> |
|
|
<tbody> |
|
|
""" |
|
|
|
|
|
|
|
|
match_groups = {} |
|
|
for match in matches: |
|
|
first_face_index = match.get("firstFaceIndex", "N/A") |
|
|
if first_face_index not in match_groups: |
|
|
match_groups[first_face_index] = [] |
|
|
match_groups[first_face_index].append(match) |
|
|
|
|
|
row_number = 1 |
|
|
for first_face_index in sorted(match_groups.keys()): |
|
|
for match in match_groups[first_face_index]: |
|
|
first_face_index = match.get("firstFaceIndex", "N/A") |
|
|
second_face_index = match.get("secondFaceIndex", "N/A") |
|
|
similarity = match.get("similarity", 0) |
|
|
|
|
|
|
|
|
first_face_img = "" |
|
|
second_face_img = "" |
|
|
|
|
|
for detection in detections: |
|
|
if detection.get("firstFaceIndex") == first_face_index: |
|
|
first_face_img = detection.get("face", "") |
|
|
if detection.get("secondFaceIndex") == second_face_index: |
|
|
second_face_img = detection.get("face", "") |
|
|
|
|
|
|
|
|
if similarity >= 0.6: |
|
|
result_text = "same person" |
|
|
result_class = "result-same" |
|
|
else: |
|
|
result_text = "different person" |
|
|
result_class = "result-different" |
|
|
|
|
|
first_face_display = f"<img src='data:image/png;base64,{first_face_img}' class='table-face-thumbnail' />" if first_face_img else f"Face {first_face_index}" |
|
|
second_face_display = f"<img src='data:image/png;base64,{second_face_img}' class='table-face-thumbnail' />" if second_face_img else f"Face {second_face_index}" |
|
|
|
|
|
html += f""" |
|
|
<tr> |
|
|
<td class="face-cell"> |
|
|
<div class="face-display"> |
|
|
{first_face_display} |
|
|
<div class="face-label">Face {first_face_index}</div> |
|
|
</div> |
|
|
</td> |
|
|
<td class="face-cell"> |
|
|
<div class="face-display"> |
|
|
{second_face_display} |
|
|
<div class="face-label">Face {second_face_index}</div> |
|
|
</div> |
|
|
</td> |
|
|
<td class="similarity-score">{similarity:.4f}</td> |
|
|
<td><span class="result-text {result_class}">{result_text}</span></td> |
|
|
</tr> |
|
|
""" |
|
|
row_number += 1 |
|
|
|
|
|
html += """ |
|
|
</tbody> |
|
|
</table> |
|
|
</div> |
|
|
</div> |
|
|
""" |
|
|
else: |
|
|
html += "<div class='no-results'>No face matches found.</div>" |
|
|
|
|
|
html += "</div>" |
|
|
return html |
|
|
|
|
|
def create_footer(): |
|
|
"""Create simple footer""" |
|
|
return """ |
|
|
<div class="footer"> |
|
|
<p>© 2024 MiniAiLive. All rights reserved.</p> |
|
|
<p> |
|
|
<a href="https://www.miniai.live" target="_blank">Website</a> | |
|
|
<a href="mailto:info@miniai.live">Contact Us</a> | |
|
|
<a href="https://www.miniai.live/privacy-policy" target="_blank">Privacy Policy</a> |
|
|
</p> |
|
|
</div> |
|
|
""" |
|
|
|
|
|
def get_custom_css(): |
|
|
"""Return simplified CSS styling that works for both light and dark themes""" |
|
|
return """ |
|
|
footer {visibility: hidden} |
|
|
|
|
|
/* Full width container */ |
|
|
.gradio-container { |
|
|
max-width: 95% !important; |
|
|
width: 95% !important; |
|
|
margin: 0 auto !important; |
|
|
font-size: 16px !important; |
|
|
} |
|
|
|
|
|
/* Center everything */ |
|
|
.container { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
width: 100%; |
|
|
} |
|
|
|
|
|
/* Header styling - logo and text in same line */ |
|
|
.company-header { |
|
|
background: var(--background-fill-primary); |
|
|
padding: 25px; |
|
|
margin-bottom: 25px; |
|
|
text-align: center; |
|
|
width: 100%; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
gap: 25px; |
|
|
flex-wrap: wrap; |
|
|
} |
|
|
|
|
|
.header-logo { |
|
|
flex-shrink: 0; |
|
|
} |
|
|
|
|
|
.header-logo img { |
|
|
width: 140px; |
|
|
height: auto; |
|
|
} |
|
|
|
|
|
.header-text { |
|
|
text-align: center; |
|
|
} |
|
|
|
|
|
.header-text h1 { |
|
|
font-size: 2.4em !important; |
|
|
margin-bottom: 12px; |
|
|
font-weight: 700; |
|
|
margin-top: 0; |
|
|
color: var(--body-text-color); |
|
|
} |
|
|
|
|
|
.header-text p { |
|
|
font-size: 1.3em !important; |
|
|
margin-bottom: 0; |
|
|
color: var(--body-text-color); |
|
|
opacity: 0.8; |
|
|
} |
|
|
|
|
|
/* About section layout */ |
|
|
.about-section { |
|
|
width: 100%; |
|
|
margin-bottom: 25px; |
|
|
} |
|
|
|
|
|
.about-content { |
|
|
display: flex; |
|
|
gap: 25px; |
|
|
width: 100%; |
|
|
} |
|
|
|
|
|
.features-section { |
|
|
flex: 0.6; |
|
|
padding: 25px; |
|
|
background: var(--background-fill-secondary); |
|
|
border-radius: 10px; |
|
|
font-size: 1.05em !important; |
|
|
} |
|
|
|
|
|
.demo-items-section { |
|
|
flex: 0.4; |
|
|
padding: 10px; |
|
|
background: var(--background-fill-secondary); |
|
|
border-radius: 10px; |
|
|
} |
|
|
|
|
|
.demo-items-grid { |
|
|
display: grid; |
|
|
grid-template-columns: repeat(2, 1fr); |
|
|
gap: 15px; |
|
|
} |
|
|
|
|
|
.demo-item { |
|
|
background: var(--background-fill-primary); |
|
|
padding: 4px; |
|
|
border-radius: 8px; |
|
|
text-align: center; |
|
|
transition: background-color 0.2s ease; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
text-decoration: none; |
|
|
color: var(--body-text-color); |
|
|
font-size: 1em !important; |
|
|
} |
|
|
|
|
|
.demo-item:hover { |
|
|
background: var(--button-secondary-background-fill-hover); |
|
|
} |
|
|
|
|
|
.demo-item img { |
|
|
height: 30px; |
|
|
margin-bottom: 10px; |
|
|
} |
|
|
|
|
|
.demo-item span { |
|
|
font-size: 0.95em !important; |
|
|
font-weight: 600; |
|
|
} |
|
|
|
|
|
/* Main content layout */ |
|
|
.main-content-row { |
|
|
display: flex; |
|
|
gap: 25px; |
|
|
width: 100%; |
|
|
margin-bottom: 25px; |
|
|
} |
|
|
|
|
|
.upload-section { |
|
|
flex: 2; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 20px; |
|
|
} |
|
|
|
|
|
.result-section { |
|
|
flex: 1.2; |
|
|
} |
|
|
|
|
|
.upload-images-row { |
|
|
display: flex; |
|
|
gap: 20px; |
|
|
width: 100%; |
|
|
} |
|
|
|
|
|
.upload-image-col { |
|
|
flex: 1; |
|
|
} |
|
|
|
|
|
/* Button styling */ |
|
|
.button-primary { |
|
|
background: var(--button-primary-background-fill) !important; |
|
|
border: none !important; |
|
|
padding: 16px 32px !important; |
|
|
font-size: 1.2em !important; |
|
|
font-weight: 600 !important; |
|
|
color: var(--button-primary-text-color) !important; |
|
|
border-radius: 8px !important; |
|
|
cursor: pointer !important; |
|
|
transition: background-color 0.2s ease !important; |
|
|
margin: 20px 0 !important; |
|
|
width: 100% !important; |
|
|
} |
|
|
|
|
|
.button-primary:hover { |
|
|
background: var(--button-primary-background-fill-hover) !important; |
|
|
} |
|
|
|
|
|
/* Result container styling */ |
|
|
.result-container { |
|
|
background: var(--background-fill-primary); |
|
|
padding: 8px; |
|
|
border-radius: 10px; |
|
|
margin-top: 0; |
|
|
width: 100%; |
|
|
text-align: center; |
|
|
height: fit-content; |
|
|
} |
|
|
|
|
|
.result-content { |
|
|
width: 100%; |
|
|
} |
|
|
|
|
|
/* Detection cards */ |
|
|
.detections-grid { |
|
|
display: grid; |
|
|
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); |
|
|
gap: 15px; |
|
|
margin-top: 20px; |
|
|
justify-content: center; |
|
|
} |
|
|
|
|
|
.detection-card { |
|
|
background: var(--background-fill-secondary); |
|
|
padding: 15px; |
|
|
border-radius: 8px; |
|
|
text-align: center; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
} |
|
|
|
|
|
.face-thumbnail { |
|
|
width: 60px; |
|
|
height: 60px; |
|
|
border-radius: 50%; |
|
|
object-fit: cover; |
|
|
margin-bottom: 10px; |
|
|
} |
|
|
|
|
|
.no-face { |
|
|
width: 60px; |
|
|
height: 60px; |
|
|
background: var(--background-fill-primary); |
|
|
border-radius: 50%; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
margin: 0 auto 10px; |
|
|
color: var(--body-text-color); |
|
|
font-size: 0.8em; |
|
|
opacity: 0.7; |
|
|
} |
|
|
|
|
|
.face-source { |
|
|
font-size: 0.9em !important; |
|
|
color: var(--body-text-color); |
|
|
opacity: 0.8; |
|
|
margin-top: 8px; |
|
|
} |
|
|
|
|
|
/* Matching table - NEW STYLING */ |
|
|
.matches-table { |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
width: 100%; |
|
|
overflow-x: auto; |
|
|
} |
|
|
|
|
|
.matches-table table { |
|
|
width: 100%; |
|
|
border-collapse: collapse; |
|
|
margin-top: 8px; |
|
|
font-size: 1em !important; |
|
|
min-width: 550px; |
|
|
} |
|
|
|
|
|
.matches-table th { |
|
|
background: var(--background-fill-secondary); |
|
|
color: var(--body-text-color); |
|
|
padding: 12px 8px !important; |
|
|
text-align: center; |
|
|
font-size: 1em !important; |
|
|
font-weight: 700; |
|
|
border-bottom: 2px solid var(--border-color-primary); |
|
|
} |
|
|
|
|
|
.matches-table td { |
|
|
padding: 10px 8px !important; |
|
|
border-bottom: 1px solid var(--border-color-primary); |
|
|
text-align: center; |
|
|
font-size: 0.95em !important; |
|
|
color: var(--body-text-color); |
|
|
} |
|
|
|
|
|
.row-number { |
|
|
font-weight: 600; |
|
|
color: var(--body-text-color); |
|
|
} |
|
|
|
|
|
.face-cell { |
|
|
vertical-align: middle; |
|
|
} |
|
|
|
|
|
.face-display { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
gap: 5px; |
|
|
} |
|
|
|
|
|
.table-face-thumbnail { |
|
|
width: 70px; |
|
|
height: 70px; |
|
|
border-radius: 50%; |
|
|
object-fit: cover; |
|
|
border: 2px solid var(--border-color-primary); |
|
|
} |
|
|
|
|
|
.face-label { |
|
|
font-size: 0.9em !important; |
|
|
color: var(--body-text-color); |
|
|
opacity: 1; |
|
|
font-weight: 600; |
|
|
} |
|
|
|
|
|
.similarity-score { |
|
|
font-weight: 700; |
|
|
color: var(--body-text-color); |
|
|
font-size: 1.05em !important; |
|
|
} |
|
|
|
|
|
.result-text { |
|
|
padding: 8px 12px !important; |
|
|
border-radius: 12px; |
|
|
font-size: 1.1em !important; |
|
|
font-weight: 700; |
|
|
text-transform: capitalize; |
|
|
} |
|
|
|
|
|
.result-same { |
|
|
background: #d4edda; |
|
|
color: #155724; |
|
|
} |
|
|
|
|
|
.result-different { |
|
|
background: #f8d7da; |
|
|
color: #721c24; |
|
|
} |
|
|
|
|
|
.no-results { |
|
|
text-align: center; |
|
|
padding: 40px; |
|
|
color: var(--body-text-color); |
|
|
opacity: 0.7; |
|
|
font-style: italic; |
|
|
font-size: 1.1em !important; |
|
|
} |
|
|
|
|
|
/* Error messages */ |
|
|
.error-message { |
|
|
background: var(--background-fill-secondary); |
|
|
color: var(--body-text-color); |
|
|
padding: 20px; |
|
|
border-radius: 8px; |
|
|
text-align: center; |
|
|
width: 100%; |
|
|
opacity: 0.9; |
|
|
font-size: 1.1em !important; |
|
|
} |
|
|
|
|
|
/* Input images styling */ |
|
|
.gradio-image { |
|
|
display: flex !important; |
|
|
justify-content: center !important; |
|
|
align-items: center !important; |
|
|
height: 380px !important; |
|
|
} |
|
|
|
|
|
.gradio-image .wrap { |
|
|
display: flex !important; |
|
|
justify-content: center !important; |
|
|
align-items: center !important; |
|
|
width: 100% !important; |
|
|
height: 100% !important; |
|
|
} |
|
|
|
|
|
/* Examples styling */ |
|
|
.examples-container { |
|
|
background: var(--background-fill-secondary); |
|
|
padding: 15px; |
|
|
border-radius: 8px; |
|
|
margin-top: 15px; |
|
|
width: 100%; |
|
|
text-align: center; |
|
|
font-size: 1em !important; |
|
|
} |
|
|
|
|
|
/* Footer */ |
|
|
.footer { |
|
|
text-align: center; |
|
|
margin-top: 25px; |
|
|
padding: 20px; |
|
|
border-radius: 8px; |
|
|
background: var(--background-fill-secondary); |
|
|
font-size: 1em !important; |
|
|
} |
|
|
|
|
|
.footer p { |
|
|
margin: 8px 0; |
|
|
color: var(--body-text-color); |
|
|
font-size: 1.05em !important; |
|
|
} |
|
|
|
|
|
.footer a { |
|
|
color: var(--body-text-color); |
|
|
text-decoration: none; |
|
|
opacity: 0.8; |
|
|
font-size: 1.05em !important; |
|
|
} |
|
|
|
|
|
.footer a:hover { |
|
|
opacity: 1; |
|
|
text-decoration: underline; |
|
|
} |
|
|
|
|
|
/* Section titles */ |
|
|
.section-title { |
|
|
margin-bottom: 15px !important; |
|
|
text-align: center; |
|
|
color: var(--body-text-color); |
|
|
font-weight: 700; |
|
|
font-size: 1.4em !important; |
|
|
} |
|
|
|
|
|
/* Ensure proper text visibility in dark mode */ |
|
|
.gradio-markdown { |
|
|
color: var(--body-text-color) !important; |
|
|
font-size: 1.05em !important; |
|
|
line-height: 1.5 !important; |
|
|
} |
|
|
|
|
|
.gradio-markdown h3 { |
|
|
color: var(--body-text-color) !important; |
|
|
font-size: 1.3em !important; |
|
|
} |
|
|
|
|
|
.gradio-markdown p { |
|
|
color: var(--body-text-color) !important; |
|
|
font-size: 1.05em !important; |
|
|
line-height: 1.5 !important; |
|
|
} |
|
|
|
|
|
.gradio-markdown li { |
|
|
color: var(--body-text-color) !important; |
|
|
font-size: 1.05em !important; |
|
|
line-height: 1.5 !important; |
|
|
margin-bottom: 8px !important; |
|
|
} |
|
|
|
|
|
/* Label styling */ |
|
|
.gr-label { |
|
|
font-size: 1.1em !important; |
|
|
font-weight: 600 !important; |
|
|
} |
|
|
|
|
|
/* Accordion styling */ |
|
|
.gr-accordion { |
|
|
font-size: 1.1em !important; |
|
|
} |
|
|
|
|
|
/* Examples text */ |
|
|
.gr-examples { |
|
|
font-size: 1em !important; |
|
|
} |
|
|
""" |
|
|
|
|
|
|
|
|
with gr.Blocks( |
|
|
title="MiniAiLive - Face Recognition WebAPI Playground", |
|
|
theme=gr.themes.Glass(), |
|
|
css=get_custom_css() |
|
|
) as demo: |
|
|
|
|
|
with gr.Column(elem_classes="container"): |
|
|
|
|
|
gr.HTML(""" |
|
|
<div class="company-header"> |
|
|
<div class="header-logo"> |
|
|
<img src="https://miniai.live/wp-content/uploads/2024/02/logo_name-1-768x426-1.png" alt="MiniAiLive Logo"> |
|
|
</div> |
|
|
<div class="header-text"> |
|
|
<h1>MiniAiLive Face Recognition WebAPI Playground</h1> |
|
|
<p>Experience our NIST FRVT Top Ranked 1:1 & 1:N Face Matching Technology</p> |
|
|
</div> |
|
|
</div> |
|
|
""") |
|
|
|
|
|
|
|
|
with gr.Column(elem_classes="about-section"): |
|
|
with gr.Row(elem_classes="about-content"): |
|
|
|
|
|
with gr.Column(scale=0.6, elem_classes="features-section"): |
|
|
gr.Markdown(""" |
|
|
**MiniAiLive** is a leading provider of cutting-edge face recognition and liveness detection solutions. |
|
|
Our technology is **NIST FRVT Top Ranked** for Face Recognition. |
|
|
|
|
|
### 🏆 Key Features: |
|
|
- **NIST FRVT Top Ranked** Top Accuracy in both 1:1 & 1:N Face Matching Technology |
|
|
- **Real-time** Face Matching & Verification |
|
|
- **On-Premise** Offers complete data control and privacy |
|
|
- **On-Device, Offline** Runs on machine. No internet connection is required. |
|
|
- **Cross-Platform Support** Supports Windows, Linux, Android & iOS |
|
|
- **Free Service** Completely free to use, Free technical support & update |
|
|
|
|
|
[Visit our website](https://miniai.live) to explore our complete suite of AI solutions! |
|
|
""") |
|
|
|
|
|
|
|
|
with gr.Column(scale=0.4, elem_classes="demo-items-section"): |
|
|
with gr.Column(elem_classes="demo-items-grid"): |
|
|
gr.HTML(""" |
|
|
<a href="https://github.com/MiniAiLive" target="_blank" class="demo-item"> |
|
|
<img src="https://miniai.live/wp-content/uploads/2024/10/new_git-1-300x67.png" alt="GitHub"> |
|
|
<span>GitHub</span> |
|
|
</a> |
|
|
""") |
|
|
|
|
|
gr.HTML(""" |
|
|
<a href="https://huggingface.co/MiniAiLive" target="_blank" class="demo-item"> |
|
|
<img src="https://miniai.live/wp-content/uploads/2024/10/new_hugging-1-300x67.png" alt="HuggingFace"> |
|
|
<span>HuggingFace</span> |
|
|
</a> |
|
|
""") |
|
|
|
|
|
gr.HTML(""" |
|
|
<a href="https://demo.miniai.live" target="_blank" class="demo-item"> |
|
|
<img src="https://miniai.live/wp-content/uploads/2024/10/new_gradio-300x67.png" alt="Gradio"> |
|
|
<span>Live Demo</span> |
|
|
</a> |
|
|
""") |
|
|
|
|
|
gr.HTML(""" |
|
|
<a href="https://docs.miniai.live/" target="_blank" class="demo-item"> |
|
|
<img src="https://miniai.live/wp-content/uploads/2024/10/a-300x70.png" alt="Documentation"> |
|
|
<span>Documentation</span> |
|
|
</a> |
|
|
""") |
|
|
|
|
|
gr.HTML(""" |
|
|
<a href="https://www.youtube.com/@miniailive" target="_blank" class="demo-item"> |
|
|
<img src="https://miniai.live/wp-content/uploads/2024/10/Untitled-1-300x70.png" alt="YouTube"> |
|
|
<span>YouTube</span> |
|
|
</a> |
|
|
""") |
|
|
|
|
|
gr.HTML(""" |
|
|
<a href="https://play.google.com/store/apps/dev?id=5831076207730531667" target="_blank" class="demo-item"> |
|
|
<img src="https://miniai.live/wp-content/uploads/2024/10/googleplay-300x62.png" alt="Google Play"> |
|
|
<span>Google Play</span> |
|
|
</a> |
|
|
""") |
|
|
|
|
|
|
|
|
with gr.Row(elem_classes="main-content-row"): |
|
|
|
|
|
with gr.Column(scale=0.6, elem_classes="upload-section"): |
|
|
gr.Markdown("### 1. Upload Images for Comparison", elem_classes="section-title") |
|
|
|
|
|
with gr.Row(elem_classes="upload-images-row"): |
|
|
|
|
|
with gr.Column(scale=1, elem_classes="upload-image-col"): |
|
|
im_match_in1 = gr.Image( |
|
|
type='filepath', |
|
|
height=380, |
|
|
label="First Image", |
|
|
show_download_button=False |
|
|
) |
|
|
|
|
|
|
|
|
with gr.Column(scale=1, elem_classes="upload-image-col"): |
|
|
im_match_in2 = gr.Image( |
|
|
type='filepath', |
|
|
height=380, |
|
|
label="Second Image", |
|
|
show_download_button=False |
|
|
) |
|
|
|
|
|
|
|
|
with gr.Accordion("Try Example Images", open=True): |
|
|
with gr.Row(): |
|
|
gr.Examples( |
|
|
examples=[ |
|
|
"assets/1.jpg", |
|
|
"assets/2.jpg", |
|
|
"assets/3.jpg", |
|
|
"assets/4.jpg", |
|
|
], |
|
|
inputs=im_match_in1, |
|
|
label="First Image Examples" |
|
|
) |
|
|
gr.Examples( |
|
|
examples=[ |
|
|
"assets/1-1.jpg", |
|
|
"assets/2-1.jpg", |
|
|
"assets/3-1.jpg", |
|
|
"assets/4-1.jpg", |
|
|
], |
|
|
inputs=im_match_in2, |
|
|
label="Second Image Examples" |
|
|
) |
|
|
|
|
|
btn_f_match = gr.Button( |
|
|
"Compare Faces 🚀", |
|
|
variant='primary', |
|
|
elem_classes="button-primary" |
|
|
) |
|
|
|
|
|
|
|
|
with gr.Column(scale=0.4, elem_classes="result-section"): |
|
|
gr.Markdown("### 2. Comparison Results", elem_classes="section-title") |
|
|
txt_compare_out = gr.HTML( |
|
|
value="<div style='text-align: center; padding: 40px; font-size: 1.1em;'>Results will appear here after comparison</div>" |
|
|
) |
|
|
|
|
|
|
|
|
btn_f_match.click( |
|
|
face_compare, |
|
|
inputs=[im_match_in1, im_match_in2], |
|
|
outputs=txt_compare_out |
|
|
) |
|
|
|
|
|
|
|
|
gr.HTML(""" |
|
|
<a href="https://visitorbadge.io/status?path=https%3A%2F%2Fhuggingface.co%2Fspaces%2FMiniAiLive%2FFaceRecognition-LivenessDetection-Demo"> |
|
|
<img src="https://api.visitorbadge.io/api/combined?path=https%3A%2F%2Fhuggingface.co%2Fspaces%2FMiniAiLive%2FFaceRecognition-LivenessDetection-Demo&label=VISITORS&labelColor=%2337d67a&countColor=%23ff8a65&style=plastic&labelStyle=none" /> |
|
|
</a> |
|
|
""") |
|
|
|
|
|
|
|
|
gr.HTML(create_footer()) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch( |
|
|
share=False, |
|
|
show_error=True, |
|
|
server_name="0.0.0.0", |
|
|
server_port=7860 |
|
|
) |