Spaces:
Configuration error
Configuration error
| import cv2 | |
| import pandas as pd | |
| import numpy as np | |
| import pytesseract | |
| import os | |
| from ultralytics import YOLO | |
| from datetime import datetime | |
| # Configure Tesseract executable path | |
| pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' | |
| # Load YOLO model | |
| model = YOLO('best.pt') | |
| # Define polygon area for detection (adjust as needed) | |
| area = [(27, 250), (16, 310), (1015, 310), (992, 250)] | |
| # Track processed numbers to avoid duplicates | |
| processed_numbers = set() | |
| # Initialize video capture | |
| cap = cv2.VideoCapture('mycarplate.mp4') # Change this to your video file path | |
| # Load class list from file | |
| with open("coco1.txt", "r") as file: | |
| class_list = file.read().splitlines() | |
| # Define CSV file and write headers if not already present | |
| csv_file = "car_plate_data_stored.csv" | |
| # Ensure the file has headers if it doesn't already exist | |
| try: | |
| pd.read_csv(csv_file) | |
| except FileNotFoundError: | |
| with open(csv_file, "w") as file: | |
| file.write("ImageFile,Date,Time,Confidence\n") | |
| frame_count = 0 | |
| # Function to correct commonly misrecognized characters | |
| def correct_characters(text): | |
| replacements = { | |
| '0': 'O', # Replace '0' with 'O' if detected, to avoid confusion with 'D' | |
| 'O': 'D', # Replace 'O' with 'D' in typical license plate context | |
| 'I': '1', # Replace 'I' with '1' if detected | |
| 'Q': '0' # Replace 'Q' with '0' if detected | |
| } | |
| corrected_text = ''.join(replacements.get(c, c) for c in text) | |
| return corrected_text | |
| # Function to format license plate text | |
| def format_plate_text(text): | |
| text = ''.join(filter(str.isalnum, text)) | |
| if len(text) == 10: # Assuming full-length plates are correctly detected | |
| return f"{text[:2]} {text[2:4]} {text[4:6]} {text[6:]}" | |
| return text # If not 10 characters, return as-is | |
| # Deskew function to correct any skewed license plates | |
| def deskew_image(image): | |
| # Check if the image is already grayscale (single channel) | |
| if len(image.shape) == 3: | |
| gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) | |
| else: | |
| gray = image # It's already grayscale, no need to convert | |
| # Apply Canny edge detection | |
| edges = cv2.Canny(gray, 50, 150, apertureSize=3) | |
| # Use Hough Transform to detect lines | |
| lines = cv2.HoughLines(edges, 1, np.pi / 180, 100) | |
| if lines is not None: | |
| for line in lines: | |
| rho, theta = line[0] | |
| a = np.cos(theta) | |
| b = np.sin(theta) | |
| x0 = a * rho | |
| y0 = b * rho | |
| x1 = int(x0 + 1000 * (-b)) | |
| y1 = int(y0 + 1000 * (a)) | |
| x2 = int(x0 - 1000 * (-b)) | |
| y2 = int(y0 - 1000 * (a)) | |
| cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) | |
| return image | |
| # Processing video frames | |
| while True: | |
| ret, frame = cap.read() | |
| frame_count += 1 | |
| # Skip frames to process every third frame for efficiency | |
| if frame_count % 3 != 0: | |
| continue | |
| if not ret: | |
| break | |
| # Resize frame for consistent processing | |
| frame = cv2.resize(frame, (1020, 500)) | |
| # Perform YOLO object detection | |
| results = model.predict(frame) | |
| detected_boxes = results[0].boxes.data | |
| detections = pd.DataFrame(detected_boxes).astype("float") | |
| for _, row in detections.iterrows(): | |
| x1, y1, x2, y2 = int(row[0]), int(row[1]), int(row[2]), int(row[3]) | |
| class_id = int(row[5]) | |
| class_name = class_list[class_id] | |
| # Calculate center point of the detected box | |
| cx, cy = (x1 + x2) // 2, (y1 + y2) // 2 | |
| # Check if center is within the defined polygon area | |
| if cv2.pointPolygonTest(np.array(area, np.int32), (cx, cy), False) >= 0: | |
| # Crop detected area | |
| crop = frame[y1:y2, x1:x2] | |
| gray_crop = cv2.cvtColor(crop, cv2.COLOR_BGR2GRAY) | |
| # Apply bilateral filter for smoothing, and threshold for clarity | |
| gray_crop = cv2.bilateralFilter(gray_crop, 10, 20, 20) | |
| _, threshold_crop = cv2.threshold(gray_crop, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) | |
| # Deskew the image if needed | |
| threshold_crop = deskew_image(threshold_crop) | |
| # Generate unique identifier for the detection | |
| current_date = datetime.now().strftime("%d-%m-%Y") | |
| current_time = datetime.now().strftime("%H:%M:%S") | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f") | |
| # Save the cropped license plate image | |
| detection_folder = "detected_plates" | |
| if not os.path.exists(detection_folder): | |
| os.makedirs(detection_folder) | |
| image_filename = f"plate_{timestamp}.jpg" | |
| image_path = os.path.join(detection_folder, image_filename) | |
| cv2.imwrite(image_path, crop) # Save original crop | |
| # Save detection information to CSV | |
| if image_filename not in processed_numbers: # Use filename as unique identifier | |
| processed_numbers.add(image_filename) | |
| with open(csv_file, "a") as file: | |
| confidence = float(row[4]) # Get detection confidence | |
| file.write(f"{image_filename},{current_date},{current_time},{confidence:.2f}\n") | |
| # Draw bounding box and display cropped image | |
| cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 1) | |
| cv2.imshow('Detected Plate', threshold_crop) | |
| # Draw the detection area on the main frame | |
| cv2.polylines(frame, [np.array(area, np.int32)], True, (255, 0, 0), 2) | |
| cv2.imshow("RGB", frame) | |
| # Break loop on 'ESC' key press | |
| if cv2.waitKey(1) & 0xFF == 27: | |
| break | |
| # Release resources | |
| cap.release() | |
| cv2.destroyAllWindows() | |