如何在OpenCV中混合多张图像?

3

我有一组带有权重的图像,想要将它们混合在一起。我知道OpenCV中有一个混合命令可以混合两个图像。但是如何将多个图像混合在一起呢?

3个回答

5
混合可以使用以下代码完成(这是使用OpenCV的Java代码):
//Create a black-colored image
Mat mergedImage = new Mat(inputImageSize, inputImageType, new Scalar(0));
//Add each image from a vector<Mat> inputImages with weight 1.0/n where n is number of images to merge
for (Mat mat : inputImages) {
    Core.addWeighted(mergedImage, 1, mat, 1.0/n, 0, mergedImage);
}

编辑:上面的代码存在舍入误差。如果inputImageType是整数类型,则除以1/n会导致此问题。因此,上面的代码仅适用于浮点矩阵。


@StefanReinhardt - 你好,请给我一天时间。我下班后会仔细研究这个问题,但是你的猜测很有可能是正确的。正如你所怀疑的那样,我认为首先添加的图像会额外减少1 /(1 +(1 / n))次。暂时忽略这个答案,我深表歉意。 - saurabheights
我不确定,在第一步没有执行除法,但由于您将结果用作新的输入,因此它将再次被加权。 在我的测试中至少是这种情况。 但是,由于您可以将输入图像乘以标量,因此有一个简单的解决方法。只需不使用 addWeighted 而是直接使用 mergedImage += 1/n *mat 执行操作即可。 - Stefan Reinhardt
@StefanReinhardt:是的,结果将再次加权,但权重为1。这实际上是发生的事情(读取顺序:最内部的括号到外部,然后是最外层的):-(((1 * 0 + a1 / n)* 1.0 + a2 / n)* 1.0 + a3 / n)... = a1 / n + a2 / n + a3 / n + ...。因此,代码可能不同,但逻辑相同。但由于您已经测试过并发现不同,我将在下班后处理此问题。但根据opencv文档,没有任何问题。 - saurabheights
啊,对不起,你说得对,我错过了第一个权重因子实际上是1。在我的代码中它是(n-1)/n。再次抱歉打扰你了。现在两种情况的结果都是相同的... - Stefan Reinhardt
没关系。我承认这是一种有点奇特的图像平均方式 :). 无论如何,祝你愉快的图像处理,继续编码。 - saurabheights
显示剩余3条评论

2
简单的矩阵运算,比如下面这些怎么办?
blendedImage = weight_1 * image_1 + weight_2 * image_2 + ... + weight_n * image_n

实际上我尝试过了,但是它不起作用。后来我意识到问题在于我没有将混合图像的大小和类型初始化为图像的大小和类型。现在它可以工作了。 - user3747190

1
这里是用Python代码混合列表中多张图片的方法。我使用了Dennis答案中的基本公式。
首先,让我们获取三张图片。
import numpy as np
import cv2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

dim = (425, 425)

apple = mpimg.imread('apple.jpg')
apple = cv2.resize(apple, dim)

banana = mpimg.imread('banana.jpg')
banana = cv2.resize(banana, dim)

orange = mpimg.imread('orange.jpg')
orange = cv2.resize(orange, dim)

_ = plt.imshow(apple)
_ = plt.show()

_ = plt.imshow(banana)
_ = plt.show()

_ = plt.imshow(orange)
_ = plt.show()

这是图片:

enter image description here

enter image description here

enter image description here

现在让我们平均混合它们。由于有三张图片,每张图片对最终输出的贡献比例为0.333。
def blend(list_images): # Blend images equally.

    equal_fraction = 1.0 / (len(list_images))

    output = np.zeros_like(list_images[0])

    for img in list_images:
        output = output + img * equal_fraction

    output = output.astype(np.uint8)
    return output

list_images = [apple, banana, orange]
output = blend(list_images)

_ = plt.imshow(output)

这里是结果:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接