import numpy as np
import cv2
from tensorflow.keras.models import load_model

# Assuming the detection and recognition models are already loaded
# detection_model = load_model(‘path_to_detection_model.h5’)
# recognition_model = load_model(‘path_to_recognition_model.h5’)

# Define vocabulary
vocab = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ "  # Adjust based on actual vocabulary in training

# Function to preprocess images for detection model
def preprocess_detection_image(image, target_size=(224, 224)):
    preprocessed_image = cv2.resize(image, target_size) / 255.0
    preprocessed_image = np.expand_dims(preprocessed_image, axis=0)  # Add batch dimension
    return preprocessed_image

# Function to detect license plates in an image
def detect_license_plates(image, detection_model):
    preprocessed_image = preprocess_detection_image(image)
    if preprocessed_image.size == 0:
        raise ValueError("Preprocessed image is empty.")
    
    bbox = detection_model.predict(preprocessed_image)[0]
    print(f"Bounding Box Prediction Output: {bbox}")  # Debug print for inspection
    
    if len(bbox) != 4:
        raise ValueError(f"Unexpected bounding box format detected: Size of bbox prediction is {len(bbox)}, expected 4.")
    
    ymin, xmin, ymax, xmax = bbox
    return int(ymin), int(xmin), int(ymax), int(xmax)

# Simplifying Preprocess ensuring Exact Dimensional consistency 
def preprocess_recognition_image(image, target_size=(100, 32)):
    preprocessed_plate = cv2.resize(image, target_size) / 255.0
    preprocessed_plate = np.expand_dims(preprocessed_plate, axis=-1)  # Add channel dimension
    preprocessed_plate = np.expand_dims(preprocessed_plate, axis=0)   # Add batch dimension
    
    # Flatten the image while ensuring proper total confirming feature split sequence
    _, height, width, _ = preprocessed_plate.shape
    if height * width != 3200:
        raise ValueError(f"Error in reshaping: expected elements misalignment, got total {height * width}")
    
    reshaped_plate = preprocessed_plate.reshape((1, 10, 320))  # Ensure reshaping correct exact
    return reshaped_plate

# Function to recognize characters in a license plate image
def recognize_characters(plate_image, recognition_model):
    preprocessed_plate = preprocess_recognition_image(plate_image)
    if preprocessed_plate.size == 0:
        raise ValueError("Preprocessed plate image is empty.")
    
    prediction = recognition_model.predict(preprocessed_plate)
    predicted_text = ''.join([vocab[np.argmax(char)] for char in prediction[0]])
    return predicted_text

# Test the models on a new image
test_image_path = "/content/dataset/test/test/test/933.jpg"  # Specific valid Path
test_image = cv2.imread(test_image_path)

if test_image is None:
    raise ValueError(f"Failed to load image from {test_image_path}")

try:
    ymin, xmin, ymax, xmax = detect_license_plates(test_image, detection_model)  # Ensure bbox returns exactly four values
    plate_image = test_image[ymin:ymax, xmin:xmax]

    print(f"Detected Bounding Box: ymin={ymin}, xmin={xmin}, ymax={ymax}, xmax={xmax}")
    print(f"Plate Image Shape: {plate_image.shape}")

    assert plate_image.size != 0, "Empty Plate Image Detected."
    preprocessed_plate_shape = preprocess_recognition_image(plate_image).shape
    print(f'Preprocessed Plate Shape: {preprocessed_plate_shape}')  # Validate shape after preprocess 
    
    predicted_text = recognize_characters(plate_image, recognition_model)
    print("Predicted License Plate Text:", predicted_text)
except Exception as e:
    print(f"Error during license plate detection or recognition: {e}")

1/1 [==============================] - 0s 72ms/step
Bounding Box Prediction Output: [287.9597  308.5445  371.42105 430.51584]
Detected Bounding Box: ymin=287, xmin=308, ymax=371, xmax=430
Plate Image Shape: (84, 102, 3)
Error during license plate detection or recognition: too many values to unpack (expected 4)