|
import numpy as np |
|
import pandas as pd |
|
import gradio as gr |
|
from tensorflow.keras.applications import MobileNetV2 |
|
from tensorflow.keras.preprocessing.image import load_img, img_to_array |
|
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input, decode_predictions |
|
from fuzzywuzzy import fuzz |
|
from transformers import pipeline |
|
import requests |
|
from PIL import Image |
|
from io import BytesIO |
|
|
|
|
|
models = { |
|
"Flan-T5 Small": pipeline("text2text-generation", model="BhavaishKumar112/flan-t5-small"), |
|
"GPT-Neo 125M": pipeline("text-generation", model="BhavaishKumar112/gpt-neo-125M"), |
|
"Final GPT-2 Trained": pipeline("text-generation", model="BhavaishKumar112/finalgpt2trained") |
|
} |
|
|
|
|
|
cuisines = ["Thai", "Indian", "Chinese", "Italian"] |
|
|
|
|
|
dataset_path = "Food_Recipe.csv" |
|
data_df = pd.read_csv(dataset_path) |
|
|
|
|
|
mobilenet_model = MobileNetV2(weights="imagenet") |
|
|
|
|
|
def preprocess_image(image_path, target_size=(224, 224)): |
|
image = load_img(image_path, target_size=target_size) |
|
image_array = img_to_array(image) |
|
image_array = np.expand_dims(image_array, axis=0) |
|
return preprocess_input(image_array) |
|
|
|
|
|
def classify_image(image): |
|
try: |
|
image_array = preprocess_image(image) |
|
predictions = mobilenet_model.predict(image_array) |
|
decoded_predictions = decode_predictions(predictions, top=3)[0] |
|
return decoded_predictions |
|
except Exception as e: |
|
print(f"Error during classification: {e}") |
|
return [] |
|
|
|
|
|
def map_to_recipe(classification_results): |
|
for result in classification_results: |
|
best_match = None |
|
best_score = 0 |
|
for index, row in data_df.iterrows(): |
|
score = fuzz.partial_ratio(result[1].lower(), row["name"].lower()) |
|
if score > best_score: |
|
best_score = score |
|
best_match = row |
|
if best_score >= 70: |
|
return best_match |
|
return None |
|
|
|
|
|
def generate_summary(recipe): |
|
ingredients = recipe.get("ingredients_name", "No ingredients provided") |
|
time_to_cook = recipe.get("time_to_cook", "Time to cook not provided") |
|
instructions = recipe.get("instructions", "No instructions provided") |
|
return f"Ingredients: {ingredients}\n\nTime to Cook: {time_to_cook}\n\nInstructions: {instructions}" |
|
|
|
|
|
def get_recipe_details(image): |
|
classification_results = classify_image(image) |
|
if not classification_results: |
|
return "Error: No classification results found for the image." |
|
recipe = map_to_recipe(classification_results) |
|
if recipe is not None: |
|
return generate_summary(recipe) |
|
else: |
|
return "No matching recipe found for this image." |
|
|
|
|
|
def generate_recipe(input_text, selected_model, selected_cuisine): |
|
prompt = ( |
|
f"Generate a detailed and structured {selected_cuisine} recipe for {input_text}. " |
|
f"Include all the necessary details such as ingredients under an 'Ingredients' heading " |
|
f"and steps under a 'Recipe' heading. Ensure the response is concise and well-organized." |
|
) |
|
model = models[selected_model] |
|
output = model(prompt, max_length=500, num_return_sequences=1)[0]['generated_text'] |
|
return output |
|
|
|
|
|
def fetch_recipe_image(recipe_name): |
|
matching_row = data_df[data_df['name'].str.contains(recipe_name, case=False, na=False)] |
|
if not matching_row.empty: |
|
image_url = matching_row.iloc[0]['image_url'] |
|
try: |
|
response = requests.get(image_url) |
|
img = Image.open(BytesIO(response.content)) |
|
return img |
|
except Exception as e: |
|
return f"Error fetching image: {e}" |
|
else: |
|
return "No matching recipe found. Please check the recipe name." |
|
|
|
|
|
def main(): |
|
with gr.Blocks(css=""" |
|
body { |
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
|
background-color: #1c1c1c; /* Dark background for high contrast */ |
|
margin: 0; |
|
padding: 0; |
|
color: #e0e0e0; /* Light text for contrast */ |
|
} |
|
.chat-container { |
|
max-width: 800px; |
|
margin: 30px auto; |
|
padding: 20px; |
|
background: #333333; /* Dark gray background */ |
|
border-radius: 16px; |
|
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); |
|
} |
|
.chat-header { |
|
text-align: center; |
|
font-size: 32px; |
|
font-weight: bold; |
|
color: #ff9800; /* Orange for visibility */ |
|
margin-bottom: 20px; |
|
} |
|
.chat-input { |
|
width: 100%; |
|
padding: 14px; |
|
font-size: 16px; |
|
border-radius: 12px; |
|
border: 1px solid #ff9800; /* Orange border */ |
|
margin-bottom: 15px; |
|
background-color: #424242; /* Dark input field */ |
|
color: #e0e0e0; /* Light text */ |
|
} |
|
.chat-button { |
|
background-color: #ff9800; |
|
color: white; |
|
border: none; |
|
padding: 12px 24px; |
|
font-size: 16px; |
|
border-radius: 12px; |
|
cursor: pointer; |
|
} |
|
.chat-button:hover { |
|
background-color: #e65100; /* Darker orange for hover */ |
|
} |
|
.chat-output { |
|
padding: 15px; |
|
background: #424242; /* Dark gray background for output */ |
|
border-radius: 10px; |
|
border: 1px solid #616161; /* Light gray border */ |
|
color: #e0e0e0; /* Light text */ |
|
white-space: pre-wrap; |
|
min-height: 120px; |
|
} |
|
.tab-title { |
|
font-weight: bold; |
|
font-size: 22px; |
|
color: #ff9800; /* Orange text for tab title */ |
|
} |
|
.tab-button { |
|
background-color: #616161; |
|
color: #ff9800; |
|
border: 1px solid #ff9800; |
|
padding: 12px; |
|
border-radius: 12px; |
|
} |
|
.tab-button:hover { |
|
background-color: #ff5722; /* Bright orange for tab button hover */ |
|
} |
|
.icon { |
|
font-size: 20px; |
|
margin-right: 10px; |
|
} |
|
.gradio-container { |
|
margin-top: 20px; |
|
} |
|
""") as app: |
|
|
|
with gr.Tab("Recipe Generator"): |
|
gr.HTML("<div class='chat-container'><div class='chat-header'><i class='icon'>🍽</i>Recipe Generator</div><p class='tab-title'>Enter a recipe name or ingredients, select a cuisine and model, and get structured recipe instructions!</p></div>") |
|
recipe_input = gr.Textbox(label="Enter Recipe Name or Ingredients", placeholder="e.g., Chicken curry or chicken, garlic, onions", elem_classes=["chat-input"]) |
|
selected_cuisine = gr.Radio(choices=cuisines, label="Cuisine", value="Indian") |
|
selected_model = gr.Radio(choices=list(models.keys()), label="Model", value="Flan-T5 Small") |
|
recipe_output = gr.Textbox(label="Recipe", lines=15, elem_classes=["chat-output"]) |
|
generate_button = gr.Button("Generate Recipe", elem_classes=["chat-button"]) |
|
generate_button.click(generate_recipe, inputs=[recipe_input, selected_model, selected_cuisine], outputs=recipe_output) |
|
|
|
with gr.Tab("Recipe Finder from Image"): |
|
gr.HTML("<div class='chat-container'><div class='chat-header'><i class='icon'>📸</i>Recipe Finder from Image</div><p class='tab-title'>Upload an image of a dish to find a matching recipe.</p></div>") |
|
image_input = gr.Image(type="filepath", label="Upload an Image") |
|
image_output = gr.Textbox(label="Recipe Details", lines=10, elem_classes=["chat-output"]) |
|
image_input.change(get_recipe_details, inputs=image_input, outputs=image_output) |
|
|
|
with gr.Tab("Recipe Image Search"): |
|
gr.HTML("<div class='chat-container'><div class='chat-header'><i class='icon'>📷</i>Recipe Image Search</div><p class='tab-title'>Enter the name of a recipe to view its image.</p></div>") |
|
recipe_name_input = gr.Textbox(label="Recipe Name", placeholder="e.g., Mixed Sprouts in Chettinad Masala Recipe", elem_classes=["chat-input"]) |
|
recipe_image_output = gr.Image(label="Recipe Image") |
|
fetch_image_button = gr.Button("Generate Image", elem_classes=["chat-button"]) |
|
fetch_image_button.click(fetch_recipe_image, inputs=recipe_name_input, outputs=recipe_image_output) |
|
|
|
app.launch() |
|
|
|
if __name__ == "__main__": |
|
main() |