Vehicle Speed Estimation Using Open CV Python With Source Code

Introduction :

This project uses the optical flow algorithm, specifically the Lucas-Kanade tracker, to estimate vehicle speeds from mono camera (CCTV) footage. Speed of a vehicle is an important parameter in many application areas such as traffic management, law enforcement and autonomous vehicles. It is being used for road safety monitor, speed control enforcement actions and increased efficiency of transportation systems due to accurate estimation. Now we can calculate the speed of a vehicle by using computer vision and machine learning. Here we are going to learn how to estimate the speed of a car and for that, I will be using Computer Vision powerful library OpenCV in Python. OpenCV is a complete open- source platform that has useful tools related to processing video and image, which makes it an excellent choice for implementing speed estimation systems.

Language And Interface :-

Vehicle Speed Estimation Using Python , A Versatile Programming Language With Source Code

Required Modules Or Packages:-

You Need The Packages List Given Below :-

  1. sys :- System-specific parameters and functions sys This module provides access to some variables used or maintained by the interpreter .
  2. _future_ :- gives access to features from future python versions in the current interpreter, permitting forward compatibility.
  3. Functools :- Implements higher-order functions for working with functions, such as decorators and other tools to build fault-tolerant APIs.
  4. Numpy :- It is a core library for numerical computation in python and it can handle large arrays of numbers.
  5. cv2 :- It is a library to use in Computer Vision You will get basic image processing tools while using cv2 for example, Image Reading and Writing .
  6. Os :- It offers facilities for working with OS, such as handling files and
  7. Itertools :-This module implements a number of iterator building blocks inspired by constructs from APL, Haskell.
  8. Contextlib :- some of the utilities I have found useful when working with context managers and code that need to close up resources, used in combining multiple operations together which requires being executed in one section killed.
  9. Common :- Often just a shared module or package, but not including
  10. Video :- Likely a custom or implementation specific video processing module in your project and not one from the standard libraries.
  11. tst_scene_render :- Most likely a package or custom module for scene rendering in some form of test environment, not part of the standard library.

    How to Run the Code :

    Step 1 . First , You Download and Install Visual Studio Code or VS Code In your PC or Laptop by VS Code Official Website .

    Step 2 . Now Open CMD As Administrator and install the above packages using pip .

    Step 3 . Now Open Visual Studio Code .

    Step 4. Now Make The files named as main.py , common.py , tst_scene_render.py , video.py .

    Step 5 . Now Copy And Paste The Code Given Below 𝗍

    Step 7 . After pasting The code , Save This & Click On Run Button . Step 8 . Now You will See The Output ..

    Code Explanation :-

    This is a Python Script to estimate vehicle speed in videos . It is a computer vision and numerical computation code, based on OpenCV and NumPy.

    Overview:

    The script first needs to import some essential libraries such as: sys for system operation; numpy is a numerical processing library; cv2 is the helper of all openCV

    operations. And it imports a custom module video for the tools at use with capture, and common utilities as well. Print functions derived from future that guarantees compatibility with Python 2/3.

    Main Components:

    App Class, it is at the core of this script and will include video processing functions as well as vehicle tracking logic.

    Initialization: It performs video capture, sets parameters for tracking and initializes to track variables. Video is used to open the video source. create_capture.

    Main Loop:

    Parameter Setup: parameters setting for Lucas-Kanade tracking and feature detection

    Implementation: It carries out optical flow tracking and for each valid frame, it uses the above speeds in different lanes to track feature points that off-passes are counted every 5 seconds.

    Speed Calculation — Analyzes the distance that tracked points have traveled to determine vehicle speed within set lanes and convert pixel measurements into KomotorHeures.

    Visualisation — Draws tracked points and lane boundaries on video frames, as well as the speeds that have been calculated. It saves the video that is annotated after

    processing :

    Main Function (main): This is the entry point of any script. It consumes the video source(bpu on voxl and a file) from command-line arguments or it defaults to webcam. It causes a creating new App object and the trackin starting.

    Execution:

    The script can be run, and it will go through video frames for vehicle tracking with the Lucas-Kanade method diffusion (for moving objects), speeds calculation from point to other in one frame process using required computer vision techniques; such as optical flow ) alongwith saving this data into a Video file. It gives a live view of the speeds and

    lane tracking for vehicles so can be used as a traffic analysis and monitoring tool.

    Source Code :

    				
    					import sys
    import math
    import numpy as np
    import cv2 as cv
    import video
    from common import anorm2, draw_str
    
    # Python 2/3 compatibility
    from __future__ import print_function
    
    class App:
        """
        The main application class that runs the Lucas-Kanade tracker on the provided video source.
        """
        def __init__(self, video_src):
            self.track_len = 2
            self.detect_interval = 4
            self.tracks = []
            self.cam = video.create_capture(video_src)
            self.alpha = 0.5
            self.frame_idx = 0
    
        def run(self):
            """
            This method contains the main loop that processes each frame and applies the Lucas-Kanade tracking algorithm.
            """
            # Lucas-Kanade parameters
            lk_params = dict(winSize=(15, 15),
                             maxLevel=2,
                             criteria=(cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
    
            feature_params = dict(maxCorners=500,
                                  qualityLevel=0.3, minDistance=7, blockSize=7)
    
            # Constants
            fps = 30
            px2m1 = 0.0895
            px2m2 = 0.088
            px2m3 = 0.0774
            px2m4 = 0.0767
            px2m5 = 0.0736
            ms2kmh = 3.6
    
            ret, first_frame = self.cam.read()
            cal_mask = np.zeros_like(first_frame[:, :, 0])
            view_mask = np.zeros_like(first_frame[:, :, 0])
            view_polygon = np.array([[440, 1920], [420, 220], [680, 250],
                                     [1080, 480], [1080, 1920]])
            cal_polygon = np.array([[440, 600], [420, 350], [1080, 350], [1080, 600]])
    
            polygon1 = np.array([[550, 490], [425, 500], [420, 570], [570, 570]])
            polygon2 = np.array([[570, 570], [555, 490], [680, 480], [720, 564]])
            polygon3 = np.array([[720, 564], [680, 480], [835, 470], [930, 540]])
            polygon4 = np.array([[930, 550], [835, 470], [970, 470], [1060, 550]])
            polygon5 = np.array([[1080, 550], [1070, 550], [970, 470], [1080, 550]])
    
            cv.fillConvexPoly(cal_mask, cal_polygon, 1)
            cv.fillConvexPoly(view_mask, view_polygon, 1)
    
            fourcc = cv.VideoWriter_fourcc(*'XVID')
            out = cv.VideoWriter("output.mp4", fourcc, 30.0, (1080, 1920))
    
            prv1, prv2, prv3, prv4, prv5 = 0, 0, 0, 0, 0
            prn1, prn2, prn3, prn4, prn5 = 0, 0, 0, 0, 0
            ptn1, ptn2, ptn3, ptn4, ptn5 = 0, 0, 0, 0, 0
    
            while self.cam.isOpened():
                _ret, frame = self.cam.read()
                if _ret:
                    vis = frame.copy()
                    cmask = frame.copy()
                    mask = cal_mask
    
                    frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
                    frame_gray = cv.bitwise_and(frame_gray, frame_gray, mask=mask)
                    vis = cv.bitwise_and(vis, vis, mask=view_mask)
    
                    cv.line(vis, (400, 575), (1080, 540), (0, 0, 255), 5)
                    cv.line(vis, (400, 495), (1080, 460), (0, 0, 255), 5)
    
                    cv.fillPoly(cmask, [polygon1], (120, 0, 120), cv.LINE_AA)
                    cv.fillPoly(cmask, [polygon2], (120, 120, 0), cv.LINE_AA)
                    cv.fillPoly(cmask, [polygon3], (0, 120, 120), cv.LINE_AA)
                    cv.fillPoly(cmask, [polygon4], (80, 0, 255), cv.LINE_AA)
                    cv.fillPoly(cmask, [polygon5], (255, 0, 80), cv.LINE_AA)
    
                    draw_str(vis, (30, 40), '1-lane speed: %d km/h' % prv1)
                    draw_str(vis, (30, 80), '2-lane speed: %d km/h' % prv2)
                    draw_str(vis, (30, 120), '3-lane speed: %d km/h' % prv3)
                    draw_str(vis, (30, 160), '4-lane speed: %d km/h' % prv4)
                    draw_str(vis, (30, 200), '5-lane speed: %d km/h' % prv5)
    
                    draw_str(vis, (900, 40), 'ptn1: %d' % prn1)
                    draw_str(vis, (900, 80), 'ptn2: %d' % prn2)
                    draw_str(vis, (900, 120), 'ptn3: %d' % prn3)
                    draw_str(vis, (900, 160), 'ptn4: %d' % prn4)
                    draw_str(vis, (900, 200), 'ptn5: %d' % prn5)
    
                    if len(self.tracks) > 0:
                        img0, img1 = self.prev_gray, frame_gray
                        p0 = np.float32([tr[-1] for tr in self.tracks]).reshape(-1, 1, 2)
                        p1, _st, _err = cv.calcOpticalFlowPyrLK(img0, img1, p0, None, **lk_params)
                        p0r, _st, _err = cv.calcOpticalFlowPyrLK(img1, img0, p1, None, **lk_params)
                        d = abs(p0 - p0r).reshape(-1, 2).max(-1)
                        good = d  self.track_len:
                                del tr[0]
                            new_tracks.append(tr)
                            cv.circle(vis, (x, y), 3, (0, 255, 0), -1)
                        self.tracks = new_tracks
    
                        for idx, tr in enumerate(self.tracks):
                            result_polygon1 = cv.pointPolygonTest(polygon1, tr[0], True)
                            result_polygon2 = cv.pointPolygonTest(polygon2, tr[0], True)
                            result_polygon3 = cv.pointPolygonTest(polygon3, tr[0], True)
                            result_polygon4 = cv.pointPolygonTest(polygon4, tr[0], True)
                            result_polygon5 = cv.pointPolygonTest(polygon5, tr[0], True)
    
                            if result_polygon1 > 0:
                                ptn1 += 1
                                dif1 = tuple(map(lambda i, j: i - j, tr[0], tr[1]))
                                mm1 += math.sqrt(dif1[0] * dif1[0] + dif1[1] * dif1[1])
                                mmm1 = mm1 / ptn1
                                v1 = mmm1 * px2m1 * fps * ms2kmh
    
                            if result_polygon2 > 0:
                                ptn2 += 1
                                dif2 = tuple(map(lambda i, j: i - j, tr[0], tr[1]))
                                mm2 += math.sqrt(dif2[0] * dif2[0] + dif2[1] * dif2[1])
                                mmm2 = mm2 / ptn2
                                v2 = mmm2 * px2m2 * fps * ms2kmh
    
                            if result_polygon3 > 0:
                                ptn3 += 1
                                dif3 = tuple(map(lambda i, j: i - j, tr[0], tr[1]))
                                mm3 += math.sqrt(dif3[0] * dif3[0] + dif3[1] * dif3[1])
                                mmm3 = mm3 / ptn3
                                v3 = mmm3 * px2m3 * fps * ms2kmh
    
                            if result_polygon4 > 0:
                                ptn4 += 1
                                dif4 = tuple(map(lambda i, j: i - j, tr[0], tr[1]))
                                mm4 += math.sqrt(dif4[0] * dif4[0] + dif4[1] * dif4[1])
                                mmm4 = mm4 / ptn4
                                v4 = mmm4 * px2m4 * fps * ms2kmh
    
                            if result_polygon5 > 0:
                                ptn5 += 1
                                dif5 = tuple(map(lambda i, j: i - j, tr[0], tr[1]))
                                mm5 += math.sqrt(dif5[0] * dif5[0] + dif5[1] * dif5[1])
                                mmm5 = mm5 / ptn5
                                v5 = mmm5 * px2m5 * fps * ms2kmh
    
                            prv1, prv2, prv3, prv4, prv5 = int(v1), int(v2), int(v3), int(v4), int(v5)
    
                    if self.frame_idx % self.detect_interval == 0:
                        mask = np.zeros_like(frame_gray)
                        mask[:] = 255
    
                        if len(self.tracks) > 0:
                            p = np.float32([tr[-1] for tr in self.tracks]).reshape(-1, 1, 2)
                            cv.polylines(mask, np.int32([tr]), False, 0)
                        p = cv.goodFeaturesToTrack(frame_gray, mask=mask, **feature_params)
    
                        if p is not None:
                            for x, y in np.float32(p).reshape(-1, 2):
                                self.tracks.append([(x, y)])
    
                    self.frame_idx += 1
                    self.prev_gray = frame_gray
                    cv.imshow("frame", vis)
                    out.write(vis)
    
                    if cv.waitKey(1) & 0xFF == ord("q"):
                        break
    
            self.cam.release()
            out.release()
            cv.destroyAllWindows()
    
    
    if __name__ == "__main__":
        video_src = sys.argv[1] if len(sys.argv) > 1 else 0
        App(video_src).run()
    
    				
    			

    Common.py

    				
    					"""
    This module contains some common routines used by other samples.
    """
    
    # Python 2/3 compatibility
    from __future__ import print_function
    import sys
    
    PY3 = sys.version_info[0] == 3
    
    if PY3:
        from functools import reduce
    
    import numpy as np
    import cv2 as cv
    
    # built-in modules
    import os
    import itertools as it
    from contextlib import contextmanager
    
    image_extensions = ['.bmp', '.jpg', '.jpeg', '.png', '.tif', '.tiff', '.pbm', '.pgm', '.ppm']
    
    
    class Bunch(object):
        def __init__(self, **kw):
            self.__dict__.update(kw)
    
        def __str__(self):
            return str(self.__dict__)
    
    
    def splitfn(fn):
        path, fn = os.path.split(fn)
        name, ext = os.path.splitext(fn)
        return path, name, ext
    
    
    def anorm2(a):
        return (a * a).sum(-1)
    
    
    def anorm(a):
        return np.sqrt(anorm2(a))
    
    
    def homotrans(H, x, y):
        xs = H[0, 0] * x + H[0, 1] * y + H[0, 2]
        ys = H[1, 0] * x + H[1, 1] * y + H[1, 2]
        s = H[2, 0] * x + H[2, 1] * y + H[2, 2]
        return xs / s, ys / s
    
    
    def to_rect(a):
        a = np.ravel(a)
        if len(a) == 2:
            a = (0, 0, a[0], a[1])
        return np.array(a, np.float64).reshape(2, 2)
    
    
    def rect2rect_mtx(src, dst):
        src, dst = to_rect(src), to_rect(dst)
        cx, cy = (dst[1] - dst[0]) / (src[1] - src[0])
        tx, ty = dst[0] - src[0] * (cx, cy)
        M = np.float64([[cx, 0, tx], [0, cy, ty], [0, 0, 1]])
        return M
    
    
    def lookat(eye, target, up=(0, 0, 1)):
        fwd = np.asarray(target, np.float64) - eye
        fwd /= anorm(fwd)
        right = np.cross(fwd, up)
        right /= anorm(right)
        down = np.cross(fwd, right)
        R = np.float64([right, down, fwd])
        tvec = -np.dot(R, eye)
        return R, tvec
    
    
    def mtx2rvec(R):
        w, u, vt = cv.SVDecomp(R - np.eye(3))
        p = vt[0] + u[:, 0] * w[0]
        c = np.dot(vt[0], p)
        s = np.dot(vt[1], p)
        axis = np.cross(vt[0], vt[1])
        return axis * np.arctan2(s, c)
    
    
    def draw_str(dst, target, s):
        x, y = target
        cv.putText(dst, s, (x, y), cv.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 255), 3, cv.LINE_AA)
    
    
    class Sketcher:
        def __init__(self, windowname, dests, colors_func):
            self.prev_pt = None
            self.windowname = windowname
            self.dests = dests
            self.colors_func = colors_func
            self.dirty = False
            self.show()
            cv.setMouseCallback(self.windowname, self.on_mouse)
    
        def show(self):
            cv.imshow(self.windowname, self.dests[0])
    
        def on_mouse(self, event, x, y, flags, param):
            pt = (x, y)
            if event == cv.EVENT_LBUTTONDOWN:
                self.prev_pt = pt
            elif event == cv.EVENT_LBUTTONUP:
                self.prev_pt = None
    
            if self.prev_pt and flags & cv.EVENT_FLAG_LBUTTON:
                for dst, color in zip(self.dests, self.colors_func()):
                    cv.line(dst, self.prev_pt, pt, color, 5)
                self.dirty = True
                self.prev_pt = pt
                self.show()
    
    
    _jet_data = {
        'red': ((0., 0, 0), (0.35, 0, 0), (0.66, 1, 1), (0.89, 1, 1), (1, 0.5, 0.5)),
        'green': ((0., 0, 0), (0.125, 0, 0), (0.375, 1, 1), (0.64, 1, 0), (0.91, 0, 0), (1, 0, 0)),
        'blue': ((0., 0.5, 0.5), (0.11, 1, 1), (0.34, 1, 1), (1, 0, 0))
    }
    
    cmap_data = {'jet': _jet_data}
    
    
    def make_cmap(name, n=256):
        data = cmap_data[name]
        xs = np.linspace(0.0, 1.0, n)
        channels = []
        eps = 1e-6
        for ch_name in ['blue', 'green', 'red']:
            ch_data = data[ch_name]
            xp, yp = [], []
            for x, y1, y2 in ch_data:
                xp += [x, x + eps]
                yp += [y1, y2]
            ch = np.interp(xs, xp, yp)
            channels.append(ch)
        return np.uint8(np.array(channels).T * 255)
    
    
    def nothing(*arg, **kw):
        pass
    
    
    def clock():
        return cv.getTickCount() / cv.getTickFrequency()
    
    
    @contextmanager
    def Timer(msg):
        print(msg, '...')
        start = clock()
        try:
            yield
        finally:
            print("%.2f ms" % ((clock() - start) * 1000))
    
    
    class StatValue:
        def __init__(self, smooth_coef=0.5):
            self.smooth_coef = smooth_coef
            self.value = None
    
        def update(self, v):
            if self.value is None:
                self.value = v
            else:
                c = self.smooth_coef
                self.value = c * self.value + (1.0 - c) * v
    
    
    class RectSelector:
        def __init__(self, win, callback):
            self.win = win
            self.callback = callback
            cv.setMouseCallback(win, self.onmouse)
            self.drag_start = None
            self.drag_rect = None
    
        def onmouse(self, event, x, y, flags, param):
            x, y = np.int16([x, y])
            if event == cv.EVENT_LBUTTONDOWN:
                self.drag_start = (x, y)
    
            if self.drag_start:
                if flags & cv.EVENT_FLAG_LBUTTON:
                    xo, yo = self.drag_start
                    x0, y0 = np.minimum([xo, yo], [x, y])
                    x1, y1 = np.maximum([xo, yo], [x, y])
                    self.drag_rect = None
                    if x1 - x0 > 0 and y1 - y0 > 0:
                        self.drag_rect = (x0, y0, x1, y1)
                else:
                    rect = self.drag_rect
                    self.drag_start = None
                    self.drag_rect = None
                    if rect:
                        self.callback(rect)
    
        def draw(self, vis):
            if not self.drag_rect:
                return False
            x0, y0, x1, y1 = self.drag_rect
            cv.rectangle(vis, (x0, y0), (x1, y1), (0, 255, 0), 2)
            return True
    
        @property
        def dragging(self):
            return self.drag_rect is not None
    
    
    def grouper(n, iterable, fillvalue=None):
        '''grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx'''
        args = [iter(iterable)] * n
        if PY3:
            output = it.zip_longest(fillvalue=fillvalue, *args)
        else:
            output = it.izip_longest(fillvalue=fillvalue, *args)
        return output
    
    
    def mosaic(w, imgs):
        '''Make a grid from images. w -- number of grid columns imgs -- images (must have same size and format)'''
        imgs = iter(imgs)
        img0 = next(imgs) if PY3 else imgs.next()
        pad = np.zeros_like(img0)
        imgs = it.chain([img0], imgs)
        rows = grouper(w, imgs, pad)
        return np.vstack(map(np.hstack, rows))
    
    
    def getsize(img):
        h, w = img.shape[:2]
        return w, h
    
    
    def mdot(*args):
        return reduce(np.dot, args)
    
    
    def draw_keypoints(vis, keypoints, color=(0, 255, 255
    
    				
    			

    tst_scene_render.py

    				
    					# Python 2/3 compatibility
    from __future__ import print_function
    
    import numpy as np
    import cv2 as cv
    from numpy import pi, sin, cos
    
    defaultSize = 512
    
    class TestSceneRender:
        def __init__(self, bgImg=None, fgImg=None, deformation=False, speed=0.25, **params):
            self.time = 0.0
            self.timeStep = 1.0 / 30.0
            self.foreground = fgImg
            self.deformation = deformation
            self.speed = speed
    
            if bgImg is not None:
                self.sceneBg = bgImg.copy()
            else:
                self.sceneBg = np.zeros((defaultSize, defaultSize), np.uint8)
    
            self.w = self.sceneBg.shape[0]
            self.h = self.sceneBg.shape[1]
    
            if fgImg is not None:
                self.foreground = fgImg.copy()
                self.center = self.currentCenter = (int(self.w / 2 - fgImg.shape[0] / 2), int(self.h / 2 - fgImg.shape[1] / 2))
    
                self.xAmpl = self.sceneBg.shape[0] - (self.center[0] + fgImg.shape[0])
                self.yAmpl = self.sceneBg.shape[1] - (self.center[1] + fgImg.shape[1])
            else:
                self.center = self.currentCenter = (self.w // 2, self.h // 2)
                self.xAmpl = self.w // 2
                self.yAmpl = self.h // 2
    
            self.initialRect = np.array([(self.h / 2, self.w / 2), (self.h / 2, self.w / 2 + self.w / 10),
                                         (self.h / 2 + self.h / 10, self.w / 2 + self.w / 10),
                                         (self.h / 2 + self.h / 10, self.w / 2)]).astype(int)
            self.currentRect = self.initialRect
    
        def getXOffset(self, time):
            return int(self.xAmpl * cos(time * self.speed))
    
        def getYOffset(self, time):
            return int(self.yAmpl * sin(time * self.speed))
    
        def setInitialRect(self, rect):
            self.initialRect = rect
    
        def getRectInTime(self, time):
            if self.foreground is not None:
                tmp = np.array(self.center) + np.array((self.getXOffset(time), self.getYOffset(time)))
                x0, y0 = tmp
                x1, y1 = tmp + self.foreground.shape[0:2]
                return np.array([y0, x0, y1, x1])
            else:
                x0, y0 = self.initialRect[0] + np.array((self.getXOffset(time), self.getYOffset(time)))
                x1, y1 = self.initialRect[2] + np.array((self.getXOffset(time), self.getYOffset(time)))
                return np.array([y0, x0, y1, x1])
    
        def getCurrentRect(self):
            if self.foreground is not None:
                x0 = self.currentCenter[0]
                y0 = self.currentCenter[1]
                x1 = self.currentCenter[0] + self.foreground.shape[0]
                y1 = self.currentCenter[1] + self.foreground.shape[1]
                return np.array([y0, x0, y1, x1])
            else:
                x0, y0 = self.currentRect[0]
                x1, y1 = self.currentRect[2]
                return np.array([x0, y0, x1, y1])
    
        def getNextFrame(self):
            img = self.sceneBg.copy()
    
            if self.foreground is not None:
                self.currentCenter = (self.center[0] + self.getXOffset(self.time), self.center[1] + self.getYOffset(self.time))
    
                img[self.currentCenter[0]:self.currentCenter[0]+self.foreground.shape[0],
                    self.currentCenter[1]:self.currentCenter[1]+self.foreground.shape[1]] = self.foreground
            else:
                self.currentRect = self.initialRect + np.int(30 * cos(self.time * self.speed) + 50 * sin(self.time * self.speed))
    
                if self.deformation:
                    self.currentRect[1:3] += int(self.h / 20 * cos(self.time))
                cv.fillConvexPoly(img, self.currentRect, (0, 0, 255))
    
            self.time += self.timeStep
            return img
    
        def resetTime(self):
            self.time = 0.0
    
    def main():
        backGr = cv.imread(cv.samples.findFile('graf1.png'))
        fgr = cv.imread(cv.samples.findFile('box.png'))
    
        render = TestSceneRender(backGr, fgr)
    
        while True:
            img = render.getNextFrame()
            cv.imshow('img', img)
    
            ch = cv.waitKey(3)
            if ch == 27:
                break
    
        print('Done')
    
    if __name__ == '__main__':
        main()
        cv.destroyAllWindows()
    
    				
    			

    video.py

    				
    					'''
    Video capture sample.
    
    This sample shows how the VideoCapture class can be used to acquire video frames from a camera or movie file.
    It also provides an example of procedural video generation by an object, mimicking the VideoCapture interface (see Chess class).
    'create_capture' is a convenience function for capture creation, falling back to procedural video in case of error.
    
    Usage:
    video.py [--shotdir] [source0] [source1] ... sourceN
    
    sourceN is:
    - an integer for camera capture
    - a name of a video file
    - 'synth' for procedural video generation
    
    Synth examples:
    synth:bg=lena.jpg:noise=0.1
    synth:class=chess:bg=lena.jpg:noise=0.1:size=640x480
    
    Keys:
    ESC - exit
    SPACE - save current frame to directory
    '''
    
    # Python 2/3 compatibility
    from __future__ import print_function
    
    import numpy as np
    import cv2 as cv
    import re
    from numpy import pi, sin, cos
    
    # local modules
    from tst_scene_render import TestSceneRender
    import common
    
    class VideoSynthBase:
        def __init__(self, size=None, noise=0.0, bg=None, **params):
            self.bg = None
            self.frame_size = (640, 480)
            if bg is not None:
                self.bg = cv.imread(cv.samples.findFile(bg))
                h, w = self.bg.shape[:2]
                self.frame_size = (w, h)
    
            if size is not None:
                w, h = map(int, size.split('x'))
                self.frame_size = (w, h)
                self.bg = cv.resize(self.bg, self.frame_size)
    
            self.noise = float(noise)
    
        def render(self, dst):
            pass
    
        def read(self, dst=None):
            w, h = self.frame_size
            if self.bg is None:
                buf = np.zeros((h, w, 3), np.uint8)
            else:
                buf = self.bg.copy()
    
            self.render(buf)
    
            if self.noise > 0.0:
                noise = np.zeros((h, w, 3), np.int8)
                cv.randn(noise, np.zeros(3), np.ones(3) * 255 * self.noise)
                buf = cv.add(buf, noise, dtype=cv.CV_8UC3)
            return True, buf
    
        def isOpened(self):
            return True
    
    class Book(VideoSynthBase):
        def __init__(self, **kw):
            super(Book, self).__init__(**kw)
            backGr = cv.imread(cv.samples.findFile('graf1.png'))
            fgr = cv.imread(cv.samples.findFile('box.png'))
            self.render = TestSceneRender(backGr, fgr, speed=1)
    
        def read(self, dst=None):
            noise = np.zeros(self.render.sceneBg.shape, np.int8)
            cv.randn(noise, np.zeros(3), np.ones(3) * 255 * self.noise)
            return True, cv.add(self.render.getNextFrame(), noise, dtype=cv.CV_8UC3)
    
    class Cube(VideoSynthBase):
        def __init__(self, **kw):
            super(Cube, self).__init__(**kw)
            self.render = TestSceneRender(cv.imread(cv.samples.findFile('pca_test1.jpg')), deformation=True, speed=1)
    
        def read(self, dst=None):
            noise = np.zeros(self.render.sceneBg.shape, np.int8)
            cv.randn(noise, np.zeros(3), np.ones(3) * 255 * self.noise)
            return True, cv.add(self.render.getNextFrame(), noise, dtype=cv.CV_8UC3)
    
    class Chess(VideoSynthBase):
        def __init__(self, **kw):
            super(Chess, self).__init__(**kw)
            w, h = self.frame_size
            self.grid_size = sx, sy = 10, 7
            white_quads = []
            black_quads = []
            for i, j in np.ndindex(sy, sx):
                q = [[j, i, 0], [j+1, i, 0], [j+1, i+1, 0], [j, i+1, 0]]
                [white_quads, black_quads][(i + j) % 2].append(q)
            self.white_quads = np.float32(white_quads)
            self.black_quads = np.float32(black_quads)
    
            fx = 0.9
            self.K = np.float64([[fx*w, 0, 0.5*(w-1)],
                                 [0, fx*w, 0.5*(h-1)],
                                 [0.0, 0.0, 1.0]])
            self.dist_coef = np.float64([-0.2, 0.1, 0, 0])
            self.t = 0
    
        def draw_quads(self, img, quads, color=(0, 255, 0)):
            img_quads = cv.projectPoints(quads.reshape(-1, 3), self.rvec, self.tvec, self.K, self.dist_coef)[0]
            img_quads.shape = quads.shape[:2] + (2,)
            for q in img_quads:
                cv.fillConvexPoly(img, np.int32(q*4), color, cv.LINE_AA, shift=2)
    
        def render(self, dst):
            t = self.t
            self.t += 1.0 / 30.0
            sx, sy = self.grid_size
            center = np.array([0.5*sx, 0.5*sy, 0.0])
            phi = pi/3 + sin(t*3) * pi/8
            c, s = cos(phi), sin(phi)
            ofs = np.array([sin(1.2*t), cos(1.8*t), 0]) * sx * 0.2
            eye_pos = center + np.array([cos(t)*c, sin(t)*c, s]) * 15.0 + ofs
            target_pos = center + ofs
            R, self.tvec = common.lookat(eye_pos, target_pos)
            self.rvec = common.mtx2rvec(R)
            self.draw_quads(dst, self.white_quads, (245, 245, 245))
            self.draw_quads(dst, self.black_quads, (10, 10, 10))
    
    # Class dictionary
    classes = dict(chess=Chess, book=Book, cube=Cube)
    
    # Presets dictionary
    presets = dict(
        empty='synth:',
        lena='synth:bg=lena.jpg:noise=0.1',
        chess='synth:class=chess:bg=lena.jpg:noise=0.1:size=640x480',
        book='synth:class=book:bg=graf1.png:noise=0.1:size=640x480',
        cube='synth:class=cube:bg=pca_test1.jpg:noise=0.0:size=640x480'
    )
    
    def create_capture(source=0, fallback=presets['chess']):
        '''
        source: camera index, video file, or synth:[...]
        '''
        source = str(source).strip()
    
        # Win32: handle drive letter ('c:', ...)
        source = re.sub(r'(^|=)([a-zA-Z]):([/\\a-zA-Z0-9])', r'\1?disk\2?\3', source)
        chunks = source.split(':')
        chunks = [re.sub(r'\?disk([a-zA-Z])\?', r'\1:', s) for s in chunks]
    
        source = chunks[0]
        try:
            source = int(source)
        except ValueError:
            pass
    
        params = dict(s.split('=') for s in chunks[1:])
    
        cap = None
        if source == 'synth':
            Class = classes.get(params.get('class', None), VideoSynthBase)
            try:
                cap = Class(**params)
            except:
                pass
        else:
            cap = cv.VideoCapture(source)
            if 'size' in params:
                w, h = map(int, params['size'].split('x'))
                cap.set(cv.CAP_PROP_FRAME_WIDTH, w)
                cap.set(cv.CAP_PROP_FRAME_HEIGHT, h)
    
        if cap is None or not cap.isOpened():
            print('Warning: unable to open video source:', source)
            if fallback is not None:
                return create_capture(fallback, None)
        return cap
    
    if __name__ == '__main__':
        import sys
        import getopt
    
        print(__doc__)
    
        args, sources = getopt.getopt(sys.argv[1:], '', 'shotdir=')
        args = dict(args)
        shotdir = args.get('--shotdir', '.')
        if len(sources) == 0:
            sources = [0]
    
        caps = list(map(create_capture, sources))
        shot_idx = 0
    
        while True:
            imgs = []
            for i, cap in enumerate(caps):
                ret, img = cap.read()
                imgs.append(img)
                cv.imshow('capture %d' % i, img)
    
            ch = cv.waitKey(1)
            if ch == 27:
                break
            if ch == ord(' '):
                for i, img in enumerate(imgs):
                    fn = '%s/shot_%d_%03d.bmp' % (shotdir, i, shot_idx)
                   
    
    				
    			

    Output :

    After Running the Code , You Will See The Output Like This 

    Additional Notes :-
    • Ensure that your video has a clear view of the road and vehicles for accurate speed
    • Adjust parameters in common.py if needed to fit specific requirements or to improve performance.

    Find More Projects

    Complain Management using Python with a Graphical User Interface (GUI) Introduction: The Complain Management using Python program designed to manage complaints effectively …

    COVID 19 Hospital Management Using Python [Django Framework] Introduction: The COVID-19 Hospital Management is a Python-based application that tracks web applications for Hospitals. …

    Drawing Ganesha Using Python Turtle Graphics[Drawing Ganapati Using Python] Introduction In this blog post, we will learn how to draw Lord Ganesha …

    Contact Management System in Python with a Graphical User Interface (GUI) Introduction: The Contact Management System is a Python-based application designed to …

    KBC Game using Python with Source Code Introduction : Welcome to this blog post on building a “Kaun Banega Crorepati” (KBC) game …

    Basic Logging System in C++ With Source Code Introduction : It is one of the most important practices in software development. Logging …

    Get Huge Discounts
    More Python Projects