Tensorflow-Number-Plate-Recognition icon indicating copy to clipboard operation
Tensorflow-Number-Plate-Recognition copied to clipboard

How can i use it on video

Open Ratnadeep22 opened this issue 7 years ago • 3 comments

Hiii... great work

I just want to test this code on video... I have done all the this but its taking too much of time to process the single frame

Ratnadeep22 avatar Feb 17 '18 06:02 Ratnadeep22

Traceback (most recent call last): File "detect.py", line 180, in im = cv2.imread(sys.argv[1]) IndexError: list index out of range

how can i got ride of this?

Thamizh-Sterio avatar Sep 06 '18 05:09 Thamizh-Sterio

did anyone here use it on video ?

Abduoit avatar Jan 25 '19 21:01 Abduoit

#!/usr/bin/env python
#
#edited by ultimus11
#https://github.com/ultimus11
# Copyright (c) 2016 Matthew Earl
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
#     The above copyright notice and this permission notice shall be included
#     in all copies or substantial portions of the Software.
#
#     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
#     OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
#     NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
#     DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
#     OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
#     USE OR OTHER DEALINGS IN THE SOFTWARE.


"""
Routines to detect number plates.

Use `detect` to detect all bounding boxes, and use `post_process` on the output
of `detect` to filter using non-maximum suppression.

"""


__all__ = (
    'detect',
    'post_process',
)


import collections
import itertools
import math
import sys

import cv2
import numpy
import tensorflow as tf

import common
import model


def make_scaled_ims(im, min_shape):
    ratio = 1. / 2 ** 0.5
    shape = (im.shape[0] / ratio, im.shape[1] / ratio)

    while True:
        shape = (int(shape[0] * ratio), int(shape[1] * ratio))
        if shape[0] < min_shape[0] or shape[1] < min_shape[1]:
            break
        yield cv2.resize(im, (shape[1], shape[0]))


def detect(im, param_vals):
    """
    Detect number plates in an image.

    :param im:
        Image to detect number plates in.

    :param param_vals:
        Model parameters to use. These are the parameters output by the `train`
        module.

    :returns:
        Iterable of `bbox_tl, bbox_br, letter_probs`, defining the bounding box
        top-left and bottom-right corners respectively, and a 7,36 matrix
        giving the probability distributions of each letter.

    """

    # Convert the image to various scales.
    scaled_ims = list(make_scaled_ims(im, model.WINDOW_SHAPE))

    # Load the model which detects number plates over a sliding window.
    x, y, params = model.get_detect_model()

    # Execute the model at each scale.
    with tf.Session(config=tf.ConfigProto()) as sess:
        y_vals = []
        for scaled_im in scaled_ims:
            feed_dict = {x: numpy.stack([scaled_im])}
            feed_dict.update(dict(zip(params, param_vals)))
            y_vals.append(sess.run(y, feed_dict=feed_dict))
    writer = tf.summary.FileWriter("logs/", sess.graph)

    # Interpret the results in terms of bounding boxes in the input image.
    # Do this by identifying windows (at all scales) where the model predicts a
    # number plate has a greater than 50% probability of appearing.
    #
    # To obtain pixel coordinates, the window coordinates are scaled according
    # to the stride size, and pixel coordinates.
    for i, (scaled_im, y_val) in enumerate(zip(scaled_ims, y_vals)):
        for window_coords in numpy.argwhere(y_val[0, :, :, 0] >
                                                       -math.log(1./0.99 - 1)):
            letter_probs = (y_val[0,
                                  window_coords[0],
                                  window_coords[1], 1:].reshape(
                                    7, len(common.CHARS)))
            letter_probs = common.softmax(letter_probs)

            img_scale = float(im.shape[0]) / scaled_im.shape[0]

            bbox_tl = window_coords * (8, 4) * img_scale
            bbox_size = numpy.array(model.WINDOW_SHAPE) * img_scale

            present_prob = common.sigmoid(
                               y_val[0, window_coords[0], window_coords[1], 0])

            yield bbox_tl, bbox_tl + bbox_size, present_prob, letter_probs


def _overlaps(match1, match2):
    bbox_tl1, bbox_br1, _, _ = match1
    bbox_tl2, bbox_br2, _, _ = match2
    return (bbox_br1[0] > bbox_tl2[0] and
            bbox_br2[0] > bbox_tl1[0] and
            bbox_br1[1] > bbox_tl2[1] and
            bbox_br2[1] > bbox_tl1[1])


def _group_overlapping_rectangles(matches):
    matches = list(matches)
    num_groups = 0
    match_to_group = {}
    for idx1 in range(len(matches)):
        for idx2 in range(idx1):
            if _overlaps(matches[idx1], matches[idx2]):
                match_to_group[idx1] = match_to_group[idx2]
                break
        else:
            match_to_group[idx1] = num_groups
            num_groups += 1

    groups = collections.defaultdict(list)
    for idx, group in match_to_group.items():
        groups[group].append(matches[idx])

    return groups


def post_process(matches):
    """
    Take an iterable of matches as returned by `detect` and merge duplicates.

    Merging consists of two steps:
      - Finding sets of overlapping rectangles.
      - Finding the intersection of those sets, along with the code
        corresponding with the rectangle with the highest presence parameter.

    """
    groups = _group_overlapping_rectangles(matches)

    for group_matches in groups.values():
        mins = numpy.stack(numpy.array(m[0]) for m in group_matches)
        maxs = numpy.stack(numpy.array(m[1]) for m in group_matches)
        present_probs = numpy.array([m[2] for m in group_matches])
        letter_probs = numpy.stack(m[3] for m in group_matches)

        yield (numpy.max(mins, axis=0).flatten(),
               numpy.min(maxs, axis=0).flatten(),
               numpy.max(present_probs),
               letter_probs[numpy.argmax(present_probs)])


def letter_probs_to_code(letter_probs):
    return "".join(common.CHARS[i] for i in numpy.argmax(letter_probs, axis=1))


if __name__ == "__main__":
    cap = cv2.VideoCapture(0)
    f = numpy.load("weights.npz")
    #for this weights.npz has to be in same directory as this program
    param_vals = [f[n] for n in sorted(f.files, key=lambda s: int(s[4:]))]
    while True:
        ret, im = cap.read()
        if not ret:
            break
        #im = cv2.imread(sys.argv[1])
        im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) / 255.
        print ("RUN")
        for pt1, pt2, present_prob, letter_probs in post_process(
                                                      detect(im_gray, param_vals)):
            #pt1 = tuple(reversed(map(int, pt1)))
            #pt2 = tuple(reversed(map(int, pt2)))
            pt1 = tuple(reversed(list(map(int, pt1))))
            pt2 = tuple(reversed(list(map(int, pt2))))
            code = letter_probs_to_code(letter_probs)
            color = (0.0, 255.0, 0.0)
            cv2.rectangle(im, pt1, pt2, color)
            cv2.putText(im,
                        code,
                        pt1,
                        cv2.FONT_HERSHEY_PLAIN,
                        1.5,
                        (0, 0, 0),
                        thickness=5)
            cv2.putText(im,
                        code,
                        pt1,
                        cv2.FONT_HERSHEY_PLAIN,
                        1.5,
                        (255, 255, 255),
                        thickness=2)
        cv2.imshow("detected numberplate", im)
        k = cv2.waitKey(10)
        cv2.imwrite(sys.argv[1], im)
        if k == ord('q'):
            break

#detect.py in.jpg weights.npz out.jpg
#for detection in video use this command in terminal or cmd:  inVideoDetect.py out.jpg
#https://drive.google.com/file/d/0B-MtVXQMUxQiZElfSy1ON09QQ0U/view
#Name this file as inVideoDetect.py and add it to same directory as detect.py

ultimus11 avatar Feb 14 '21 18:02 ultimus11