Compare the difference of using weighted average and normal average over the last frames streaming from your webcam using OpenCV in Python.
The effect can be seen in the video below and code used to create that is provided below.
The code is straight forward and not optimized. The average is calculated by using a deque from the collection library from Python to create a circular buffer.
The two classes of AverageBuffer and WeightedAverageBuffer share the same code for the constructor and apply, but have each their implementation of get_frame which calculates the average and weighted average, respectively.
Please notice, that the code is not written for efficiency and the AverageBuffer has some easy wins in performance if calculated more efficiently.
An important point to see here, is that the frames are saved as float32 in the buffers. This is necessary when we do the actual calculations on the frames later, where we multiply them by a factor, say 4.
Example. The frames are uint8, which are integers 0 to 255. Say we multiply the frame by 4, and the value is 128. This will give 128*4 = 512, which as an uint8 is 0. Hence, we get an undesirable effect. Therefore we convert them to float32 to avoid this.
import cv2
import numpy as np
from collections import deque
class AverageBuffer:
def __init__(self, maxlen):
self.buffer = deque(maxlen=maxlen)
self.shape = None
def apply(self, frame):
self.shape = frame.shape
self.buffer.append(frame)
def get_frame(self):
mean_frame = np.zeros(self.shape, dtype='float32')
for item in self.buffer:
mean_frame += item
mean_frame /= len(self.buffer)
return mean_frame.astype('uint8')
class WeightedAverageBuffer(AverageBuffer):
def get_frame(self):
mean_frame = np.zeros(self.shape, dtype='float32')
i = 0
for item in self.buffer:
i += 4
mean_frame += item*i
mean_frame /= (i*(i + 1))/8.0
return mean_frame.astype('uint8')
# Setup camera
cap = cv2.VideoCapture(0)
# Set a smaller resolution
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
average_buffer = AverageBuffer(30)
weighted_buffer = WeightedAverageBuffer(30)
while True:
# Capture frame-by-frame
_, frame = cap.read()
frame = cv2.flip(frame, 1)
frame = cv2.resize(frame, (320, 240))
frame_f32 = frame.astype('float32')
average_buffer.apply(frame_f32)
weighted_buffer.apply(frame_f32)
cv2.imshow('WebCam', frame)
cv2.imshow("Average", average_buffer.get_frame())
cv2.imshow("Weighted average", weighted_buffer.get_frame())
if cv2.waitKey(1) == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
Why Value-driven Data Science is the Key to Your Success In the world of data…
Harnessing the Power of Project-Based Learning and Python for Machine Learning Mastery In today's data-driven…
Is Python the right choice for Machine Learning? Should you learn Python for Machine Learning?…
Learn Python by Creating 19 Projects Do you want to learn Python by creating projects?…
Implement a four-in-a-row game in Python On a high level, you will learn about the…
Implement a valid parentheses checker in Python Keep your skills sharp and start learning Python…