savitha7's picture
update response with height
2152bda verified
raw
history blame
6.06 kB
import gradio as gr
from transformers import CLIPProcessor, CLIPModel
from PIL import Image
# Load the model and processor
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
# Define the broad BMI classes for Model 1
bmi_classes_model1 = [
"underweight (x < 18.5 BMI)",
"normal weight (18.5 < x < 25 BMI)",
"overweight (25 BMI < x < 30)",
"obesity (x > 30 BMI)"
]
# Define the finer BMI ranges for Model 2
bmi_ranges_model2 = {
"underweight (x < 18.5 bmi)": [
"BMI less than 16.0",
"BMI between 16.0 and 16.99",
"BMI between 17.0 and 18.49"
],
"normal weight (18.5 < x < 25 bmi)": [
"BMI between 18.5 and 20.4",
"BMI between 20.5 and 22.4",
"BMI between 22.5 and 24.9"
],
"overweight (25 bmi < x < 30)": [
"BMI between 25.0 and 26.9",
"BMI between 27.0 and 28.9",
"BMI between 29.0 and 29.9"
],
"obesity (x > 30 bmi)": [
"BMI between 30.0 and 34.9",
"BMI between 35.0 and 39.9",
"BMI 40.0 and above"
]
}
bmi_mapp = {
"BMI less than 16.0":"BMI < 16.0",
"BMI between 16.0 and 16.99":"16.0 ≤ BMI ≤ 16.99",
"BMI between 17.0 and 18.49":"17.0 ≤ BMI ≤ 18.49",
"BMI between 18.5 and 20.4":"18.5 ≤ BMI ≤ 20.4",
"BMI between 20.5 and 22.4":"20.5 ≤ BMI ≤ 22.4",
"BMI between 22.5 and 24.9":"22.5 ≤ BMI ≤ 24.9",
"BMI between 25.0 and 26.9":"25.0 ≤ BMI ≤ 26.9",
"BMI between 27.0 and 28.9":"27.0 ≤ BMI ≤ 28.9",
"BMI between 29.0 and 29.9":"29.0 ≤ BMI ≤ 29.9",
"BMI between 30.0 and 34.9": "30.0 ≤ BMI ≤ 34.9",
"BMI between 35.0 and 39.9": "35.0 ≤ BMI ≤ 39.9",
"BMI 40.0 and above":"BMI ≥ 40.0"
}
# Define BMI ranges with boundaries and midpoints for adjusted BMI calculation
bmi_ranges = {
"underweight (x < 18.5 bmi)": {
"BMI < 16.0": (0, 16.0, 16.0), # Upper boundary 16.0
"16.0 ≤ BMI ≤ 16.99": (16.0, 16.99, 16.5), # Midpoint 16.5
"17.0 ≤ BMI ≤ 18.49": (17.0, 18.49, 17.75) # Midpoint 17.75
},
"normal weight (18.5 < x < 25 bmi)": {
"18.5 ≤ BMI ≤ 20.4": (18.5, 20.4, 19.45), # Midpoint 19.45
"20.5 ≤ BMI ≤ 22.4": (20.5, 22.4, 21.45), # Midpoint 21.45
"22.5 ≤ BMI ≤ 24.9": (22.5, 24.9, 23.7) # Midpoint 23.7
},
"overweight (25 bmi < x < 30)": {
"25.0 ≤ BMI ≤ 26.9": (25.0, 26.9, 25.95), # Midpoint 25.95
"27.0 ≤ BMI ≤ 28.9": (27.0, 28.9, 27.95), # Midpoint 27.95
"29.0 ≤ BMI ≤ 29.9": (29.0, 29.9, 29.45) # Midpoint 29.45
},
"obesity (x > 30 bmi)": {
"30.0 ≤ BMI ≤ 34.9": (30.0, 34.9, 32.5), # Midpoint 32.5
"35.0 ≤ BMI ≤ 39.9": (35.0, 39.9, 37.45), # Midpoint 37.45
"BMI ≥ 40.0": (40.0, 100, 40.0) # Lower boundary 40.0
}
}
def predict_bmi(image, height_in_inches):
# Prepare inputs for Model 1
inputs_model1 = processor(text=bmi_classes_model1, images=image, return_tensors="pt", padding=True)
outputs_model1 = model(**inputs_model1)
probs_model1 = outputs_model1.logits_per_image.softmax(dim=1)
print(probs_model1,'probs_model1')
# Get the broad category prediction from Model 1
max_prob_index_model1 = probs_model1.argmax().item()
predicted_bmi_class = bmi_classes_model1[max_prob_index_model1]
print(predicted_bmi_class,'predicted_bmi_class')
# Select class names for Model 2 based on Model 1's prediction
model2_classes = bmi_ranges_model2[predicted_bmi_class.lower()]
print(model2_classes,'model2_classes')
# Prepare inputs for Model 2
inputs_model2 = processor(text=model2_classes, images=image, return_tensors="pt", padding=True)
outputs_model2 = model(**inputs_model2)
probs_model2 = outputs_model2.logits_per_image.softmax(dim=1)
print(probs_model2,'probs_model2')
# Get the finer range prediction from Model 2
max_prob_index_model2 = probs_model2.argmax().item()
finer_bmi_range = model2_classes[max_prob_index_model2]
print(finer_bmi_range,'finer_bmi_range')
# Determine the BMI prediction based on the range
bmi_prediction = get_adjusted_bmi(predicted_bmi_class, finer_bmi_range)
print(bmi_prediction)
# Calculate weight using user-provided height
predicted_weight = calculate_weight(bmi_prediction, height_in_inches)
# Create the JSON output
result = {
"weightCategory": f"{predicted_bmi_class} - {finer_bmi_range}",
"bmiPrediction": f"{bmi_prediction:.2f}",
"height": str(height_in_inches),
"predictedWeight": f"{predicted_weight:.2f} lbs"
}
return result
def get_adjusted_bmi(weight_category, finer_range):
"""Return the appropriate BMI value for the given finer range within the weight category."""
category_ranges = bmi_ranges.get(weight_category.lower())
print(category_ranges,'category_ranges')
for range_label, (low, high, mid) in category_ranges.items():
print(range_label,'range_label')
if range_label == bmi_mapp[finer_range]:
return mid
"""elif "BMI <" in range_label or "BMI ≥" in range_label:
return high if "BMI <" in range_label else low"""
return None
def calculate_weight(bmi, height_in_inches):
"""Calculate the weight from BMI and height (in inches)."""
height_in_meters = height_in_inches * 0.0254
weight_kg = bmi * (height_in_meters ** 2)
weight_lbs = weight_kg * 2.20462
return weight_lbs
# Create Gradio interface with updated input components
interface = gr.Interface(
fn=predict_bmi,
inputs=[
gr.Image(type="pil"),
gr.Number(label="Height in inches") # Allow user to enter height
],
outputs="json",
title="BMI Prediction",
description="Upload an image and enter your height to predict BMI category and receive a detailed prediction."
)
interface.launch()