首页 > 解决方案 > 检测连续图像的非/最小变化像素的最快方法

问题描述

我想找到静态视频流的像素。通过这种方式,我可以检测到视频流中的徽标和其他非移动项目。我的脚本背后的想法如下:

我的脚本:

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()

这个过程非常缓慢,我很好奇是否有更快的方法来做到这一点。我对 Cython 等持开放态度。非常感谢提前!

标签: pythonimagenumpyopencvcomputer-vision

解决方案


一种方法是使用 逐帧比较每个帧cv2.bitwise_and()。这个想法是前一帧中的像素必须存在于当前帧中才能成为不变的像素。通过遍历帧列表,场景中的所有特征都必须存在于前一帧和当前帧中,才能被视为非移动项目。因此,如果我们按顺序遍历每一帧,最后一次迭代将具有所有先前帧的共享特征。

使用每秒捕获一次的这组帧

在此处输入图像描述

我们将每一帧转换为灰度,然后cv2.bitwise_and()使用前一帧和当前帧。每次连续迭代的不变像素以灰色突出显示,而变化像素为黑色。最后一次迭代应该展示所有帧之间共享的像素。

在此处输入图像描述

相反,如果您还对每一帧进行阈值处理,您会得到更明显的结果

在此处输入图像描述

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)

推荐阅读