How i can take the average of 100 image using opencv?

后端 未结 3 2011
南方客
南方客 2021-02-06 02:54

i have 100 image, each one is 598 * 598 pixels, and i want to remove the pictorial and noise by taking the average of pixels, but if i want to use Adding for \"pixel by pixel\"t

相关标签:
3条回答
  • 2021-02-06 03:36

    You need to loop over each image, and accumulate the results. Since this is likely to cause overflow, you can convert each image to a CV_64FC3 image, and accumualate on a CV_64FC3 image. You can use also CV_32FC3 or CV_32SC3 for this, i.e. using float or integer instead of double.

    Once you have accumulated all values, you can use convertTo to both:

    • make the image a CV_8UC3
    • divide each value by the number of image, to get the actual mean.

    This is a sample code that creates 100 random images, and computes and shows the mean:

    #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;
    }
    
    0 讨论(0)
  • 2021-02-06 03:36

    Firstly- convert images to floats. You have N=100 images. Imagine that a single image is an array of average pixel values of 1 image. You need to calculate an array of average pixel values of N images.

    Let A- array of average pixel values of X images, B - array of average pixel values of Y images. Then C = (A * X + B * Y) / (X + Y) - array of average pixel values of X + Y images. To get better accuracy in floating point operations X and Y should be approximately equal

    You may merge all you images like subarrays in merge sort. In you case merge operation is C = (A * X + B * Y) / (X + Y) where A and B are arrays of average pixel values of X and Y images

    0 讨论(0)
  • 2021-02-06 03:53

    Suppose that the images will not need to undergo transformations (gamma, color space, or alignment). The numpy package lets you do this quickly and succinctly.

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

    This will auto-promote the elements to float. If you want the as BGR888, then:

    avg_img = avg_img.astype(np.uint8)
    

    Could also do uint16 for 16 bits per channel. If you are dealing with 8 bits per channel, you almost certainly won't need 100 images.

    0 讨论(0)
提交回复
热议问题