Spaces:
Running
Running
| # cal.py | |
| import torch | |
| from ultralytics import YOLO | |
| import cv2 | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import streamlit as st | |
| # Configuration class | |
| class Config: | |
| CLASSES = ['asparagus', 'avocados', 'broccoli', 'cabbage', #4 | |
| 'celery', 'cucumber', 'green_apples', 'green_beans', #4 | |
| 'green_capsicum', 'green_grapes', 'kiwifruit', #3 | |
| 'lettuce', 'limes', 'peas', 'spinach', #4 | |
| 'Banana', 'Cauliflower', 'Date', 'Garlic', #4 | |
| 'Ginger', 'Mushroom', 'Onion', 'Parsnip', #4 | |
| 'Peach', 'Pear', 'Potato', 'Turnip', #4 | |
| 'Beetroot', 'Blackberry', 'Blueberry', 'Cherry', #4 | |
| 'Eggplant', 'Plum', 'Purple asparagus', 'Purple grapes', #4 | |
| 'Radish', 'Raspberry', 'Red Apple', 'Red Grape', #4 | |
| 'Red cabbage', 'Red capsicum', 'Strawberry', 'Tomato', #4 | |
| 'Watermelon', 'apricot', 'carrot', 'corn', #4 | |
| 'grapefruit', 'lemon', 'mango', 'nectarine', #4 | |
| 'orange', 'pineapple', 'pumpkin', 'sweet_potato'] #4 | |
| CALORIES_DICT = { | |
| # Green foods (existing) | |
| 'asparagus': 20, | |
| 'avocados': 160, | |
| 'broccoli': 55, | |
| 'cabbage': 25, | |
| 'celery': 16, | |
| 'cucumber': 16, | |
| 'green_apples': 52, | |
| 'green_beans': 31, | |
| 'green_capsicum': 20, | |
| 'green_grapes': 69, | |
| 'kiwifruit': 61, | |
| 'lettuce': 15, | |
| 'limes': 30, | |
| 'peas': 81, | |
| 'spinach': 23, | |
| # White/Beige foods | |
| 'Banana': 89, | |
| 'Cauliflower': 25, | |
| 'Date': 282, | |
| 'Garlic': 149, | |
| 'Ginger': 80, | |
| 'Mushroom': 22, | |
| 'Onion': 40, | |
| 'Parsnip': 75, | |
| 'Peach': 39, | |
| 'Pear': 57, | |
| 'Potato': 77, | |
| 'Turnip': 28, | |
| # Purple/Red foods | |
| 'Beetroot': 43, | |
| 'Blackberry': 43, | |
| 'Blueberry': 57, | |
| 'Cherry': 50, | |
| 'Eggplant': 25, | |
| 'Plum': 46, | |
| 'Purple asparagus': 20, | |
| 'Purple grapes': 69, | |
| 'Radish': 16, | |
| 'Raspberry': 52, | |
| 'Red Apple': 52, | |
| 'Red Grape': 69, | |
| 'Red cabbage': 31, | |
| 'Red capsicum': 31, | |
| 'Strawberry': 32, | |
| 'Tomato': 18, | |
| 'Watermelon': 30, | |
| # Orange/Yellow foods | |
| 'apricot': 48, | |
| 'carrot': 41, | |
| 'corn': 86, | |
| 'grapefruit': 42, | |
| 'lemon': 29, | |
| 'mango': 60, | |
| 'nectarine': 44, | |
| 'orange': 47, | |
| 'pineapple': 50, | |
| 'pumpkin': 26, | |
| 'sweet_potato': 86 | |
| } | |
| # Load the model | |
| def load_model(): | |
| model = YOLO('./best.pt') | |
| return model | |
| # Function to make predictions on a single image | |
| def predict_image(image_path, model, conf_threshold=0.03): | |
| # Perform inference on the image | |
| results = model.predict( | |
| source=image_path, | |
| imgsz=640, | |
| conf=conf_threshold | |
| ) | |
| # Load the image for visualization | |
| image = cv2.imread(image_path) | |
| image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) | |
| # To store detailed information about detections | |
| detection_details = [] | |
| # Iterate over detections | |
| for result in results[0].boxes.data: | |
| # Extract bounding box coordinates, confidence score, and class ID | |
| x1, y1, x2, y2, confidence, class_id = result.cpu().numpy() | |
| # Draw the bounding box with top confidence score | |
| cv2.rectangle(image, (int(x1), int(y1)), (int(x2), int(y2)), color=(0, 255, 0), thickness=2) | |
| label = f"{Config.CLASSES[int(class_id)]}: {confidence:.2f}" | |
| cv2.putText(image, label, (int(x1), int(y1) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), thickness=1) | |
| # Save details for printing below | |
| detection_details.append({ | |
| "class": Config.CLASSES[int(class_id)], | |
| "top_confidence": confidence, | |
| "bbox": (x1, y1, x2, y2) | |
| }) | |
| return image, detection_details | |
| # Function to calculate detected items and their calories | |
| def calculate_calories(detection_details): | |
| """ | |
| Calculate calories for detected items, keeping only the highest confidence detection for each unique food item. | |
| Args: | |
| detection_details: List of dictionaries containing detection information | |
| Each dict has keys: "class" (food name), "top_confidence" (detection confidence), "bbox" | |
| Returns: | |
| List of tuples: (food_item, calories, confidence) for unique items with highest confidence | |
| """ | |
| # Dictionary to keep track of highest confidence detection for each food item | |
| unique_items = {} | |
| # Process each detection | |
| for det in detection_details: | |
| item = det["class"] | |
| confidence = det["top_confidence"] | |
| # Only update if this is the first instance or has higher confidence | |
| if item not in unique_items or confidence > unique_items[item]["confidence"]: | |
| unique_items[item] = { | |
| "calories": Config.CALORIES_DICT[item], | |
| "confidence": confidence | |
| } | |
| # Convert to list of tuples format | |
| detected_items = [ | |
| (item, data["calories"], data["confidence"]) | |
| for item, data in unique_items.items() | |
| ] | |
| # Sort by confidence (optional) | |
| detected_items.sort(key=lambda x: x[2], reverse=True) | |
| return detected_items |