import PIL from torchvision import datasets, transforms, models import torch from PIL import Image import torch.nn as nn import pandas as pd import numpy as np import numpy import gradio as gr # import warnings # warnings.filterwarnings("ignore", category=UserWarning) class_names = ['apple_pie', 'bibimbap', 'cannoli', 'edamame', 'falafel', 'french_toast', 'ramen', 'sushi', 'tiramisu'] # def pil_loader(path): # with open(path, 'rb') as f: # img = Image.open(f) # return img.convert('RGB') # def predict(img_path): # # Load and preprocess the image # # image = pil_loader(img_path) # # Convert Gradio image input to a NumPy array # img_array = img_path.astype(np.uint8) # # # Convert NumPy array to PIL Image # image = Image.fromarray(img_array) # test_transforms = transforms.Compose([ # transforms.Resize(256), # transforms.CenterCrop(224), # transforms.ToTensor(), # transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # ]) # # Apply transformations # image = test_transforms(image) # inf_model = models.resnet18(pretrained=False) # num_ftrs = inf_model.fc.in_features # # Here the size of each output sample is set to 2. # # Alternatively, it can be generalized to nn.Linear(num_ftrs, len(class_names)). # inf_model.fc = nn.Linear(num_ftrs, len(class_names)) # # model_1 = model_1.to(device) # inf_model.to(torch.device('cpu')) # inf_model.load_state_dict(torch.load('./resnet18_tinyfood_classifier.pth', map_location='cpu')) # # Perform inference # with torch.no_grad(): # inf_model.eval() # out = inf_model(image.unsqueeze(0)) # Add batch dimension # # Get the predicted class and confidence # _, preds = torch.max(out, 1) # idx = preds.cpu().numpy()[0] # pred_class = class_names[idx] # # Assuming `out` is logits, you may need to apply softmax instead of sigmoid # probabilities = torch.softmax(out, dim=1) # Apply softmax to get probabilities # confidence = probabilities[0, idx].item() * 100 # Get confidence for the predicted class # nutrition_data_path = './food-data.csv' # # Membaca file CSV # df = pd.read_csv(nutrition_data_path) # # Mencocokkan prediksi dengan data CSV # if pred_class.capitalize() in df["Makanan"].values: # row = df.loc[df["Makanan"] == pred_class.capitalize()] # # Convert int64 values to native Python data types # calories = int(row["Kalori"].values[0]) # protein = int(row["Protein"].values[0]) # fat = int(row["Lemak"].values[0]) # carbs = int(row["Karbohidrat"].values[0]) # fiber = int(row["Serat"].values[0]) # sugar = int(row["Gula"].values[0]) # price = int(row["Harga (Rp)"].values[0]) # # # Mengambil informasi gizi # # calories = row["Kalori"].values[0] # # protein = row["Protein"].values[0] # # fat = row["Lemak"].values[0] # # carbs = row["Karbohidrat"].values[0] # # fiber = row["Serat"].values[0] # # sugar = row["Gula"].values[0] # # price = row["Harga (Rp)"].values[0] # return pred_class, calories, protein, fat, carbs, fiber, sugar, price # else: # nutrition_info = None # return 'Food not found', 0, 0, 0, 0, 0, 0 # # return pred_class, confidence # img_path = '/content/drive/MyDrive/Assignment-Citra-SkillacademyAI/bibimbap.jpeg' # print(predict(img_path)) def pil_loader(path): # Define a function to load an image using PIL and convert it to RGB format with open(path, 'rb') as f: with open(path, 'rb') as f: img = Image.open(f) return img.convert('RGB') def predict(img_path): # Load and preprocess the image ##### Uncomment: without gradio # image = pil_loader(img_path) ##### Uncomment: with gradio # Convert Gradio image input to a NumPy array img_array = img_path.astype(np.uint8) # Convert NumPy array to PIL Image image = Image.fromarray(img_array) # Define transformations to apply to the image test_transforms = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # Apply transformations image = test_transforms(image) # Load a pre-trained ResNet18 model and modify the fully connected layer inf_model = models.resnet18(pretrained=False) num_ftrs = inf_model.fc.in_features # Here the size of each output sample is set to 2. # Alternatively, it can be generalized to nn.Linear(num_ftrs, len(class_names)). inf_model.fc = nn.Linear(num_ftrs, len(class_names)) # model_1 = model_1.to(device) # Move the model to CPU and load its state dict from the specified path inf_model.to(torch.device('cpu')) inf_model.load_state_dict(torch.load('./resnet18_tinyfood_classifier.pth', map_location='cpu')) # Perform inference on the image using the model with torch.no_grad(): inf_model.eval() out = inf_model(image.unsqueeze(0)) # Add batch dimension # Get the predicted class and confidence _, preds = torch.max(out, 1) idx = preds.cpu().numpy()[0] pred_class = class_names[idx] # Assuming `out` is logits, you may need to apply softmax instead of sigmoid # Apply softmax to get probabilities and calculate confidence for the predicted class probabilities = torch.softmax(out, dim=1) # Apply softmax to get probabilities confidence = probabilities[0, idx].item() * 100 # Get confidence for the predicted class # Read nutrition data from a CSV file and match the predicted class nutrition_data_path = './food-data.csv' df = pd.read_csv(nutrition_data_path) if pred_class.capitalize() in df["Makanan"].values: row = df.loc[df["Makanan"] == pred_class.capitalize()] # Extract nutrition information for the predicted class calories = row["Kalori"].values[0] protein = row["Protein"].values[0] fat = row["Lemak"].values[0] carbs = row["Karbohidrat"].values[0] fiber = row["Serat"].values[0] sugar = row["Gula"].values[0] price = row["Harga (Rp)"].values[0] return pred_class, calories, protein, fat, carbs, fiber, sugar, price # return "Food", 1, 1, 1, 1, 1, 1 # return calories else: nutrition_info = None # Return 'Food not found' message if predicted class not in the nutrition data return 'Food not found', 0, 0, 0, 0, 0, 0 # return "Text2" # return pred_class, confidence # img_path = '/content/drive/MyDrive/Assignment-Citra-SkillacademyAI/bibimbap.jpeg' # img_path = '/content/drive/MyDrive/Assignment-Citra-SkillacademyAI/food-101-tiny/cannoli.jpeg' # print(predict(img_path)) # interface = gr.Interface( # predict, # inputs="image", # title="Cafe App", # description="This App will provide the information of your food choice in Selera Cafe. The menu includes: Apple Pie, Bibimbap, Cannoli, Edamame, Falafel, French Toast, Ramen, Sushi, Tiramisu. Enjoy your food!", # outputs=[ # gr.Text(label="Food Label"), # gr.Number(label="Calories"), # gr.Number(label="Protein"), # gr.Number(label="Fat"), # gr.Number(label="Carbs"), # gr.Number(label="Fiber"), # gr.Number(label="Sugar"), # gr.Number(label="Price") # ], # examples = [ # './bibimbap.jpeg', # './apple-pie.jpeg', # './cannoli.jpeg' # ]) # interface.launch() interface = gr.Interface( predict, inputs="image", title="Selera Cafe App", description="This App will provide the information of your food choice in Selera Cafe. The menu includes: Apple Pie, Bibimbap, Cannoli, Edamame, Falafel, French Toast, Ramen, Sushi, Tiramisu. Enjoy your food!", # outputs=gr.Text(), outputs=[ gr.Text(label="Food Label"), gr.Text(label="Calories"), gr.Text(label="Protein"), gr.Text(label="Fat"), gr.Text(label="Carbs"), gr.Text(label="Fiber"), gr.Text(label="Sugar"), gr.Text(label="Price") ], # examples = [ # '/content/drive/MyDrive/Assignment-Citra-SkillacademyAI/bibimbap.jpeg', # '/content/drive/MyDrive/Assignment-Citra-SkillacademyAI/food-101-tiny/apple-pie.jpeg', # '/content/drive/MyDrive/Assignment-Citra-SkillacademyAI/food-101-tiny/cannoli.jpeg' # ]) examples = [ './bibimbap.jpeg', './apple-pie.jpeg', './cannoli.jpeg' ]) interface.launch() # Type is not JSON serializable: numpy.int64