【问题标题】:How i can take the average of 100 image using opencv?我如何使用 opencv 取 100 张图像的平均值?
【发布时间】:2016-02-27 09:30:32
【问题描述】:

我有 100 张图像,每张是 598 * 598 像素,我想通过取像素的平均值来消除图像和噪点,但是如果我想使用“逐像素添加”,那么除以我会写一个循环,直到一个图像重复 596*598,一百个图像重复 598*598*100。

有什么方法可以帮我做这个操作吗?

【问题讨论】:

标签: c++ opencv add average


【解决方案1】:

您需要遍历每个图像,并累积结果。由于这可能会导致溢出,您可以将每个图像转换为CV_64FC3 图像,并在CV_64FC3 图像上进行累积。您也可以为此使用CV_32FC3CV_32SC3,即使用floatinteger 而不是double

累积所有值后,您可以同时使用convertTo

  • 将图片设为CV_8UC3
  • 将每个值除以图像数量,得到实际平均值。

这是一个示例代码,它创建 100 个随机图像,并计算并显示 意思是:

#include <opencv2\opencv.hpp>
using namespace cv;

Mat3b getMean(const vector<Mat3b>& images)
{
    if (images.empty()) return Mat3b();

    // Create a 0 initialized image to use as accumulator
    Mat m(images[0].rows, images[0].cols, CV_64FC3);
    m.setTo(Scalar(0,0,0,0));

    // Use a temp image to hold the conversion of each input image to CV_64FC3
    // This will be allocated just the first time, since all your images have
    // the same size.
    Mat temp;
    for (int i = 0; i < images.size(); ++i)
    {
        // Convert the input images to CV_64FC3 ...
        images[i].convertTo(temp, CV_64FC3);

        // ... so you can accumulate
        m += temp;
    }

    // Convert back to CV_8UC3 type, applying the division to get the actual mean
    m.convertTo(m, CV_8U, 1. / images.size());
    return m;
}

int main()
{
    // Create a vector of 100 random images
    vector<Mat3b> images;
    for (int i = 0; i < 100; ++i)
    {
        Mat3b img(598, 598);
        randu(img, Scalar(0), Scalar(256));

        images.push_back(img);
    }

    // Compute the mean
    Mat3b meanImage = getMean(images);

    // Show result
    imshow("Mean image", meanImage);
    waitKey();

    return 0;
}

【讨论】:

    【解决方案2】:

    假设图像不需要进行转换(伽玛、色彩空间或对齐)。 numpy 包可让您快速简洁地完成此操作。

    # List of images, all must be the same size and data type.
    images=[img0, img1, ...]
    avg_img = np.mean(images, axis=0)
    

    这将自动提升元素浮动。如果你想要作为 BGR888,那么:

    avg_img = avg_img.astype(np.uint8)
    

    也可以为每通道 16 位执行 uint16。如果您处理每个通道 8 位,则几乎可以肯定不需要 100 个图像。

    【讨论】:

      【解决方案3】:

      首先-将图像转换为浮点数。你有 N=100 张图片。想象一下,单个图像是 1 个图像的平均像素值的数组。您需要计算 N 个图像的平均像素值数组。

      A-X 图像的平均像素值数组,B-Y 图像的平均像素值数组。然后 C = (A * X + B * Y) / (X + Y) - X + Y 图像的平均像素值数组。为了在浮点运算中获得更好的精度,XY 应该大致相等

      您可以合并所有图像,例如 merge sort 中的子数组。在您的情况下,合并操作是C = (A * X + B * Y) / (X + Y),其中ABXY 图像的平均像素值数组

      【讨论】:

        猜你喜欢
        • 2013-06-21
        • 2022-11-30
        • 2011-12-17
        • 1970-01-01
        • 2021-05-20
        • 1970-01-01
        • 2021-08-02
        • 2021-04-04
        • 1970-01-01
        相关资源
        最近更新 更多