OpenCV C ++ накапливать Weeighted — странное поведение

Я пытаюсь получить скользящее среднее количество кадров с моей камеры, но через несколько секунд изображение усредненных кадров становится ярче, ярче и белее.

моя камера обеспечивает изображение в оттенках серого с 3 каналами.
Я на Windows 7, Visualstudio 2012, OpenCV 243

#include<opencv2\opencv.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include <iostream>

using namespace cv;
using namespace std;int main(int argc, char* argv[])
{
VideoCapture cap(0);
Mat frame1;
cap.read(frame1);
Mat acc = Mat::zeros(frame1.size(), CV_32FC1);

while(1){
Mat frame;
Mat gray;
cap.read(frame);
cvtColor(frame ,gray ,CV_BGR2GRAY,0);
accumulateWeighted(gray, acc,0.005);
imshow("gray", gray);
imshow("acc", acc);
waitKey(1); //don't know why I need it but without it the windows freezes
}
}

Может кто-нибудь сказать мне, что я сделал не так?
Спасибо!

0

Решение

Проблема здесь в том, как imshow отображает значения матрицы в значения пикселей. Как правило, необработанные данные с камеры поступают как целочисленный тип данных, обычно в диапазоне [0, 255]. Функция накапливать весы делает то, что вы ожидаете, и вычисляет скользящее среднее для кадров. Таким образом, acc — это матрица с плавающей точкой со значениями где-то в [0, 255].

Теперь, когда вы передаете эту матрицу imshow, значения матрицы должны быть сопоставлены с интенсивностями. Поскольку тип данных является типом с плавающей запятой, 0 отображается на черный, 1 отображается на белый, а все, что находится вне этого диапазона, обрезается. Таким образом, только если область вашего изображения очень будет темным и останется таким, будет ли скользящее среднее значение оставаться ниже 1 и будет отображен в цвет, отличный от чистого белого.

К счастью, исправить это просто:

imshow («акк», акк / 255);

2

Другие решения

Я нашел более элегантное решение для этого вопроса. Функция, которая вам нужна, уже предоставлена ​​OpenCV. Это работает с 3-канальными цветными или 1-канальными изображениями в оттенках серого:

метод convertScaleAbs

Встроенная документация

масштабирует элементы массива, вычисляет абсолютные значения и преобразует результаты в 8-разрядные целые числа без знака: dst (i) = saturate_castabs (src (i) * alpha + beta)

Подпись

convertScaleAbs(InputArray src, OutputArray dst, double alpha=1, double beta=0)

Пример кода

// Variables
Mat frame;
Mat accumulator;
Mat scaled;

// Initialize the accumulator matrix
accumulator = Mat::zeros(frame.size(), CV_32FC3);

while(1){
// Capture frame
capture >> frame;

// Get 50% of the new frame and add it to 50% of the accumulator
accumulateWeighted(frame, accumulator, 0.5);

// Scale it to 8-bit unsigned
convertScaleAbs(accumulator, scaled);

imshow("Original", frame);

imshow("Weighted Average", scaled);

waitKey(1);
}
1

По вопросам рекламы [email protected]