Untitled

mail@pastecode.io avatar
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