How can I take an average of 100 images using opencv?

I have 100 images, each of them is 598 * 598 pixels, and I want to remove the graphics and noise by taking the average of the pixels, but if I want to use Adding for "pixel by pixel" then division I will write a loop up to 596 * 598 repetitions for one image and 598 * 598 * 100 for hundreds of images.

Is there any way to help me in this operation?

+8
source share
3 answers

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

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

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

This is an example code that creates 100 random images, and calculates and displays as:

 #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; } 
+4
source

First convert the images to floats. You have N = 100 images. Imagine that a single image is an array of average pixel values ​​over 1 image. You need to calculate an array of average pixel values ​​for N images.

Let A be an array of average pixel values ​​of X images, B be an array of average pixel values ​​of Y images. Then C = (A * X + B * Y) / (X + Y) is an array of average pixel values ​​of X + Y images. To increase the accuracy of floating point operations, X and Y should be approximately equal

You can combine all your images, such as subarrays, into merge sort . In this case, the merge operation C = (A * X + B * Y) / (X + Y) , where A and B are arrays of average values ​​of pixels X and Y images

+1
source

Assume that the images do not have to undergo transformations (gamma, color space or alignment). The Numpy package allows you to do this quickly and concisely.

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

This will automatically promote items for swimming. If you want as BGR888, then:

 avg_img = avg_img.astype(np.uint8) 

Can also make uint16 for 16 bits per channel. If you are dealing with 8 bits per channel, you will almost certainly not need 100 images.

-1
source

Source: https://habr.com/ru/post/1244002/


All Articles