【问题标题】:Background isolation from complementing images与补充图像的背景隔离
【发布时间】:2022-01-24 17:18:05
【问题描述】:

我正在尝试从多个图像中分离出背景,这些图像彼此之间存在不同,即背景重叠。 我拥有的图像在此处单独列出:https://imgur.com/a/Htno7lm 但是这里有所有 6 个组合的预览:

我想在一系列图像中执行此操作,因为我正在阅读一些视频提要,并通过获取最后一帧来处理它们以隔离背景,如下所示:

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)

结果是我:

这仍然不完美,因为我正在寻找中值,如果我寻找众数值,性能会显着下降。

是否有一种方法可以像第一个替代方案一样获得作为缓冲区的结果,但会以良好的性能输出给我最好的结果?

--编辑 正如@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)

【问题讨论】:

  • 可以尝试“模式”而不是中位数。 6张应该足够便宜的图像。 scipy.stats.mode。 -- 如果您需要视频数据,请查看 OpenCV 的“背景分割”模块
  • 如果我对 np.asarray 或 np.stack 中的图像进行中位数,最终结果是相同的(最后一张图像)
  • 我尝试使用 scipy 模式,但它性能低下,我的最终目标是使用更大的图像并且超过 6 张,我尝试查看一些背景分割,但它与我的完全相反想要,我真的不知道如何将其转换为这个

标签: python numpy opencv image-processing


【解决方案1】:

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

如果我不使用直方图和大量内存,而是使用固定数量的工作表和对缓存友好的数据访问,它可能会更快。

【讨论】:

    猜你喜欢
    • 2022-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 2017-07-19
    • 2012-04-28
    • 2016-02-12
    • 2019-01-28
    相关资源
    最近更新 更多