我试图从多个影像中分离出一个背景,这些影像彼此之间有一些不同的东西,即与背景重叠。我拥有的影像在此处单独列出:
我想在一系列影像中做到这一点,因为我正在阅读一些视频提要,并通过获取最后一帧来处理它们以隔离背景,如下所示:
import os
import cv2
first = True
bwand = None
for filename in os.listdir('images'):
curImage = cv2.imread('images/%s' % filename)
if(first):
first = False
bwand = curImage
continue
bwand = cv2.bitwise_and(bwand,curImage)
cv2.imwrite("and.png",bwand)
从这段代码中,我总是用按位运算来增加我的缓冲区,但我得到的结果不是我想要的:按位和:
就视频过滤和性能而言,并发添加到缓冲区的方式对我来说是最好的方法,但如果我把它当作一个串列,我可以像这样寻找中值:
import os
import cv2
import numpy as np
sequence = []
for filename in os.listdir('images'):
curImage = cv2.imread('images/%s' % filename)
sequence.append(curImage)
imgs = np.asarray(sequence)
median = np.median(imgs, axis=0)
cv2.imwrite("res.png",median)
结果是我:
这仍然不完美,因为我正在寻找中值,如果我要寻找众数值,性能会显著下降。
是否有一种方法可以像第一个替代方案一样获得作为缓冲区的结果,但以良好的性能输出给我最好的结果?
--Edit 正如@Christoph Rackwitz 所建议的,我使用了 OpenCV 背景减法器,它作为请求的功能之一,它是一个缓冲区,但结果并不是最令人愉快的:
代码:
import os
import cv2
mog = cv2.createBackgroundSubtractorMOG2()
for filename in os.listdir('images'):
curImage = cv2.imread('images/%s' % filename)
mog.apply(curImage)
x = mog.getBackgroundImage()
cv2.imwrite("res.png",x)
uj5u.com热心网友回复:
由于scipy.stats.mode
需要很长时间才能完成它,我手动做了同样的事情:
- 计算直方图(对于每个影像的每一行的每个像素的每个通道)
argmax
获取模式- 重塑和铸造
仍然不是视频速度,但很好。numba
可能可以加快速度。
filenames = ...
assert len(filenames) < 256, "need larger dtype for histogram"
stack = np.array([cv.imread(fname) for fname in filenames])
sheet = stack[0]
hist = np.zeros((sheet.size, 256), dtype=np.uint8)
index = np.arange(sheet.size)
for sheet in stack:
hist[index, sheet.flat] = 1
result = np.argmax(hist, axis=1).astype(np.uint8).reshape(sheet.shape)
del hist # because it's huge
cv.imshow("result", result); cv.waitKey()
如果我不使用直方图和大量存储器,而是使用固定数量的作业表和快取友好的资料访问,它可能会更快。
0 评论