lokesh341 commited on
Commit
4bf06b6
·
verified ·
1 Parent(s): 0e0c258

Update services/plantation/missing_patch_check.py

Browse files
services/plantation/missing_patch_check.py CHANGED
@@ -1,85 +1,81 @@
1
  import cv2
2
  import numpy as np
3
- from ultralytics import YOLO
4
- import os
5
  import logging
6
- from typing import Tuple, List, Dict, Any
7
 
8
- # Configure logging
9
  logging.basicConfig(
10
  filename="app.log",
11
  level=logging.INFO,
12
  format="%(asctime)s - %(levelname)s - %(message)s"
13
  )
14
 
15
- # Define base directory and model path
16
- BASE_DIR = os.path.dirname(os.path.abspath(__file__))
17
- MODEL_PATH = os.path.abspath(os.path.join(BASE_DIR, "../../models/yolov8n.pt"))
18
-
19
- # Initialize YOLO model
20
- try:
21
- model = YOLO(MODEL_PATH)
22
- logging.info("Loaded YOLOv8n model for missing patch detection.")
23
- logging.info(f"Model class names: {model.names}")
24
- except Exception as e:
25
- logging.error(f"Failed to load YOLOv8n model: {str(e)}")
26
- model = None
27
-
28
- def process_missing_patches(frame: np.ndarray) -> Tuple[List[Dict[str, Any]], np.ndarray]:
29
- # Validate input frame
30
- if not isinstance(frame, np.ndarray) or frame.size == 0:
31
- logging.error("Invalid input frame provided to missing_patch_check.")
32
- return [], frame
33
-
34
- # Check if model is loaded
35
- if model is None:
36
- logging.error("YOLO model not loaded. Skipping missing patch detection.")
37
- return [], frame
38
-
39
  try:
40
- # Perform YOLO inference
41
- results = model(frame, verbose=False)
42
- logging.debug("Completed YOLO inference for missing patch detection.")
43
- except Exception as e:
44
- logging.error(f"Error during YOLO inference: {str(e)}")
45
- return [], frame
46
 
47
- detections: List[Dict[str, Any]] = []
48
- line_counter = 1
49
-
50
- for r in results:
51
- for box in r.boxes:
52
- conf = float(box.conf[0])
53
- if conf < 0.3:
54
- continue
55
- cls = int(box.cls[0])
56
- label = model.names[cls]
57
- if label != "missing_patch":
58
  continue
59
- xyxy = box.xyxy[0].cpu().numpy().astype(int)
60
- x_min, y_min, x_max, y_max = xyxy
61
 
62
- detection_label = f"Line {line_counter} - Missing Patch (Conf: {conf:.2f})"
63
- detections.append({
64
- "type": "missing_patch",
65
- "label": detection_label,
66
- "confidence": conf,
67
- "coordinates": [x_min, y_min, x_max, y_max]
68
- })
 
 
 
 
 
69
 
70
- color = (255, 165, 0) # Orange for missing patches
71
- cv2.rectangle(frame, (x_min, y_min), (x_max, y_max), color, 2)
72
- cv2.putText(
73
- frame,
74
- detection_label,
75
- (x_min, y_min - 10),
76
- cv2.FONT_HERSHEY_SIMPLEX,
77
- 0.6,
78
- color,
79
- 2
80
- )
81
-
82
- line_counter += 1
 
 
 
 
 
 
 
 
 
 
 
83
 
84
- logging.info(f"Detected {len(detections)} missing patches in plantation.")
85
- return detections, frame
 
 
 
 
 
1
  import cv2
2
  import numpy as np
 
 
3
  import logging
4
+ from typing import List, Dict, Tuple
5
 
6
+ # Setup logging
7
  logging.basicConfig(
8
  filename="app.log",
9
  level=logging.INFO,
10
  format="%(asctime)s - %(levelname)s - %(message)s"
11
  )
12
 
13
+ def process_missing_patches(frame: np.ndarray) -> Tuple[List[Dict], np.ndarray]:
14
+ """
15
+ Process a frame to identify missing patches in a plantation.
16
+ Args:
17
+ frame: Input frame (BGR numpy array)
18
+ Returns:
19
+ Tuple: (List of missing patch detections, annotated frame)
20
+ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  try:
22
+ # Convert frame to HSV and detect green regions (trees)
23
+ hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
24
+ lower_green = np.array([35, 40, 40])
25
+ upper_green = np.array([85, 255, 255])
26
+ mask = cv2.inRange(hsv, lower_green, upper_green)
 
27
 
28
+ # Find contours of trees
29
+ contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
30
+ tree_positions = []
31
+ for contour in contours:
32
+ area = cv2.contourArea(contour)
33
+ if area < 300:
 
 
 
 
 
34
  continue
35
+ x, y, w, h = cv2.boundingRect(contour)
36
+ tree_positions.append((x + w // 2, y + h // 2))
37
 
38
+ # Assume a grid-like plantation pattern and detect gaps
39
+ detections = []
40
+ if tree_positions:
41
+ # Estimate grid spacing by calculating average distance between trees
42
+ if len(tree_positions) > 1:
43
+ distances = []
44
+ for i in range(len(tree_positions)):
45
+ for j in range(i + 1, len(tree_positions)):
46
+ p1, p2 = tree_positions[i], tree_positions[j]
47
+ dist = np.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
48
+ distances.append(dist)
49
+ avg_spacing = np.mean(distances) if distances else 100
50
 
51
+ # Create a grid based on frame dimensions and avg_spacing
52
+ height, width = frame.shape[:2]
53
+ grid_step = int(avg_spacing)
54
+ for y in range(0, height, grid_step):
55
+ for x in range(0, width, grid_step):
56
+ # Check if there's a tree within this grid cell
57
+ has_tree = False
58
+ for tx, ty in tree_positions:
59
+ if (x - grid_step // 2 <= tx <= x + grid_step // 2 and
60
+ y - grid_step // 2 <= ty <= y + grid_step // 2):
61
+ has_tree = True
62
+ break
63
+ if not has_tree:
64
+ # Mark as missing patch
65
+ x_min, y_min = x - grid_step // 2, y - grid_step // 2
66
+ x_max, y_max = x + grid_step // 2, y + grid_step // 2
67
+ detections.append({
68
+ "type": "missing_patch",
69
+ "label": "Missing Patch",
70
+ "box": [x_min, y_min, x_max, y_max]
71
+ })
72
+ cv2.rectangle(frame, (x_min, y_min), (x_max, y_max), (0, 0, 255), 2)
73
+ cv2.putText(frame, "Missing", (x_min, y_min - 10),
74
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
75
 
76
+ logging.info(f"Detected {len(detections)} missing patches in frame.")
77
+ return detections, frame
78
+
79
+ except Exception as e:
80
+ logging.error(f"Error in missing patch check: {str(e)}")
81
+ return [], frame