Prathamesh Sable commited on
Commit
d576d75
·
1 Parent(s): 3edbe0b

yolo working with seg

Browse files
Files changed (1) hide show
  1. routers/analysis.py +40 -33
routers/analysis.py CHANGED
@@ -1,18 +1,22 @@
1
  import asyncio
2
  import os
3
  from datetime import datetime
 
4
  from fastapi import APIRouter, Depends, HTTPException, UploadFile, File
5
  from fastapi.responses import JSONResponse, FileResponse
 
6
  import pytz
7
  from sqlalchemy.orm import Session
8
  from typing import List, Dict, Any
9
  from db.models import User, Ingredient
10
  from interfaces.ingredientModels import IngredientAnalysisResult, IngredientRequest
11
- from interfaces.productModels import ProductIngredientsRequest,ProductData
12
  from services.auth_service import get_current_user
 
 
13
  from logger_manager import log_info, log_error, logger
14
  from db.database import get_db,SessionLocal
15
- from db.repositories import IngredientRepository, ProductRepository
16
  from dotenv import load_dotenv
17
  from langsmith import traceable
18
  import io
@@ -51,19 +55,19 @@ def ingredient_db_to_pydantic(db_ingredient):
51
  details_with_source=[source.data for source in db_ingredient.sources]
52
  )
53
 
54
-
55
  def extract_product_from_image_yolo(image_path: str) -> str | None:
56
  """Extracts the product image using YOLOv8 with preprocessing and postprocessing."""
57
  try:
58
  # Load image
59
  image = cv2.imread(image_path)
 
60
 
61
  # Preprocessing: Resize image
62
  target_size = (640, 640)
63
- image_resized = cv2.resize(image, target_size)
64
-
65
  # Run inference with YOLO
66
- results = yolo_model(image_resized)
67
 
68
  if not results:
69
  print("No objects detected by YOLO.")
@@ -73,23 +77,24 @@ def extract_product_from_image_yolo(image_path: str) -> str | None:
73
  result = results[0]
74
  masks = result.masks
75
 
76
- if masks is None:
77
  print("No segmentation masks found by YOLO.")
78
  return None
79
-
80
  # Select the largest mask
81
- largest_mask_index = np.argmax([mask.area for mask in masks])
82
- largest_mask_tensor = masks[largest_mask_index].data.cpu()
 
83
  largest_mask = largest_mask_tensor.numpy().astype(np.uint8)
84
 
85
  # Resize the mask to the original image size
86
- largest_mask = cv2.resize(largest_mask, (image.shape[1], image.shape[0]))
87
-
88
  # Postprocessing: Basic mask cleanup (dilation/erosion)
89
- kernel = np.ones((5, 5), np.uint8)
90
  mask_cleaned = cv2.dilate(largest_mask, kernel, iterations=1)
91
  mask_cleaned = cv2.erode(mask_cleaned, kernel, iterations=1)
92
-
93
  # Create a masked image
94
  masked_image = np.zeros_like(image)
95
  masked_image[mask_cleaned.astype(bool)] = image[mask_cleaned.astype(bool)]
@@ -98,32 +103,27 @@ def extract_product_from_image_yolo(image_path: str) -> str | None:
98
  y_coords, x_coords = np.where(mask_cleaned)
99
  x_min, x_max = np.min(x_coords), np.max(x_coords)
100
  y_min, y_max = np.min(y_coords), np.max(y_coords)
101
- cropped_image = masked_image[y_min:y_max, x_min:x_max]
 
 
 
 
102
 
103
  # Save the cropped image
104
- cropped_image_path = os.path.join(
105
- UPLOADED_IMAGES_DIR, f"{uuid.uuid4()}.jpg"
106
- )
107
- cropped_image_bgr = cv2.cvtColor(cropped_image, cv2.COLOR_RGB2BGR)
108
  cv2.imwrite(cropped_image_path, cropped_image_bgr)
109
-
110
  return cropped_image_path
 
111
  except Exception as e:
112
- print(f"Error during image processing: {e}")
113
  return None
114
 
115
 
116
  @router.post("/process_image")
117
  async def process_image(image: UploadFile = File(...)):
118
- """
119
- Endpoint to process an image and extract the product using SAM.
120
-
121
- Args:
122
- image: The uploaded image file.
123
-
124
- Returns:
125
- JSON response with the path to the processed image or an error message.
126
- """
127
  try:
128
  # Save the uploaded image temporarily
129
  temp_image_filename = f"{uuid.uuid4()}.jpg"
@@ -134,7 +134,7 @@ async def process_image(image: UploadFile = File(...)):
134
 
135
  print("Image saved temporarily to:", temp_image_path)
136
 
137
- # Extract the product
138
  extracted_product_path = extract_product_from_image_yolo(temp_image_path)
139
 
140
  # Remove the temporary file
@@ -147,7 +147,6 @@ async def process_image(image: UploadFile = File(...)):
147
  {
148
  "message": "Product extracted successfully",
149
  "product_image_path": extracted_product_path,
150
- "image": FileResponse(extracted_product_path, media_type="image/jpeg")
151
  }
152
  )
153
  else:
@@ -160,7 +159,15 @@ async def process_image(image: UploadFile = File(...)):
160
  print("Error:", e)
161
  return JSONResponse({"error": str(e)}, status_code=500)
162
 
163
-
 
 
 
 
 
 
 
 
164
  # process single ingredient
165
  @router.post("/process_ingredient", response_model=IngredientAnalysisResult)
166
  @traceable
 
1
  import asyncio
2
  import os
3
  from datetime import datetime
4
+ import uuid
5
  from fastapi import APIRouter, Depends, HTTPException, UploadFile, File
6
  from fastapi.responses import JSONResponse, FileResponse
7
+ import numpy as np
8
  import pytz
9
  from sqlalchemy.orm import Session
10
  from typing import List, Dict, Any
11
  from db.models import User, Ingredient
12
  from interfaces.ingredientModels import IngredientAnalysisResult, IngredientRequest
13
+ from interfaces.productModels import ProductIngredientsRequest
14
  from services.auth_service import get_current_user
15
+ from PIL import Image
16
+ import cv2
17
  from logger_manager import log_info, log_error, logger
18
  from db.database import get_db,SessionLocal
19
+ from db.repositories import IngredientRepository
20
  from dotenv import load_dotenv
21
  from langsmith import traceable
22
  import io
 
55
  details_with_source=[source.data for source in db_ingredient.sources]
56
  )
57
 
 
58
  def extract_product_from_image_yolo(image_path: str) -> str | None:
59
  """Extracts the product image using YOLOv8 with preprocessing and postprocessing."""
60
  try:
61
  # Load image
62
  image = cv2.imread(image_path)
63
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
64
 
65
  # Preprocessing: Resize image
66
  target_size = (640, 640)
67
+ image_resized = cv2.resize(image, target_size, interpolation=cv2.INTER_CUBIC)
68
+ original_height, original_width = image.shape[:2]
69
  # Run inference with YOLO
70
+ results = yolo_model(image_resized,conf=0.2,show=True)
71
 
72
  if not results:
73
  print("No objects detected by YOLO.")
 
77
  result = results[0]
78
  masks = result.masks
79
 
80
+ if masks is None or len(masks.data) == 0:
81
  print("No segmentation masks found by YOLO.")
82
  return None
83
+
84
  # Select the largest mask
85
+ mask_areas = [cv2.contourArea(masks.xy[i]) for i in range(len(masks))]
86
+ largest_mask_index = np.argmax(mask_areas)
87
+ largest_mask_tensor = masks.data[largest_mask_index].cpu()
88
  largest_mask = largest_mask_tensor.numpy().astype(np.uint8)
89
 
90
  # Resize the mask to the original image size
91
+ largest_mask = cv2.resize(largest_mask, (original_width, original_height))
92
+
93
  # Postprocessing: Basic mask cleanup (dilation/erosion)
94
+ kernel = np.ones((3, 3), np.uint8)
95
  mask_cleaned = cv2.dilate(largest_mask, kernel, iterations=1)
96
  mask_cleaned = cv2.erode(mask_cleaned, kernel, iterations=1)
97
+
98
  # Create a masked image
99
  masked_image = np.zeros_like(image)
100
  masked_image[mask_cleaned.astype(bool)] = image[mask_cleaned.astype(bool)]
 
103
  y_coords, x_coords = np.where(mask_cleaned)
104
  x_min, x_max = np.min(x_coords), np.max(x_coords)
105
  y_min, y_max = np.min(y_coords), np.max(y_coords)
106
+ cropped_image = masked_image[y_min:y_max, x_min:x_max]
107
+
108
+ # sharpen the image
109
+ sharpen_kernel = np.array([[-1, -1, -1], [-1, 9, -1], [-1, -1, -1]])
110
+ cropped_image_sharpened = cv2.filter2D(cropped_image, -1, sharpen_kernel)
111
 
112
  # Save the cropped image
113
+ cropped_image_path = os.path.join(UPLOADED_IMAGES_DIR, f"{uuid.uuid4()}.jpg")
114
+ cropped_image_bgr = cv2.cvtColor(cropped_image_sharpened, cv2.COLOR_RGB2BGR)
 
 
115
  cv2.imwrite(cropped_image_path, cropped_image_bgr)
116
+
117
  return cropped_image_path
118
+
119
  except Exception as e:
120
+ print(f"Error during YOLO image processing: {e}")
121
  return None
122
 
123
 
124
  @router.post("/process_image")
125
  async def process_image(image: UploadFile = File(...)):
126
+ """Process image endpoint using YOLO."""
 
 
 
 
 
 
 
 
127
  try:
128
  # Save the uploaded image temporarily
129
  temp_image_filename = f"{uuid.uuid4()}.jpg"
 
134
 
135
  print("Image saved temporarily to:", temp_image_path)
136
 
137
+ # Extract the product using YOLO
138
  extracted_product_path = extract_product_from_image_yolo(temp_image_path)
139
 
140
  # Remove the temporary file
 
147
  {
148
  "message": "Product extracted successfully",
149
  "product_image_path": extracted_product_path,
 
150
  }
151
  )
152
  else:
 
159
  print("Error:", e)
160
  return JSONResponse({"error": str(e)}, status_code=500)
161
 
162
+ @router.get("/get_image/{image_name}")
163
+ async def get_image(image_name: str):
164
+ """Endpoint to retrieve an image by its name."""
165
+ image_path = os.path.join(UPLOADED_IMAGES_DIR, image_name)
166
+ if os.path.exists(image_path):
167
+ return FileResponse(image_path, media_type="image/jpeg")
168
+ else:
169
+ return JSONResponse({"error": "Image not found"}, status_code=404)
170
+
171
  # process single ingredient
172
  @router.post("/process_ingredient", response_model=IngredientAnalysisResult)
173
  @traceable