Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import cv2 | |
| import numpy as np | |
| from PIL import Image | |
| from src.skin_analyzer import analyze_skin_function | |
| from src.image import ImageBundle | |
| import plotly.express as px | |
| import plotly.graph_objects as go | |
| import matplotlib.pyplot as plt | |
| import io | |
| def resize_image(image, height=512): | |
| # Calculate the new width to maintain the aspect ratio | |
| aspect_ratio = image.width / image.height | |
| new_width = int(height * aspect_ratio) | |
| return image.resize((new_width, height), Image.Resampling.LANCZOS) | |
| def create_histogram(data, title): | |
| fig = px.histogram(data, nbins=30, title=title) | |
| fig.update_layout(title=dict(y=0.9)) | |
| fig.update_xaxes(title_text="Value") | |
| fig.update_yaxes(title_text="Frequency") | |
| return fig | |
| # Function to create pie chart using Plotly | |
| def create_pie_chart(data, title): | |
| fig = px.pie(values=data.values(), names=data.keys(), title=title) | |
| fig.update_layout(title=dict(y=0.9)) | |
| return fig | |
| # Function to create bar chart using Plotly | |
| def create_bar_chart(data, title, top_n=None): | |
| sorted_data = dict(sorted(data.items(), key=lambda item: item[1], reverse=True)) | |
| colors = ( | |
| ["red" if i < top_n else "blue" for i in range(len(sorted_data))] | |
| if top_n and top_n < len(sorted_data) | |
| else "blue" | |
| ) | |
| fig = px.bar(x=list(sorted_data.keys()), y=list(sorted_data.values()), title=title) | |
| fig.update_traces(marker_color=colors) | |
| fig.update_layout( | |
| title=dict(y=0.9), xaxis_title=None, yaxis_title="Counts", showlegend=False | |
| ) | |
| fig.update_xaxes(tickangle=45) | |
| return fig | |
| def process_image( | |
| image, | |
| l_min_skin, | |
| l_max_skin, | |
| l_min_tonality, | |
| l_max_tonality, | |
| chroma_thresh, | |
| analyze_skin, | |
| analyze_eyes, | |
| analyze_hair, | |
| ): | |
| """ | |
| Process the uploaded image and return the analysis results based on selected analyses. | |
| :param image: Uploaded image. | |
| :param analyze_skin: Whether to perform skin analysis. | |
| :param analyze_eyes: Whether to perform eye analysis. | |
| :param analyze_hair: Whether to perform hair analysis. | |
| :return: Analysis results. | |
| """ | |
| image_bundle = ImageBundle(image_array=image) | |
| # Detect faces and landmarks | |
| face_data = image_bundle.detect_faces_and_landmarks() | |
| landmarks = image_bundle.detect_face_landmarks() | |
| # Perform segmentation | |
| segmentation_maps = image_bundle.segment_image() | |
| analysis_results = {} | |
| # overlay_images = [] | |
| # if analyze_hair: | |
| # hair_mask = segmentation_maps["hair_mask"] | |
| # # analysis_results['hair_analysis'] = analyze_hair_function(image, hair_mask) | |
| # overlay_images.append(segmentation_maps["hair_mask"]) | |
| if analyze_skin: | |
| skin_mask = segmentation_maps["face_skin_mask"] | |
| skin_analysis = analyze_skin_function( | |
| image, | |
| skin_mask, | |
| l_min_skin, | |
| l_max_skin, | |
| l_min_tonality, | |
| l_max_tonality, | |
| chroma_thresh, | |
| ) | |
| if "filtered_skin_mask" in skin_analysis: | |
| filtered_skin_mask = skin_analysis["filtered_skin_mask"] | |
| del skin_analysis["filtered_skin_mask"] | |
| if "l_hist" in skin_analysis: | |
| l_hist = skin_analysis["l_hist"] | |
| del skin_analysis["l_hist"] | |
| if "tonality_l_hist" in skin_analysis: | |
| tonality_l_hist = skin_analysis["tonality_l_hist"] | |
| del skin_analysis["tonality_l_hist"] | |
| if "chroma_hist" in skin_analysis: | |
| chroma_hist = skin_analysis["chroma_hist"] | |
| del skin_analysis["chroma_hist"] | |
| # analysis_results["skin_analysis"] = skin_analysis | |
| # Create bar charts for analysis results | |
| chroma_chart = create_pie_chart(skin_analysis["chroma_counts"], "Chroma Counts") | |
| undertone_chart = create_pie_chart( | |
| skin_analysis["undertone_counts"], "Undertone Counts" | |
| ) | |
| overtone_chart = create_bar_chart( | |
| skin_analysis["overtone_counts"], "Overtone Counts", 1 | |
| ) | |
| tonality_chart = create_pie_chart( | |
| skin_analysis["tonality_counts"], "Tonality Counts" | |
| ) | |
| season_chart = create_bar_chart( | |
| skin_analysis["season_counts"], "Season Counts", 3 | |
| ) | |
| # overlay_images.append(skin_analysis["overlay_image"]) | |
| # if analyze_eyes: | |
| # eye_mask = segmentation_maps["right_iris_mask"] | segmentation_maps["left_iris_mask"] | |
| # # analysis_results['eye_analysis'] = analyze_eye_function(image, eye_mask) | |
| # overlay_images.append(eye_mask) | |
| # Combine overlay images | |
| overlay = image.copy() | |
| overlay[filtered_skin_mask > 0] = (0, 0, 255) # Red for skin | |
| overlay = cv2.addWeighted(image, 0.85, overlay, 0.15, 0) | |
| # Convert combined_overlay to PIL Image for display | |
| combined_overlay = Image.fromarray(overlay) | |
| # Resize images before returning | |
| combined_overlay = resize_image(combined_overlay) | |
| # l_hist = resize_image(l_hist) | |
| # tonality_l_hist = resize_image(tonality_l_hist) | |
| # chroma_hist = resize_image(chroma_hist) | |
| # chroma_chart = resize_image(chroma_chart) | |
| # undertone_chart = resize_image(undertone_chart) | |
| # overtone_chart = resize_image(overtone_chart) | |
| # tonality_chart = resize_image(tonality_chart) | |
| # season_chart = resize_image(season_chart) | |
| return ( | |
| combined_overlay, | |
| l_hist, | |
| tonality_l_hist, | |
| chroma_hist, | |
| # analysis_results, | |
| chroma_chart, | |
| undertone_chart, | |
| overtone_chart, | |
| tonality_chart, | |
| season_chart, | |
| ) | |
| with gr.Blocks() as demo: | |
| with gr.Row(): | |
| with gr.Column(): | |
| skin_checkbox = gr.Checkbox(label="Skin Analysis", value=True) | |
| submit_button = gr.Button("Submit") | |
| with gr.Column(): | |
| eye_checkbox = gr.Checkbox(label="Eye Analysis", value=False) | |
| hair_checkbox = gr.Checkbox(label="Hair Analysis", value=False) | |
| with gr.Row(): | |
| with gr.Column(): | |
| upload_image = gr.Image(type="numpy", label="Upload an Image") | |
| with gr.Column(): | |
| l_min_slider = gr.Slider( | |
| minimum=0, maximum=100, value=10, label="L(%) Min Skin" | |
| ) | |
| l_max_slider = gr.Slider( | |
| minimum=0, maximum=100, value=90, label="L(%) Max Skin" | |
| ) | |
| l_hist_output = gr.Plot(label="L Histogram") | |
| # processed_image_output = gr.Image(type="pil", label="Processed Image") | |
| with gr.Row(): | |
| with gr.Column(): | |
| processed_image_output = gr.Image(type="pil", label="Processed Image") | |
| with gr.Column(): | |
| undertone_chart_output = gr.Plot(label="Undertone Counts") | |
| with gr.Row(): | |
| with gr.Column(): | |
| tonality_min_slider = gr.Slider( | |
| minimum=0, maximum=100, value=50, label="L(%) Min Tonality" | |
| ) | |
| tonality_max_slider = gr.Slider( | |
| minimum=0, maximum=100, value=70, label="L(%) Max Tonality" | |
| ) | |
| tonality_hist_output = gr.Plot(label="Tonality L Histogram") | |
| with gr.Column(): | |
| tonality_chart_output = gr.Plot(label="Tonality Counts") | |
| # with gr.Row(): | |
| # submit_button = gr.Button("Submit") | |
| with gr.Row(): | |
| with gr.Column(): | |
| chroma_slider = gr.Slider( | |
| minimum=0, maximum=100, value=50, label="Chroma(%) Threshold" | |
| ) | |
| chroma_hist_output = gr.Plot(label="Chroma Histogram") | |
| with gr.Column(): | |
| chroma_chart_output = gr.Plot(label="Chroma Counts") | |
| with gr.Row(): | |
| with gr.Column(): | |
| overtone_chart_output = gr.Plot(label="Overtone Counts") | |
| with gr.Column(): | |
| season_chart_output = gr.Plot(label="Season Counts") | |
| inputs = [ | |
| upload_image, | |
| l_min_slider, | |
| l_max_slider, | |
| tonality_min_slider, | |
| tonality_max_slider, | |
| chroma_slider, | |
| skin_checkbox, | |
| eye_checkbox, | |
| hair_checkbox, | |
| ] | |
| outputs = [ | |
| processed_image_output, | |
| l_hist_output, | |
| tonality_hist_output, | |
| chroma_hist_output, | |
| chroma_chart_output, | |
| undertone_chart_output, | |
| overtone_chart_output, | |
| tonality_chart_output, | |
| season_chart_output, | |
| ] | |
| # Set up change event triggers for the sliders | |
| l_min_slider.change(process_image, inputs=inputs, outputs=outputs) | |
| l_max_slider.change(process_image, inputs=inputs, outputs=outputs) | |
| tonality_min_slider.change(process_image, inputs=inputs, outputs=outputs) | |
| tonality_max_slider.change(process_image, inputs=inputs, outputs=outputs) | |
| chroma_slider.change(process_image, inputs=inputs, outputs=outputs) | |
| # upload_image.change(process_image, inputs=inputs, outputs=outputs) | |
| skin_checkbox.change(process_image, inputs=inputs, outputs=outputs) | |
| eye_checkbox.change(process_image, inputs=inputs, outputs=outputs) | |
| hair_checkbox.change(process_image, inputs=inputs, outputs=outputs) | |
| # Link the submit button to the analyze_image function | |
| submit_button.click(process_image, inputs=inputs, outputs=outputs) | |
| demo.launch() | |