File size: 2,858 Bytes
d2454ee
 
 
 
 
7ddf71b
d2454ee
417a04e
d2454ee
7ddf71b
417a04e
 
d2454ee
 
 
 
417a04e
d2454ee
417a04e
 
 
7ddf71b
417a04e
d2454ee
417a04e
d2454ee
 
 
 
 
 
7ddf71b
 
 
 
 
 
 
 
417a04e
7ddf71b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417a04e
7ddf71b
 
 
 
 
d2454ee
 
 
 
7ddf71b
417a04e
7ddf71b
 
 
 
 
 
 
d2454ee
 
7ddf71b
 
 
 
 
d2454ee
 
 
 
7ddf71b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import gradio as gr
from transformers import pipeline
from PIL import Image
import torch
from torchvision import transforms
import re

# MODELES
INGREDIENT_MODEL_ID = "stchakman/Fridge_Items_Model"
RECIPE_MODEL_ID     = "flax-community/t5-recipe-generation"

# PIPELINES
ingredient_classifier = pipeline(
    "image-classification",
    model=INGREDIENT_MODEL_ID,
    device=0 if torch.cuda.is_available() else -1,
    top_k=5
)
recipe_generator = pipeline(
    "text2text-generation",
    model=RECIPE_MODEL_ID,
    device=0 if torch.cuda.is_available() else -1,
)

# AUGMENTATION
augment = transforms.Compose([
    transforms.RandomHorizontalFlip(p=0.5),
    transforms.RandomRotation(10),
    transforms.ColorJitter(brightness=0.2, contrast=0.2),
])

def parse_recipe_text(raw: str):
    """
    Parse le texte brut retourne par le modele en JSON { ingredients: [...], steps: [...] }.
    """
    raw = raw.replace("ingredients: ingredients:", "ingredients:")
    # On cherche la section ingredients et directions
    ing_match = re.search(r"ingredients:\s*(.*?)\s*directions:", raw, re.IGNORECASE | re.DOTALL)
    dir_match = re.search(r"directions:\s*(.+)$", raw, re.IGNORECASE | re.DOTALL)

    # ingredients
    ingredients = []
    if ing_match:
        ing_str = ing_match.group(1).strip()
        parts = re.findall(r"(\d+\s+[^\d,\.]+(?: [^\d,\.]+)*)", ing_str)
        if parts:
            ingredients = [p.strip() for p in parts]
        else:
            ingredients = [i.strip() for i in ing_str.split(",") if i.strip()]

    # etapes
    steps = []
    if dir_match:
        steps_str = dir_match.group(1).strip()
        for s in re.split(r"\.\s*", steps_str):
            s = s.strip()
            if s:
                steps.append(s.endswith(".") and s or s + ".")

    return {"ingredients": ingredients, "steps": steps}

def generate_recipe_json(image: Image.Image):
    # Aug
    image_aug = augment(image)
    results = ingredient_classifier(image_aug)
    ingredients = [res["label"] for res in results]
    ingredient_str = ", ".join(ingredients)
    prompt = f"Ingredients: {ingredient_str}. Recipe:"
    raw = recipe_generator(prompt, max_new_tokens=256, do_sample=True)[0]["generated_text"]

    parsed = parse_recipe_text(raw)
    return {
        "detected_ingredients": ingredients,
        "recipe_text": raw,
        "ingredients_parsed": parsed["ingredients"],
        "steps": parsed["steps"]
    }

interface = gr.Interface(
    fn=generate_recipe_json,
    inputs=gr.Image(type="pil", label="📷 Image de vos ingredients"),
    outputs="json",
    title="🧑‍🍳 Generateur de Recettes (JSON) 🧑‍🍳",
    description="Depose une image d'ingredients, recupere directement un JSON structure avec ingredients et etapes.",
    allow_flagging="never"
)

if __name__ == "__main__":
    interface.launch(share=True)