I want to find the pixels of a video stream that are static. This way I can detect logos and other non-moving items on my video stream. My idea behind the script is as follows:
previous
np.std
x-
and y-coordinates
of a new image.My script:
import math
import cv2
import numpy as np
video = cv2.VideoCapture(0)
previous = []
n_of_frames = 200
while True:
ret, frame = video.read()
if ret:
cropped_img = frame[0:150, 0:500]
gray = cv2.cvtColor(cropped_img, cv2.COLOR_BGR2GRAY)
if len(previous) == n_of_frames:
stdev_gray = np.std(previous, axis=2)
previous = previous[1:]
previous.append(gray)
else:
previous.append(gray)
cv2.imshow('frame', frame)
key = cv2.waitKey(1)
if key == ord('q'):
break
video.release()
cv2.destroyAllWindows()
This process is pretty slow and I am curious if there are faster ways to do this. I am open to Cython etc. Many many thanks in advance!
We can do this via the following formula: Assume a window or image with a given WIDTH and HEIGHT. We then know the pixel array has a total number of elements equaling WIDTH * HEIGHT. For any given X, Y point in the window, the location in our 1 dimensional pixel array is: LOCATION = X + Y*WIDTH.
In digital imaging, a pixel (abbreviated px), pel, or picture element is the smallest addressable element in a raster image, or the smallest addressable element in an all points addressable display device; so it is the smallest controllable element of a picture represented on the screen.
An approach is to compare each frame-by-frame using cv2.bitwise_and()
. The idea is that pixels in the previous frame must be present in the current frame to be a non-changing pixel. By iterating through the list of frames, all features in the scene must be present in the previous and current frame to be considered a non-moving item. So if we sequentially iterate through each frame, the last iteration will have shared features from all previous frames.
Using this set of frames captured once per second
We convert each frame to grayscale then cv2.bitwise_and()
with the previous and current frame. The non-changing pixels of each successive iteration are highlighted in gray while changing pixels are black. The very last iteration should showcase pixels shared between all frames.
If instead you also thresholded each frame, you get a more pronounced result
import cv2
import glob
images = [cv2.imread(image, 0) for image in glob.glob("*.png")]
result = cv2.bitwise_and(images[0], images[1])
for image in images[2:]:
result = cv2.bitwise_and(result, image)
cv2.imshow('result', result)
cv2.waitKey(0)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With