Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用OpenCV在不将所有图像保留在内存中的情况下平均N个图像_Java_Opencv_Image Processing_Average - Fatal编程技术网

Java 如何使用OpenCV在不将所有图像保留在内存中的情况下平均N个图像

Java 如何使用OpenCV在不将所有图像保留在内存中的情况下平均N个图像,java,opencv,image-processing,average,Java,Opencv,Image Processing,Average,我创建了一个类,该类尝试从任意数量的图像(逐个传递)创建一个平均图像 这个进程将在它自己的线程中运行,而其他线程读取图像,进行处理,并将输出传递给这个平均对象 不幸的是,每增加一张图像,平均图像就会变得越来越亮。 我怀疑我的平均函数有错误,但我一直找不到 编辑:我遗漏了等式中的“curImg/curCount”部分。通过此校正,图像现在变暗。我的平均成绩不好 编辑2:我看到我被否决了。我能做些什么来改进这个问题吗 class AverageImage { private Vector&l

我创建了一个类,该类尝试从任意数量的图像(逐个传递)创建一个平均图像

这个进程将在它自己的线程中运行,而其他线程读取图像,进行处理,并将输出传递给这个平均对象

不幸的是,每增加一张图像,平均图像就会变得越来越亮。 我怀疑我的平均函数有错误,但我一直找不到

编辑:我遗漏了等式中的“curImg/curCount”部分。通过此校正,图像现在变暗。我的平均成绩不好

编辑2:我看到我被否决了。我能做些什么来改进这个问题吗

class AverageImage {
    private Vector<Mat> average = new Vector<>();
    private int count = 0;

    public void add(Mat img) {
        count++;
        Vector<Mat> splitImg = new Vector<>();
        Mat convertedImg = img.clone();
        convertedImg.convertTo(convertedImg, CvType.CV_32FC1);
        Core.split(img.clone(), splitImg);

        if (average.isEmpty()) {
            average = splitImg;
        } else {
            // prevAverage * (prevCount/curCount) + curImg/curCount
            for (int i = 0; i < average.size(); i++) {
                Core.multiply(average.get(i), new Scalar((count - 1) / ((double) count)), average.get(i));
                Mat temp = new Mat();
                Core.divide(count, splitImg.get(i), temp);
                Core.add(average.get(i), temp, average.get(i));
            }
        }
    }

    public Mat getAverage() {
        Mat convertedAverage = new Mat();
        Core.merge(average, convertedAverage);
        convertedAverage.convertTo(convertedAverage.clone(), CvType.CV_8UC3);
        return convertedAverage;
    }

}
类平均图像{
私有向量平均值=新向量();
私有整数计数=0;
公共无效添加(材料img){
计数++;
向量拆分img=新向量();
Mat convertedImg=img.clone();
convertedImg.convertTo(convertedImg,CvType.CV_32FC1);
split(img.clone(),splitImg);
if(average.isEmpty()){
平均值=splitImg;
}否则{
//prevAverage*(prevCount/curCount)+curImg/curCount
对于(int i=0;i
次要注释:
convertedImg
在您的代码中根本没有使用。您可以删除它


你对所谓的世界的决定是正确的。然而,真正困扰您的部分是
divide
语句:

Core.divide(count, splitImg.get(i), temp);
,当您调用第一个元素为标量的变量时,正在执行的操作是:

dst(I) = saturate(scale / src(I))
scale
用于划分输出。因此,您正在做的是
count/splitImg.get(i)
而实际上您应该做的是
splitImg.get(i)/count
。考虑到这一点,
divide
不支持拍摄图像并除以系数。但是,一种解决方法是使用
核心。将
计数的倒数相乘:

Core.multiply(splitImg.get(i), new Scalar(1.0 / count), temp);
您所需要做的就是更改
核心。将
语句除以上面的语句,它就应该可以工作了

        // prevAverage * (prevCount/curCount) + curImg/curCount
        for (int i = 0; i < average.size(); i++) {
            Core.multiply(average.get(i), new Scalar((count - 1) / ((double) count)), average.get(i));
            Mat temp = new Mat();
            // Core.divide(count, splitImg.get(i), temp);
            Core.multiply(splitImg.get(i), new Scalar(1.0 / count), temp);
            Core.add(average.get(i), temp, average.get(i));
        }
最后,为了计算这个方程的第二项,我们做:

Core.multiply(splitImg.get(i), new Scalar(1.0 / count), temp);

对于数值稳定性,可能最好只存储累积和图像,并在需要平均值时将其除以当前N

注意不要溢出

Core.multiply(splitImg.get(i), new Scalar(1.0 / count), temp);