如何删除移动的对象以仅获取背景?

时间:2018-12-10 17:09:35

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

我实际上是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

2 个答案:

答案 0 :(得分:0)

我对OpenCV不太熟悉,所以如果我不提供可以复制和粘贴的代码段,希望您能对不起。但是,如果我正确理解了伪代码,它就是这样做的:

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%的相关性来判断像素是否“相同”。然后,它将所有标记的像素取平均值,并将其平均。

答案 1 :(得分:0)

正如评论者中提到的那样,图像的均值确实消除了前景,但是整个图像变得有些褪色。这是执行此操作的代码:

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)

我从中得到的输出图像:

enter image description here

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

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)

最终输出:

enter image description here

如果图像更多,则可以完全删除前景。希望您有可以建立的基础。

我的代码假定您所有图像的尺寸均相同。如果您以不同的视图捕获图像,则解决方案将更加复杂。在这种情况下,您可能必须使用模板匹配算法(您的伪代码似乎在做类似的事情)来从图像中提取常用画布。