Я пытаюсь получить скользящее среднее количество кадров с моей камеры, но через несколько секунд изображение усредненных кадров становится ярче, ярче и белее.
моя камера обеспечивает изображение в оттенках серого с 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
}
}
Может кто-нибудь сказать мне, что я сделал не так?
Спасибо!
Проблема здесь в том, как imshow отображает значения матрицы в значения пикселей. Как правило, необработанные данные с камеры поступают как целочисленный тип данных, обычно в диапазоне [0, 255]. Функция накапливать весы делает то, что вы ожидаете, и вычисляет скользящее среднее для кадров. Таким образом, acc — это матрица с плавающей точкой со значениями где-то в [0, 255].
Теперь, когда вы передаете эту матрицу imshow, значения матрицы должны быть сопоставлены с интенсивностями. Поскольку тип данных является типом с плавающей запятой, 0 отображается на черный, 1 отображается на белый, а все, что находится вне этого диапазона, обрезается. Таким образом, только если область вашего изображения очень будет темным и останется таким, будет ли скользящее среднее значение оставаться ниже 1 и будет отображен в цвет, отличный от чистого белого.
К счастью, исправить это просто:
imshow («акк», акк / 255);
Я нашел более элегантное решение для этого вопроса. Функция, которая вам нужна, уже предоставлена OpenCV. Это работает с 3-канальными цветными или 1-канальными изображениями в оттенках серого:
Встроенная документация
масштабирует элементы массива, вычисляет абсолютные значения и преобразует результаты в 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);
}