【问题标题】:How to remove moving objects to obtain background only?如何去除移动的物体只获得背景?
【发布时间】:2019-05-11 15:12:25
【问题描述】:

我几乎是 python 新手,对它了解不多。我需要帮助将此伪代码转换为 Python,Python 是通过删除图像中的移动对象来获取背景的。关于伪代码,我不理解第 3、4 和 5 行,所以也许一旦将其转换为 Python,我可以更好地理解它。在第 3 行和第 4 行,我不明白 & 的作用,在最后一行,我什至不明白它是如何计算图像的。

任何帮助将不胜感激。

代码如下:

Mat sequence[3];// the sequence of images to loop through
Mat output, x = 0, y = 0; // looping through the sequence         
    matchTemplate(sequence[i], sequence[i+1], output, CV_TM_CCOEFF_NORMED)
    mask = 1 & (output>0.9) // get correlated part amongst the images
    x += sequence[i] & mask + sequence[i+1] & mask; // accumulate background infer
    y += 2*mask; // keep count 
end of loop;
Mat bg = x.mul(1.0/y); // average background

下面还提供了可供尝试的示例图像:

image1

image2

image3

【问题讨论】:

  • 欢迎杰克。更多代码和一些图像会很有用。
  • 是算法的问题,还是实现的问题?如果是后者,你应该说你是否理解伪代码,如果不是,为什么。
  • 另外,做for every pixel: take all 3 values from the imgs, drop outlier if any, and bg = avg不是更简单吗?
  • 我几乎是 python 新手,对它了解不多。关于伪代码,我不理解第 3、4 和 5 行,所以也许一旦将其转换为 Python,我可以更好地理解它。在第 3 行和第 4 行中,我不明白 & 的作用以及在最后一行中,它甚至是如何计算图像的。
  • 你可以试试@Wassinger。我想它会起作用的。平均将显示最终图像中的所有对象,但只是有点褪色。没有对象实际上无法获取背景。

标签: python image opencv image-processing computer-vision


【解决方案1】:

我对OpenCV不是很熟悉,所以如果我没有提供代码sn-p你可以复制和粘贴,希望你能原谅我。但如果我正确理解伪代码,它就是这样做的:

sequence = list of images
x will hold sum of backgrounds
y will hold the number of frames use to build x

for each index i in sequence:
    c = matrix of correlation coefficients between (sequence[i], sequence[i+1]) from matchTemplate
    mask = pixels that are highly correlated (90%+)
    x += actual pixels from sequence[i] & mask and sequence[i+1] & mask that are considered background
    y += 2 for every pixel in mask

bg = average of background images x / number of frames y

因此,对于每对图像,它会标记两个图像中相同的像素。假设是相邻帧之间的背景不会发生变化,而前景会发生变化。像素是否“相同”是根据相关性>90%来判断的。然后它取所有标记的像素,并对它们进行平均。

【讨论】:

  • 谢谢。在这里,我会在 Python 中按原样使用与号吗?因为我仍然不明白如何在 Python 中实现这段代码。我已经对它的作用有了一些了解。
【解决方案2】:

正如其中一位评论者所提到的,图像的均值确实去除了前景,但整个图像变得有点褪色。这是执行此操作的代码:

import skimage.io as io
import numpy as np
import matplotlib.pyplot as plt

cim1 = io.imread('https://i.stack.imgur.com/P44wT.jpg')
cim2 = io.imread('https://i.stack.imgur.com/wU4Yt.jpg')
cim3 = io.imread('https://i.stack.imgur.com/yUbB6.jpg')

x,y,z = cim1.shape
newimage = np.copy(cim1)
for row in range(x-1):
    for col in range(y-1):
        r = np.mean([cim1[row][col][0],cim2[row][col][0],cim3[row][col][0]]).astype(int)
        g = np.mean([cim1[row][col][1],cim2[row][col][1],cim3[row][col][1]]).astype(int)
        b = np.mean([cim1[row][col][2],cim2[row][col][2],cim3[row][col][2]]).astype(int)
        newimage[row][col] = [r,g,b]

fix, ax = plt.subplots(figsize=(10,10))
ax.axis('off')
ax.imshow(newimage)

我从中得到的输出图像:

解决这个问题的更好方法是找到三幅图像的中值。您在算法中拥有的图像越多,背景就越好。这是我试过的一个 sn-p (只是用中位数代替平均值)。如果您有更多图像,您可以获得更准确的图像。

x,y,z = cim1.shape
newimage = np.copy(cim1)
for row in range(x-1):
    for col in range(y-1):
        r = np.median([cim1[row][col][0],cim2[row][col][0],cim3[row][col][0]]).astype(int)
        g = np.median([cim1[row][col][1],cim2[row][col][1],cim3[row][col][1]]).astype(int)
        b = np.median([cim1[row][col][2],cim2[row][col][2],cim3[row][col][2]]).astype(int)
        newimage[row][col] = [r,g,b]


fix, ax = plt.subplots(figsize=(10,10))   
ax.axis('off')
ax.imshow(newimage)

最终输出:

如果您有更多图像,则可以完全移除前景。希望您有可以借鉴的想法。

我的代码假设您的所有图像都具有相同的尺寸。如果您在不同的视图中捕获图像,解决方案会稍微复杂一些。在这种情况下,您可能必须使用模板匹配算法(您的伪代码似乎在做类似的事情)从图像中提取公共画布。

【讨论】:

  • 谢谢。那么,你是说如果一个普通人手持拍摄一些相同场景的照片(相机有点晃动),这不适用吗? @Muthukrishnan
  • 你能转换伪代码吗?因为显然图像不会那么静止,因为它们将由普通人在没有任何三脚架的情况下拍摄。 @Muthukrishnan
  • 伪代码是模板匹配(第 3 行)输出是值在 -1 和 1 之间的 corr 矩阵的图像,1 是完美匹配。按位 & 运算符为您提供二进制匹配(掩码)或 0.9 阈值不匹配。如果匹配为 1,则复制像素,否则不复制。我像在伪代码中一样在您的图像上运行模板匹配,因为图像非常不同,相关性没有给我任何东西。如果图像的比例不同,则模板匹配不起作用,这是在没有三脚架的情况下拍摄的情况。您可能需要一种尺度不变的方法。 @JackShane
猜你喜欢
  • 1970-01-01
  • 2016-04-20
  • 1970-01-01
  • 2021-01-20
  • 1970-01-01
  • 2014-07-11
  • 2013-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多