| <!DOCTYPE html> |
| <html lang="en"> |
|
|
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}"> |
| <title>MIE1517 Final Project</title> |
| </head> |
|
|
| <body> |
| <header class="header"> |
| <div class="container1"> |
| <div class="header-content"> |
| <h1 class="logo">MIE1517 Final Project</h1> |
| <nav> |
| <ul class="nav-links"> |
| <li><a href="http://127.0.0.1:5000">Home</a></li> |
| <li><a href="#">Final Report</a></li> |
| <li><a href="#">Project Presentation</a></li> |
| <li><a href="#">Reference</a></li> |
| </ul> |
| </nav> |
| </div> |
| </div> |
| </header> |
|
|
| <section class="intro"> |
| <div class="container"> |
| <div class="intro-content"> |
| <h2>Generated the recipe based on what you have</h2> |
| <p>By Zixiao Qiu, Wensha Sun, YuHan Cheng, Jiamei Shu</p> |
| </div> |
| </div> |
| </section> |
|
|
| <section class="instruction"> |
| <div class="container"> |
| <div class="inst-content"> |
| <h2>How to use?</h2> |
| <p>Upload the image of your fridge, and we will provide a recipe based on your current ingredients.</p> |
| <h3>Running Steps</h3> |
| <ol class="steps"> |
| <li>Our SAM2 + ResNet model will recognize the ingredients in the fridge.</li> |
| <li>The output will be the input to our LLM model.</li> |
| <li>By connecting to the OpenAI API, GPT4o-mini will generate the recipe and provide the essential |
| cooking steps.</li> |
| <li>Now, you can follow the recipe to cook your meal.</li> |
| </ol> |
| </div> |
| </div> |
| </section> |
|
|
| <div class="container"> |
| <div class="result-section" style="display: block;"> |
| <h2>Example Generated Recipe</h2> |
| <div class="recipe-container"> |
| <div class="recipe-image"> |
| <img class="recipe-image-demo" |
| src="{{ url_for('static', filename='images/15761732485695_.pic.png') }}" alt="Recipe Image" |
| style="max-width: 100%; display: block;"> |
| </div> |
| <div class="recipe-text"> |
| <p class="recipe-result-demo"><strong>Detected Ingredient:</strong> onion, cabbage, cucumber, |
| cauliflower, |
| ginger, potato, egg, garlic<br><br><strong>Generated Recipe:</strong> |
| <ol> |
| <li>Here are three possible recipes using the provided ingredients:</li> |
| <h4>1. Cabbage and Cauliflower Stir-Fry</h4> |
| <li>**Essential Cooking Steps:**</li> |
| <li>1. Heat oil in a pan and sauté chopped onion and minced garlic until translucent.</li> |
| <li>2. Add chopped ginger and cook for another minute.</li> |
| <li>3. Add chopped cabbage and cauliflower florets, stir-frying until tender.</li> |
| <li>4. Season with salt and pepper to taste.</li> |
| <li>5. Serve hot as a side dish.</li> |
| <h4>2. Vegetable Egg Curry</h4> |
| <li>**Essential Cooking Steps:**</li> |
| <li>1. Boil potatoes and cauliflower until tender, then chop them into bite-sized pieces.</li> |
| <li>2. In a pan, heat oil and sauté chopped onion and minced garlic until golden.</li> |
| <li>3. Add chopped ginger, followed by the boiled vegetables, and mix well.</li> |
| <li>4. Add spices (like turmeric, cumin, and chili powder) and cook for a few minutes.</li> |
| <li>5. Beat eggs and pour them over the vegetable mixture, stirring gently until the eggs are |
| cooked |
| through.</li> |
| <li>6. Serve with rice or bread.</li> |
| <h4>3. Cucumber and Cabbage Salad with Ginger Dressing</h4> |
| <li>**Essential Cooking Steps:**</li> |
| <li>1. Thinly slice cucumber and shred cabbage.</li> |
| <li>2. In a bowl, mix together minced garlic, grated ginger, salt, and a splash of vinegar or |
| lemon |
| juice for the dressing.</li> |
| <li>3. Toss the cucumber and cabbage with the dressing until well coated.</li> |
| <li>4. Let it sit for a few minutes to marinate before serving.</li> |
| <li>5. Optionally, top with boiled egg slices for added protein.</li> |
| <li>Enjoy your cooking!</li> |
| </ol> |
| </p> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <section class="upload-section"> |
| <div class="container"> |
| <div class="upload-content"> |
| <h2>Upload Your Fridge Image</h2> |
| <form id="upload-form" action="#" method="post" enctype="multipart/form-data"> |
| <label for="fridge-image">Select an image of your fridge:</label> |
| <input type="file" id="fridge-image" name="fridge-image" accept="image/*" required> |
| <button type="submit" class="upload-btn">Upload Image</button> |
| </form> |
| <div id="loading-message" class="loading-message" style="display: none;"> |
| <p>Processing your image, please wait...</p> |
| </div> |
| <div id="result-section" class="result-section" style="display: none;"> |
| <h2>Generated Recipe</h2> |
| <div class="recipe-container"> |
| <div class="recipe-image"> |
| <img id="recipe-image" src="#" alt="Recipe Image" style="max-width: 100%; display: none;"> |
| </div> |
| <div class="recipe-text"> |
| <p id="recipe-result">The recipe will be displayed here after processing.</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </section> |
|
|
|
|
| <footer class="footer"> |
| <div class="container"> |
| <p>© 2024 MIE1517 Project Team. All rights reserved.</p> |
| </div> |
| </footer> |
|
|
| <script> |
| const uploadForm = document.getElementById('upload-form'); |
| const loadingMessage = document.getElementById('loading-message'); |
| const resultSection = document.getElementById('result-section'); |
| const recipeResult = document.getElementById('recipe-result'); |
| const recipeImage = document.getElementById('recipe-result'); |
| |
| uploadForm.addEventListener('submit', function (event) { |
| event.preventDefault(); |
| loadingMessage.style.display = 'block'; |
| resultSection.style.display = 'none'; |
| |
| const formData = new FormData(uploadForm); |
| |
| |
| const file = formData.get('fridge-image'); |
| if (file) { |
| const reader = new FileReader(); |
| reader.onload = function (e) { |
| document.getElementById('recipe-image').src = e.target.result; |
| document.getElementById('recipe-image').style.display = 'block'; |
| }; |
| reader.readAsDataURL(file); |
| } |
| |
| |
| |
| fetch('/upload', { |
| method: 'POST', |
| body: formData |
| }) |
| .then(response => response.json()) |
| .then(data => { |
| document.getElementById('loading-message').style.display = 'none'; |
| document.getElementById('result-section').style.display = 'block'; |
| |
| if (data.error) { |
| document.getElementById('recipe-result').textContent = `Error: ${data.error}`; |
| } else { |
| const detectedIngredientHTML = `<strong>Detected Ingredient:</strong> ${data.ingredient}<br><br>`; |
| |
| |
| const steps = data.recipe.split(/\n+/).filter(line => line.trim() !== ''); |
| |
| |
| let formattedRecipe = ''; |
| steps.forEach((step, index) => { |
| if (step.includes("###")) { |
| |
| formattedRecipe += `<h4>${step.replace("###", "").trim()}</h4>`; |
| } else { |
| |
| formattedRecipe += `<li>${step.trim()}</li>`; |
| } |
| }); |
| |
| |
| const recipeHTML = `<strong>Generated Recipe:</strong><ol>${formattedRecipe}</ol>`; |
| |
| recipeResult.innerHTML = detectedIngredientHTML + recipeHTML; |
| } |
| }) |
| |
| |
| |
| .catch(error => { |
| loadingMessage.style.display = 'none'; |
| resultSection.style.display = 'block'; |
| recipeResult.textContent = `Error: ${error.message}`; |
| }); |
| }); |
| |
| </script> |
| </body> |
|
|
| </html> |