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 :-
- sys :- System-specific parameters and functions sys This module provides access to some variables used or maintained by the interpreter .
- _future_ :- gives access to features from future python versions in the current interpreter, permitting forward compatibility.
- Functools :- Implements higher-order functions for working with functions, such as decorators and other tools to build fault-tolerant APIs.
- Numpy :- It is a core library for numerical computation in python and it can handle large arrays of numbers.
- 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 .
- Os :- It offers facilities for working with OS, such as handling files and
- Itertools :-This module implements a number of iterator building blocks inspired by constructs from APL, Haskell.
- 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.
- Common :- Often just a shared module or package, but not including
- Video :- Likely a custom or implementation specific video processing module in your project and not one from the standard libraries.
- 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 …