Untitled
unknown
plain_text
3 days ago
5.0 kB
2
Indexable
Never
import cv2 import numpy as np import pytesseract from picamera2 import Picamera2 import time import os # Define office worker plate numbers office_worker_plates = ['PJH1123', 'PPT1109'] # Add more if needed # Folder to save cropped plates output_directory = "cropped_plates" os.makedirs(output_directory, exist_ok=True) # Initialize camera picam2 = Picamera2() picam2.configure(picam2.create_preview_configuration(main={"format": 'XRGB8888', "size": (320, 240)})) # Lower resolution picam2.start() # Function to add status text to the cropped image def add_status_text(cropped_img, text): # Add a black rectangle at the bottom of the image h, w = cropped_img.shape[:2] result_img = cv2.copyMakeBorder(cropped_img, 0, 50, 0, 0, cv2.BORDER_CONSTANT, value=[0, 0, 0]) # Choose font and position for the status text font = cv2.FONT_HERSHEY_SIMPLEX position = (10, h + 30) font_scale = 1 font_color = (255, 255, 255) thickness = 2 # Add the text at the bottom of the image cv2.putText(result_img, text, position, font, font_scale, font_color, thickness, lineType=cv2.LINE_AA) return result_img # Function to process and detect plate number def recognize_license_plate(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Convert to grayscale # Apply bilateral filter instead of Gaussian blur to reduce noise and maintain edges (more efficient) gray = cv2.bilateralFilter(gray, 11, 17, 17) # Edge detection using Canny (optimized) edged = cv2.Canny(gray, 30, 150) # Find contours in the edged image cnts, _ = cv2.findContours(edged.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:10] screenCnt = None # Loop over contours to find the plate for c in cnts: peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.02 * peri, True) # Adjust for more accuracy # Assume a contour with four points is the license plate if len(approx) == 4: screenCnt = approx break if screenCnt is None: return None, None # Draw a green box around the detected plate cv2.drawContours(img, [screenCnt], -1, (0, 255, 0), 3) # Create a mask and crop the license plate area mask = np.zeros(gray.shape, np.uint8) new_image = cv2.drawContours(mask, [screenCnt], 0, 255, -1) new_image = cv2.bitwise_and(img, img, mask=mask) # Now crop the image to the detected plate region (x, y) = np.where(mask == 255) (topx, topy) = (np.min(x), np.min(y)) (bottomx, bottomy) = (np.max(x), np.max(y)) if topx >= 0 and topy >= 0 and bottomx > topx and bottomy > topy: Cropped = gray[topx:bottomx + 1, topy:bottomy + 1] else: Cropped = None if Cropped is not None: # Use Tesseract to extract text from the cropped license plate area config = '--psm 8' # Single-line mode text = pytesseract.image_to_string(Cropped, config=config) # Filter out non-alphanumeric characters and restrict length text = ''.join(filter(str.isalnum, text)).upper() # Check if the text length is valid (6-7 characters) if 6 <= len(text) <= 7: return text, Cropped return None, None # Main loop to capture and process images from the camera while True: start_time = time.time() # Record the start time frame = picam2.capture_array() # Perform license plate recognition plate_number, cropped_plate = recognize_license_plate(frame) if plate_number: if plate_number in office_worker_plates: status = "Officer" else: status = "Outsider" # Add the status text to the cropped plate image if cropped_plate is not None: cropped_with_status = add_status_text(cropped_plate, status) # Generate a unique filename using timestamp for every saved image timestamp = int(time.time()) filename = os.path.join(output_directory, f"{plate_number}_{status}_{timestamp}.jpg") # Save the cropped image with the status text cv2.imwrite(filename, cropped_with_status) # Display the cropped plate with the status in a separate window cv2.imshow("Cropped Plate", cropped_with_status) print(f"Saved: {filename}") # Display the camera feed with the green bounding box cv2.imshow("Camera Preview", frame) # Ensure it processes frames close to 1 second intervals elapsed_time = time.time() - start_time sleep_time = max(1.0 - elapsed_time, 0) # Adjust to maintain ~1 second between captures time.sleep(sleep_time) # Quit if 'q' is pressed if cv2.waitKey(1) & 0xFF == ord('q'): break cv2.destroyAllWindows()
Leave a Comment