Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to detect the non/least-changing pixels of successive images

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:

  • collect a number of equally-sized and graysized frames in a list called previous
  • if a certain amount of frames is collected, call the function np.std
  • This function loops over all the x-and y-coordinates of a new image.
  • Calculate the standard deviation of the grayvalues for all the coordinates based on the grayvalues of the corresponding coordinates of all the frames

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!

like image 273
HJA24 Avatar asked Nov 15 '19 13:11

HJA24


People also ask

How do I find out the pixels of an image?

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.

What is a pixel in digital image processing?

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.


1 Answers

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

enter image description here

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.

enter image description here

If instead you also thresholded each frame, you get a more pronounced result

enter image description here

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)
like image 165
nathancy Avatar answered Sep 18 '22 23:09

nathancy