使用OpenCV从图像序列中获取中间图像

aho*_*ota 6 java android opencv image-processing matrix

我有一系列图像,我想要计算中间图像(删除移动元素).直观地,对循环进行硬编码以遍历所有像素将具有总运行时间以及相当大的存储器使用.有没有办法在OpenCV中轻松完成此操作?(我对平均不感兴趣,我需要做一个中位数).我正在为Android编写这个(使用OpenCV4Android),因此显然计算能力有限.

小智 3

如果平均值没问题:

Mat result(CV_64FC3, listImages[0].size());
for(int i = 0; i < listImages.size(); i++) {
    result += listImages[i];
}
result /= listImages.size();
result.convertTo(result, CV_8UC3);
Run Code Online (Sandbox Code Playgroud)

编辑:

这个快速伪中位数应该可以解决问题:

// Following algorithm will retain the pixel which is the closest to the mean
// Computing Mean
Mat tmpResult = Mat.zeros(listImages[0].size(), CV_64FC3);
for(int i = 0; i < listImages.size(); i++) {
    tmpResult += listImages[i];
}
tmpResult /= listImages.size();
tmpResult.convertTo(tmpResult, CV_8UC3);
// We will now, for each pixel retain the closest to the mean
// Initializing result with the first image
Mat result(listImages[0].clone());
Mat diff1, diff2, minDiff;
for(int i = 1; i < listImages.size(); i++) {
    // Computing diff between mean/newImage and mean/lastResult
    absdiff(tmpResult, listImages[i], diff1);
    absdiff(tmpResult, result, diff2);
    // If a pixel of the new image is closer to the mean, it replaces the old one
    min(diff1, diff2, minDiff);
    // Get the old pixels that are still ok
    result = result & ~(minDiff - diff2);
    // Get the new pixels
    result += listImages[i] & (minDiff - diff2);
}
Run Code Online (Sandbox Code Playgroud)

然而经典的应该也相当快。它是 O(nb^2 * w * h),其中 nb 是图像数量,w、h 是图像的宽度、高度。上面是O(nb * w * h),在Mats上有更多的操作。

经典代码(几乎所有计算都将在本机中进行):

Mat tmp;
// We will sorting pixels where the first mat will get the lowest pixels and the last one, the highest
for(int i = 0; i < listImages.size(); i++) {
    for(int j = i + 1; j < listImages.size(); j++) {
        listImages[i].copyTo(tmp);
        min(listImages[i], listImages[j], listImages[i]);
        max(listImages[j], tmp, listImages[j]);
    }
}
// We get the median
Mat result = listImages[listImages.size() / 2];
Run Code Online (Sandbox Code Playgroud)