Mansib/Allure
2
1import torch2import clip3from PIL import Image4import gradio as gr5import datetime6 7device = "cuda" if torch.cuda.is_available() else "cpu"8model, preprocess = clip.load("ViT-B/32", device=device)9 10 11def allure(image, gender):12 image = Image.fromarray(image.astype("uint8"), "RGB")13 gender = gender.lower()14 image = preprocess(image).unsqueeze(0).to(device)15 positive_terms = [f'a hot {gender}',16 f'a beautiful {gender}', f'an alluring {gender}', 'a photorealistic image taken with a high-quality camera', 'a photorealistic image taken with a low-quality/bad camera']17 negative_terms = [f'a gross {gender}',18 f'an ugly {gender}', f'a hideous {gender}', 'a toonish, unrealistic or photoshopped image taken with a high-quality camera', 'a toonish, unrealistic or photoshopped image taken with a low-quality/bad camera']19 20 pairs = list(zip(positive_terms, negative_terms))21 22 def evaluate(terms):23 text = clip.tokenize(terms).to(device)24 25 with torch.no_grad():26 logits_per_image, logits_per_text = model(image, text)27 probs = logits_per_image.softmax(dim=-1).cpu().numpy()28 return probs[0]29 30 probs = [evaluate(pair) for pair in pairs]31 32 positive_probs = [prob[0] for prob in probs]33 negative_probs = [prob[1] for prob in probs]34 35 hotness_score = round((probs[0][0] - probs[0][1] + 1) * 50, 2)36 beauty_score = round((probs[1][0] - probs[1][1] + 1) * 50, 2)37 attractiveness_score = round((probs[2][0] - probs[2][1] + 1) * 50, 2)38 39 authenticity_score_lq = round((probs[-1][0] - probs[-1][1] + 1) * 50, 2)40 authenticity_score_hq = round((probs[-2][0] - probs[-2][1] + 1) * 50, 2)41 authenticity_score = (authenticity_score_lq + authenticity_score_hq)/242 43 hot_score = sum(positive_probs[:-1])/len(positive_probs[:-1])44 ugly_score = sum(negative_probs[:-1])/len(negative_probs[:-1])45 composite = ((hot_score - ugly_score)+1) * 5046 composite = round(composite, 2)47 48 judgement = "extremely toonish and/or distorted"49 50 if authenticity_score >= 90:51 judgement = "likely real"52 elif authenticity_score >= 80:53 judgement = "slightly altered"54 elif authenticity_score >= 70:55 judgement = "moderately altered"56 elif authenticity_score >= 50:57 judgement = "significantly toonish or altered"58 59 return composite, hotness_score, beauty_score, attractiveness_score, authenticity_score_hq, authenticity_score_lq, f"{authenticity_score} ({judgement})"60 61 62# theme = gr.themes.Soft(63# font=[gr.themes.GoogleFont("Quicksand"),64# "ui-sans-serif", "sans-serif"],65# font_mono=[gr.themes.GoogleFont("IBM Plex Mono"),66# "ui-monospace", "monospace"],67# primary_hue="cyan",68# secondary_hue="cyan",69# radius_size="lg")70 71# theme.set(72# input_radius="64px",73# button_large_radius='64px',74# button_small_radius='64px',75# body_background_fill=theme.block_background_fill_dark,76# block_shadow=theme.block_shadow_dark,77# block_label_radius='64px',78# block_label_right_radius='64px',79# background_fill_primary=theme.background_fill_primary_dark,80# background_fill_secondary=theme.background_fill_secondary_dark,81# block_label_border_width=theme.block_label_border_width_dark,82# block_label_border_color=theme.block_label_border_color_dark83# )84 85with gr.Interface(86 # theme=theme,87 fn=allure,88 inputs=[89 gr.Image(label="Image"),90 gr.Dropdown(91 [92 'Person', 'Man', 'Woman'93 ],94 default='Person',95 label="Gender"96 )97 ],98 outputs=[99 gr.Textbox(label="Composite Score (%)"),100 gr.Textbox(label="Hotness (%)"),101 gr.Textbox(label="Beauty (%)"),102 gr.Textbox(label="Allure (%)"),103 gr.Textbox(label="HQ Authenticity (%)"),104 gr.Textbox(label="LQ Authenticity (%)"),105 gr.Textbox(label="Composite Authenticity (≥ 90% → likely real)"),106 ],107 examples=[108 ['Mansib_01_x2048.png', 'Man'],109 ['Mansib_02_x2048.png', 'Man']110 ],111 title=f"Attractiveness Evaluator (powered by OpenAI CLIP) [Updated on {datetime.datetime.now().strftime('%A, %b %d %Y %I:%M:%S%p')}]",112 description=f"""A simple attractiveness evaluation app using the latest, current (newest stable release as of {datetime.datetime.now().strftime('%A, %b %d %Y %I:%M:%S%p')}) version of OpenAI's CLIP model.""",113) as iface:114 with gr.Accordion("How does it work?"):115 gr.Markdown(116 """The input image is passed to OpenAI's CLIP image captioning model and evaluated for how much it conforms to the model's idea of hotness, beauty, and attractiveness. 117These values are then combined to produce a composite score on a scale of 0 to 100.118# ⚠️ WARNING: This is meant solely for educational use!""")119 120iface.queue(api_open=False) # Add `api_open = False` to disable direct API access.121iface.launch()122 