<gh_stars>0
from keras import backend as K
from keras.models import load_model
from keras.preprocessing import image
from keras.optimizers import Adam
#from imageio import imread
import numpy as np
import random
import cv2
#from matplotlib import pyplot as plt

from models.keras_ssd300 import ssd_300
from keras_loss_function.keras_ssd_loss import SSDLoss
from keras_layers.keras_layer_AnchorBoxes import AnchorBoxes
from keras_layers.keras_layer_DecodeDetections import DecodeDetections
from keras_layers.keras_layer_DecodeDetectionsFast import DecodeDetectionsFast
from keras_layers.keras_layer_L2Normalization import L2Normalization

from ssd_encoder_decoder.ssd_output_decoder import decode_detections, decode_detections_fast

from data_generator.object_detection_2d_data_generator import DataGenerator
from data_generator.object_detection_2d_photometric_ops import ConvertTo3Channels
from data_generator.object_detection_2d_geometric_ops import Resize
from data_generator.object_detection_2d_misc_utils import apply_inverse_transforms

from threading import Thread
from datetime import datetime
import time

# Set the image size.
img_height = 300
img_width = 300

classes = ['background',
            'Vehicle plate registration']
colors = ( (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) for i in range(len(classes)) )

orig_images = [] # Store the images here.
input_images = [] # Store resized versions of the images here.

# We'll only load one image in this example.
#img_path = '/home/bende/Datasets/OpenImages_face_plate/validation/Vehicle registration plate/0c756c9366a8cb10.jpg'
#img_path = '../ssd_keras_files/voiturefeu.jpg'
video_path = '../ssd_keras_files/UK_Dash_Cam_IDIOT_DRIVERS.mp4'
confidence_threshold = 0.5

# TODO: Set the path to the `.h5` file of the model to be loaded.
#model_path = '../ssd_keras_files/ssd300_OID_plates_epoch-97_loss-2.9400_val_loss-2.4888.h5'
model_path = '../ssd_keras_files/ssd300_OID_plates_MODEL.h5'


class CountsPerSec:
    """
    Class that tracks the number of occurrences ("counts") of an
    arbitrary event and returns the frequency in occurrences
    (counts) per second. The caller must increment the count.
    """

    def __init__(self):
        self._start_time = None
        self._num_occurrences = 0

    def start(self):
        self._start_time = datetime.now()
        return self

    def increment(self):
        self._num_occurrences += 1

    def countsPerSec(self):
        elapsed_time = (datetime.now() - self._start_time).total_seconds()
        return self._num_occurrences / elapsed_time

class VideoGet:
    """
    Class that continuously gets frames from a VideoCapture object
    with a dedicated thread.
    """

    def __init__(self, src=0):
        self.stream = cv2.VideoCapture(src)
        (self.grabbed, self.frame) = self.stream.read()
        self.stopped = False
    
    def start(self):
        Thread(target=self.update, args=()).start()
        return self
    
    def update(self):
        # keep looping infinitely until the thread is stopped
        while True:
          # if the thread indicator variable is set, stop the thread
          if self.stopped:
            return
    
          # otherwise, read the next frame from the stream
          (self.grabbed, self.frame) = self.stream.read()
    
    def read(self):
        # return the frame most recently read
        return self.frame

    def stop(self):
        self.stopped = True

class VideoShow:
    """
    Class that continuously shows a frame using a dedicated thread.
    """

    def __init__(self, frame=None):
        self.frame = frame
        self.stopped = False

    def start(self):
        Thread(target=self.show, args=()).start()
        return self

    def show(self):
        while not self.stopped:
            cv2.imshow("Video", self.frame)
            if cv2.waitKey(1) == ord("q"):
                self.stopped = True

    def stop(self):
        self.stopped = True

def putIterationsPerSec(frame, iterations_per_sec):
    """
    Add iterations per second text to lower-left corner of a frame.
    """

    cv2.putText(frame, "{:.0f} iterations/sec".format(iterations_per_sec),
        (10, 450), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 255))
    return frame

def predict_on_image(read_image, model):
    start = time.time()

    img = image.img_to_array(cv2.resize(read_image, (img_height, img_width))) 

    y_pred = model.predict(np.array([img]))
    ####TIME####
    timebreak = time.time()
    seconds = timebreak - start
    print("Time taken to make predictions: {0} seconds".format(seconds))
    ############

    y_pred_thresh = [y_pred[k][y_pred[k,:,1] > confidence_threshold] for k in range(y_pred.shape[0])]

    if y_pred_thresh[0]:
        np.set_printoptions(precision=2, suppress=True, linewidth=90)
        print("Predicted boxes:\n")
        print('   class   conf xmin   ymin   xmax   ymax')
        print(y_pred_thresh[0])

    return y_pred_thresh

# Display the image and draw the predicted boxes onto it.
def display_pediction_image(read_image, y_pred_thresh):
    # Set the colors for the bounding boxes
    #colors = plt.cm.hsv(np.linspace(0, 1, 21)).tolist()

    """
    plt.figure(figsize=(20,12))
    plt.imshow(orig_images[0])

    current_axis = plt.gca()

    for box in y_pred_thresh[0]:
        # Transform the predicted bounding boxes for the 300x300 image to the original image dimensions.
        xmin = box[2] * orig_images[0].shape[1] / img_width
        ymin = box[3] * orig_images[0].shape[0] / img_height
        xmax = box[4] * orig_images[0].shape[1] / img_width
        ymax = box[5] * orig_images[0].shape[0] / img_height
        color = colors[int(box[0])]
        label = '{}: {:.2f}'.format(classes[int(box[0])], box[1])
        current_axis.add_patch(plt.Rectangle((xmin, ymin), xmax-xmin, ymax-ymin, color=color, fill=False, linewidth=2))  
        current_axis.text(xmin, ymin, label, size='x-large', color='white', bbox={'facecolor':color, 'alpha':1.0})

    plt.show()
    """
    # Visualize detected bounding boxes.
    for box in y_pred_thresh[0]:
        classId = int(box[0])
        score = box[1]
        color = colors[int(box[0])]
        xmin = int(box[2] * read_image.shape[1] / img_width)
        ymin = int(box[3] * read_image.shape[0] / img_height)
        xmax = int(box[4] * read_image.shape[1] / img_width)
        ymax = int(box[5] * read_image.shape[0] / img_height)
        cv2.blur(src=read_image[ymin:ymax, xmin:xmax],dst=read_image[ymin:ymax, xmin:xmax], ksize=(20,10))
        cv2.rectangle(read_image, (xmin, ymin), (xmax, ymax), color, thickness=2)
        label = '{}: {:.2f}'.format(classes[int(box[0])], box[1])
        cv2.putText(read_image, label, (xmin, ymin), cv2.FONT_HERSHEY_PLAIN, 1.0, (255,255,255), 1)



# 1: Build the Keras model
K.clear_session() # Clear previous models from memory.
"""
model = ssd_300(image_size=(img_height, img_width, 3),
                n_classes=1,
                mode='inference',
                l2_regularization=0.005,
                scales=[0.1, 0.2, 0.37, 0.54, 0.71, 0.88, 1.05], # The scales for MS COCO are [0.07, 0.15, 0.33, 0.51, 0.69, 0.87, 1.05]
                aspect_ratios_per_layer=[[1.0, 2.0, 0.5],
                                        [1.0, 2.0, 0.5, 3.0, 1.0/3.0],
                                        [1.0, 2.0, 0.5, 3.0, 1.0/3.0],
                                        [1.0, 2.0, 0.5, 3.0, 1.0/3.0],
                                        [1.0, 2.0, 0.5],
                                        [1.0, 2.0, 0.5]],
                two_boxes_for_ar1=True,
                steps=[8, 16, 32, 64, 100, 300],
                offsets=[0.5, 0.5, 0.5, 0.5, 0.5, 0.5],
                clip_boxes=False,
                variances=[0.1, 0.1, 0.2, 0.2],
                normalize_coords=True,
                subtract_mean=[123, 117, 104],
                swap_channels=[2, 1, 0],
                confidence_thresh=confidence_threshold,
                iou_threshold=0.45,
                top_k=200,
                nms_max_output_size=400)

# 2: Load the trained weights into the model.

model.load_weights(model_path, by_name=True)

# 3: Compile the model so that Keras won't complain the next time you load it.

adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)

ssd_loss = SSDLoss(neg_pos_ratio=3, alpha=1.0)

model.compile(optimizer=adam, loss=ssd_loss.compute_loss)
"""

# We need to create an SSDLoss object in order to pass that to the model loader.
ssd_loss = SSDLoss(neg_pos_ratio=3, n_neg_min=0, alpha=1.0)

model = load_model(model_path, custom_objects={'AnchorBoxes': AnchorBoxes,
                                               'L2Normalization': L2Normalization,
                                               'DecodeDetections': DecodeDetections,
                                               'compute_loss': ssd_loss.compute_loss})



"""
read_image = cv2.imread(img_path)
y_pred_thresh = predict_on_image(read_image, model)
display_pedicted_image(read_image, y_pred_thresh)
cv2.waitKey()
"""
"""
# Create a VideoCapture object and read from input file
# If the input is the camera, pass 0 instead of the video file name
cap = cv2.VideoCapture(video_path)
 
# Check if camera opened successfully
if (cap.isOpened()== False): 
  print("Error opening video stream or file")

fps = cap.get(cv2.CAP_PROP_FPS)
print("Frames per second using video.get(cv2.CAP_PROP_FPS) : {0}".format(fps))
#frames_to_skip = fps/5
frames_to_skip = 1
i=1
# Read until video is completed
while(cap.isOpened()):
  # Capture frame-by-frame
  ret, frame = cap.read()
  if ret == True:
    
    if i == frames_to_skip:
        y_pred_thresh = predict_on_image(frame, model)
        display_pediction_image(frame, y_pred_thresh)
        cv2.imshow('SSD Keras Plates recognition', frame)

        # Press Q on keyboard to  exit
        if cv2.waitKey(25) & 0xFF == ord('q'):
            break
        i=0
    i+=1
     
  # Break the loop
  else: 
    break

 
# When everything done, release the video capture object
cap.release()
 
# Closes all the frames
cv2.destroyAllWindows()

"""


cap = cv2.VideoCapture(video_path)
cps = CountsPerSec().start()

while True:
    (grabbed, frame) = cap.read()
    if not grabbed or cv2.waitKey(1) == ord("q"):
        break

    frame = putIterationsPerSec(frame, cps.countsPerSec())
    y_pred_thresh = predict_on_image(frame, model)  
    display_pediction_image(frame, y_pred_thresh)
    cv2.imshow("Video", frame)
    cps.increment()


"""

video_getter = VideoGet(video_path).start()
cps = CountsPerSec().start()
while True:
        if (cv2.waitKey(1) == ord("q")) or video_getter.stopped:
            video_getter.stop()
            break

        frame = video_getter.read()
        frame = putIterationsPerSec(frame, cps.countsPerSec())
        y_pred_thresh = predict_on_image(frame, model)
        display_pediction_image(frame, y_pred_thresh)
        cv2.imshow('SSD Keras Plates recognition', frame)
        cps.increment()
"""

"""
video_getter = VideoGet(video_path).start()
video_shower = VideoShow(video_getter.frame).start()
cps = CountsPerSec().start()

while True:
    if video_getter.stopped or video_shower.stopped:
        video_shower.stop()
        video_getter.stop()
        break

    frame = video_getter.frame
    frame = putIterationsPerSec(frame, cps.countsPerSec())
    y_pred_thresh = predict_on_image(frame, model)
    display_pediction_image(frame, y_pred_thresh)
    video_shower.frame = frame
    cps.increment()
"""
from keras import backend as K
from keras.models import load_model
from keras.preprocessing import image
from keras.optimizers import Adam
#from imageio import imread
import numpy as np
import random
import cv2
#from matplotlib import pyplot as plt

from models.keras_ssd300 import ssd_300
from keras_loss_function.keras_ssd_loss import SSDLoss
from keras_layers.keras_layer_AnchorBoxes import AnchorBoxes
from keras_layers.keras_layer_DecodeDetections import DecodeDetections
from keras_layers.keras_layer_DecodeDetectionsFast import DecodeDetectionsFast
from keras_layers.keras_layer_L2Normalization import L2Normalization

from ssd_encoder_decoder.ssd_output_decoder import decode_detections, decode_detections_fast

from data_generator.object_detection_2d_data_generator import DataGenerator
from data_generator.object_detection_2d_photometric_ops import ConvertTo3Channels
from data_generator.object_detection_2d_geometric_ops import Resize
from data_generator.object_detection_2d_misc_utils import apply_inverse_transforms

from threading import Thread
from datetime import datetime
import time

# Set the image size.
img_height = 300
img_width = 300

classes = ['background',
            'Vehicle plate registration']
colors = ( (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) for i in range(len(classes)) )

orig_images = [] # Store the images here.
input_images = [] # Store resized versions of the images here.

# We'll only load one image in this example.
#img_path = '/home/bende/Datasets/OpenImages_face_plate/validation/Vehicle registration plate/0c756c9366a8cb10.jpg'
#img_path = '../ssd_keras_files/voiturefeu.jpg'
video_path = '../ssd_keras_files/UK_Dash_Cam_IDIOT_DRIVERS.mp4'
confidence_threshold = 0.5

# TODO: Set the path to the `.h5` file of the model to be loaded.
#model_path = '../ssd_keras_files/ssd300_OID_plates_epoch-97_loss-2.9400_val_loss-2.4888.h5'
model_path = '../ssd_keras_files/ssd300_OID_plates_MODEL.h5'


class CountsPerSec:
    """
    Class that tracks the number of occurrences ("counts") of an
    arbitrary event and returns the frequency in occurrences
    (counts) per second. The caller must increment the count.
    """

    def __init__(self):
        self._start_time = None
        self._num_occurrences = 0

    def start(self):
        self._start_time = datetime.now()
        return self

    def increment(self):
        self._num_occurrences += 1

    def countsPerSec(self):
        elapsed_time = (datetime.now() - self._start_time).total_seconds()
        return self._num_occurrences / elapsed_time

class VideoGet:
    """
    Class that continuously gets frames from a VideoCapture object
    with a dedicated thread.
    """

    def __init__(self, src=0):
        self.stream = cv2.VideoCapture(src)
        (self.grabbed, self.frame) = self.stream.read()
        self.stopped = False
    
    def start(self):
        Thread(target=self.update, args=()).start()
        return self
    
    def update(self):
        # keep looping infinitely until the thread is stopped
        while True:
          # if the thread indicator variable is set, stop the thread
          if self.stopped:
            return
    
          # otherwise, read the next frame from the stream
          (self.grabbed, self.frame) = self.stream.read()
    
    def read(self):
        # return the frame most recently read
        return self.frame

    def stop(self):
        self.stopped = True

class VideoShow:
    """
    Class that continuously shows a frame using a dedicated thread.
    """

    def __init__(self, frame=None):
        self.frame = frame
        self.stopped = False

    def start(self):
        Thread(target=self.show, args=()).start()
        return self

    def show(self):
        while not self.stopped:
            cv2.imshow("Video", self.frame)
            if cv2.waitKey(1) == ord("q"):
                self.stopped = True

    def stop(self):
        self.stopped = True

def putIterationsPerSec(frame, iterations_per_sec):
    """
    Add iterations per second text to lower-left corner of a frame.
    """

    cv2.putText(frame, "{:.0f} iterations/sec".format(iterations_per_sec),
        (10, 450), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 255))
    return frame

def predict_on_image(read_image, model):
    start = time.time()

    img = image.img_to_array(cv2.resize(read_image, (img_height, img_width))) 

    y_pred = model.predict(np.array([img]))
    ####TIME####
    timebreak = time.time()
    seconds = timebreak - start
    print("Time taken to make predictions: {0} seconds".format(seconds))
    ############

    y_pred_thresh = [y_pred[k][y_pred[k,:,1] > confidence_threshold] for k in range(y_pred.shape[0])]

    if y_pred_thresh[0]:
        np.set_printoptions(precision=2, suppress=True, linewidth=90)
        print("Predicted boxes:\n")
        print('   class   conf xmin   ymin   xmax   ymax')
        print(y_pred_thresh[0])

    return y_pred_thresh

# Display the image and draw the predicted boxes onto it.
def display_pediction_image(read_image, y_pred_thresh):
    # Set the colors for the bounding boxes
    #colors = plt.cm.hsv(np.linspace(0, 1, 21)).tolist()

    """
    plt.figure(figsize=(20,12))
    plt.imshow(orig_images[0])

    current_axis = plt.gca()

    for box in y_pred_thresh[0]:
        # Transform the predicted bounding boxes for the 300x300 image to the original image dimensions.
        xmin = box[2] * orig_images[0].shape[1] / img_width
        ymin = box[3] * orig_images[0].shape[0] / img_height
        xmax = box[4] * orig_images[0].shape[1] / img_width
        ymax = box[5] * orig_images[0].shape[0] / img_height
        color = colors[int(box[0])]
        label = '{}: {:.2f}'.format(classes[int(box[0])], box[1])
        current_axis.add_patch(plt.Rectangle((xmin, ymin), xmax-xmin, ymax-ymin, color=color, fill=False, linewidth=2))  
        current_axis.text(xmin, ymin, label, size='x-large', color='white', bbox={'facecolor':color, 'alpha':1.0})

    plt.show()
    """
    # Visualize detected bounding boxes.
    for box in y_pred_thresh[0]:
        classId = int(box[0])
        score = box[1]
        color = colors[int(box[0])]
        xmin = int(box[2] * read_image.shape[1] / img_width)
        ymin = int(box[3] * read_image.shape[0] / img_height)
        xmax = int(box[4] * read_image.shape[1] / img_width)
        ymax = int(box[5] * read_image.shape[0] / img_height)
        cv2.blur(src=read_image[ymin:ymax, xmin:xmax],dst=read_image[ymin:ymax, xmin:xmax], ksize=(20,10))
        cv2.rectangle(read_image, (xmin, ymin), (xmax, ymax), color, thickness=2)
        label = '{}: {:.2f}'.format(classes[int(box[0])], box[1])
        cv2.putText(read_image, label, (xmin, ymin), cv2.FONT_HERSHEY_PLAIN, 1.0, (255,255,255), 1)



# 1: Build the Keras model
K.clear_session() # Clear previous models from memory.
"""
model = ssd_300(image_size=(img_height, img_width, 3),
                n_classes=1,
                mode='inference',
                l2_regularization=0.005,
                scales=[0.1, 0.2, 0.37, 0.54, 0.71, 0.88, 1.05], # The scales for MS COCO are [0.07, 0.15, 0.33, 0.51, 0.69, 0.87, 1.05]
                aspect_ratios_per_layer=[[1.0, 2.0, 0.5],
                                        [1.0, 2.0, 0.5, 3.0, 1.0/3.0],
                                        [1.0, 2.0, 0.5, 3.0, 1.0/3.0],
                                        [1.0, 2.0, 0.5, 3.0, 1.0/3.0],
                                        [1.0, 2.0, 0.5],
                                        [1.0, 2.0, 0.5]],
                two_boxes_for_ar1=True,
                steps=[8, 16, 32, 64, 100, 300],
                offsets=[0.5, 0.5, 0.5, 0.5, 0.5, 0.5],
                clip_boxes=False,
                variances=[0.1, 0.1, 0.2, 0.2],
                normalize_coords=True,
                subtract_mean=[123, 117, 104],
                swap_channels=[2, 1, 0],
                confidence_thresh=confidence_threshold,
                iou_threshold=0.45,
                top_k=200,
                nms_max_output_size=400)

# 2: Load the trained weights into the model.

model.load_weights(model_path, by_name=True)

# 3: Compile the model so that Keras won't complain the next time you load it.

adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)

ssd_loss = SSDLoss(neg_pos_ratio=3, alpha=1.0)

model.compile(optimizer=adam, loss=ssd_loss.compute_loss)
"""

# We need to create an SSDLoss object in order to pass that to the model loader.
ssd_loss = SSDLoss(neg_pos_ratio=3, n_neg_min=0, alpha=1.0)

model = load_model(model_path, custom_objects={'AnchorBoxes': AnchorBoxes,
                                               'L2Normalization': L2Normalization,
                                               'DecodeDetections': DecodeDetections,
                                               'compute_loss': ssd_loss.compute_loss})



"""
read_image = cv2.imread(img_path)
y_pred_thresh = predict_on_image(read_image, model)
display_pedicted_image(read_image, y_pred_thresh)
cv2.waitKey()
"""
"""
# Create a VideoCapture object and read from input file
# If the input is the camera, pass 0 instead of the video file name
cap = cv2.VideoCapture(video_path)
 
# Check if camera opened successfully
if (cap.isOpened()== False): 
  print("Error opening video stream or file")

fps = cap.get(cv2.CAP_PROP_FPS)
print("Frames per second using video.get(cv2.CAP_PROP_FPS) : {0}".format(fps))
#frames_to_skip = fps/5
frames_to_skip = 1
i=1
# Read until video is completed
while(cap.isOpened()):
  # Capture frame-by-frame
  ret, frame = cap.read()
  if ret == True:
    
    if i == frames_to_skip:
        y_pred_thresh = predict_on_image(frame, model)
        display_pediction_image(frame, y_pred_thresh)
        cv2.imshow('SSD Keras Plates recognition', frame)

        # Press Q on keyboard to  exit
        if cv2.waitKey(25) & 0xFF == ord('q'):
            break
        i=0
    i+=1
     
  # Break the loop
  else: 
    break

 
# When everything done, release the video capture object
cap.release()
 
# Closes all the frames
cv2.destroyAllWindows()

"""


cap = cv2.VideoCapture(video_path)
cps = CountsPerSec().start()

while True:
    (grabbed, frame) = cap.read()
    if not grabbed or cv2.waitKey(1) == ord("q"):
        break

    frame = putIterationsPerSec(frame, cps.countsPerSec())
    y_pred_thresh = predict_on_image(frame, model)  
    display_pediction_image(frame, y_pred_thresh)
    cv2.imshow("Video", frame)
    cps.increment()


"""

video_getter = VideoGet(video_path).start()
cps = CountsPerSec().start()
while True:
        if (cv2.waitKey(1) == ord("q")) or video_getter.stopped:
            video_getter.stop()
            break

        frame = video_getter.read()
        frame = putIterationsPerSec(frame, cps.countsPerSec())
        y_pred_thresh = predict_on_image(frame, model)
        display_pediction_image(frame, y_pred_thresh)
        cv2.imshow('SSD Keras Plates recognition', frame)
        cps.increment()
"""

"""
video_getter = VideoGet(video_path).start()
video_shower = VideoShow(video_getter.frame).start()
cps = CountsPerSec().start()

while True:
    if video_getter.stopped or video_shower.stopped:
        video_shower.stop()
        video_getter.stop()
        break

    frame = video_getter.frame
    frame = putIterationsPerSec(frame, cps.countsPerSec())
    y_pred_thresh = predict_on_image(frame, model)
    display_pediction_image(frame, y_pred_thresh)
    video_shower.frame = frame
    cps.increment()
"""
#from imageio import imread #from matplotlib import pyplot as plt # Set the image size. # Store the images here. # Store resized versions of the images here. # We'll only load one image in this example. #img_path = '/home/bende/Datasets/OpenImages_face_plate/validation/Vehicle registration plate/0c756c9366a8cb10.jpg' #img_path = '../ssd_keras_files/voiturefeu.jpg' # TODO: Set the path to the `.h5` file of the model to be loaded. #model_path = '../ssd_keras_files/ssd300_OID_plates_epoch-97_loss-2.9400_val_loss-2.4888.h5' Class that tracks the number of occurrences ("counts") of an     arbitrary event and returns the frequency in occurrences     (counts) per second. The caller must increment the count. Class that continuously gets frames from a VideoCapture object     with a dedicated thread. # keep looping infinitely until the thread is stopped # if the thread indicator variable is set, stop the thread # otherwise, read the next frame from the stream # return the frame most recently read Class that continuously shows a frame using a dedicated thread. Add iterations per second text to lower-left corner of a frame. ####TIME#### ############ # Display the image and draw the predicted boxes onto it. # Set the colors for the bounding boxes #colors = plt.cm.hsv(np.linspace(0, 1, 21)).tolist() plt.figure(figsize=(20,12))     plt.imshow(orig_images[0])      current_axis = plt.gca()      for box in y_pred_thresh[0]:         # Transform the predicted bounding boxes for the 300x300 image to the original image dimensions.         xmin = box[2] * orig_images[0].shape[1] / img_width         ymin = box[3] * orig_images[0].shape[0] / img_height         xmax = box[4] * orig_images[0].shape[1] / img_width         ymax = box[5] * orig_images[0].shape[0] / img_height         color = colors[int(box[0])]         label = '{}: {:.2f}'.format(classes[int(box[0])], box[1])         current_axis.add_patch(plt.Rectangle((xmin, ymin), xmax-xmin, ymax-ymin, color=color, fill=False, linewidth=2))           current_axis.text(xmin, ymin, label, size='x-large', color='white', bbox={'facecolor':color, 'alpha':1.0})      plt.show() # Visualize detected bounding boxes. # 1: Build the Keras model # Clear previous models from memory. model = ssd_300(image_size=(img_height, img_width, 3),                 n_classes=1,                 mode='inference',                 l2_regularization=0.005,                 scales=[0.1, 0.2, 0.37, 0.54, 0.71, 0.88, 1.05], # The scales for MS COCO are [0.07, 0.15, 0.33, 0.51, 0.69, 0.87, 1.05]                 aspect_ratios_per_layer=[[1.0, 2.0, 0.5],                                         [1.0, 2.0, 0.5, 3.0, 1.0/3.0],                                         [1.0, 2.0, 0.5, 3.0, 1.0/3.0],                                         [1.0, 2.0, 0.5, 3.0, 1.0/3.0],                                         [1.0, 2.0, 0.5],                                         [1.0, 2.0, 0.5]],                 two_boxes_for_ar1=True,                 steps=[8, 16, 32, 64, 100, 300],                 offsets=[0.5, 0.5, 0.5, 0.5, 0.5, 0.5],                 clip_boxes=False,                 variances=[0.1, 0.1, 0.2, 0.2],                 normalize_coords=True,                 subtract_mean=[123, 117, 104],                 swap_channels=[2, 1, 0],                 confidence_thresh=confidence_threshold,                 iou_threshold=0.45,                 top_k=200,                 nms_max_output_size=400)  # 2: Load the trained weights into the model.  model.load_weights(model_path, by_name=True)  # 3: Compile the model so that Keras won't complain the next time you load it.  adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)  ssd_loss = SSDLoss(neg_pos_ratio=3, alpha=1.0)  model.compile(optimizer=adam, loss=ssd_loss.compute_loss) # We need to create an SSDLoss object in order to pass that to the model loader. read_image = cv2.imread(img_path) y_pred_thresh = predict_on_image(read_image, model) display_pedicted_image(read_image, y_pred_thresh) cv2.waitKey() # Create a VideoCapture object and read from input file # If the input is the camera, pass 0 instead of the video file name cap = cv2.VideoCapture(video_path)   # Check if camera opened successfully if (cap.isOpened()== False):    print("Error opening video stream or file")  fps = cap.get(cv2.CAP_PROP_FPS) print("Frames per second using video.get(cv2.CAP_PROP_FPS) : {0}".format(fps)) #frames_to_skip = fps/5 frames_to_skip = 1 i=1 # Read until video is completed while(cap.isOpened()):   # Capture frame-by-frame   ret, frame = cap.read()   if ret == True:          if i == frames_to_skip:         y_pred_thresh = predict_on_image(frame, model)         display_pediction_image(frame, y_pred_thresh)         cv2.imshow('SSD Keras Plates recognition', frame)          # Press Q on keyboard to  exit         if cv2.waitKey(25) & 0xFF == ord('q'):             break         i=0     i+=1         # Break the loop   else:      break    # When everything done, release the video capture object cap.release()   # Closes all the frames cv2.destroyAllWindows() video_getter = VideoGet(video_path).start() cps = CountsPerSec().start() while True:         if (cv2.waitKey(1) == ord("q")) or video_getter.stopped:             video_getter.stop()             break          frame = video_getter.read()         frame = putIterationsPerSec(frame, cps.countsPerSec())         y_pred_thresh = predict_on_image(frame, model)         display_pediction_image(frame, y_pred_thresh)         cv2.imshow('SSD Keras Plates recognition', frame)         cps.increment() video_getter = VideoGet(video_path).start() video_shower = VideoShow(video_getter.frame).start() cps = CountsPerSec().start()  while True:     if video_getter.stopped or video_shower.stopped:         video_shower.stop()         video_getter.stop()         break      frame = video_getter.frame     frame = putIterationsPerSec(frame, cps.countsPerSec())     y_pred_thresh = predict_on_image(frame, model)     display_pediction_image(frame, y_pred_thresh)     video_shower.frame = frame     cps.increment()