Motion Detector (opencv)

  • Автор темы Drony
  • Дата начала
D

Drony

#1
Всем привет! =)
Только начал разбираться с OpenCV. Хочу попробовать камеру распознавать движение. Детектор движения должен реализоваться на C++ при помощи библиотеки OpenCV.
Но возникла одна проблемка. Вот, собственно код:
C++:
#include "v_motion_detector.h"

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/video/tracking.hpp>

const double VMotionDetector::MOTION_THRESHOLD = 10;
const double VMotionDetector::MIN_CONTOUR_AREA = 150;

VMotionDetector::VMotionDetector( const cv::Size& imageSize, double cycleTime) :
m_previousImage( cv::Mat::zeros( imageSize, CV_8UC1 ) ),
m_motionHistoryImage( imageSize, CV_32FC1 ),
m_openingKernel( 5, 5, CV_8UC1 ),
m_segmask( imageSize, CV_32FC1 ),
m_maxMotionGradient( 1.5 * cycleTime ),
m_motionHistoryDuration( 7 * cycleTime )
{
}

void VMotionDetector::detectMovingRegions( const cv::Mat& currentFrame, double timestamp,
std::vector<cv::Rect>& targets , cv::Mat& mask )
{
//Сглаживаем текущий кадр (currentFrame) фильтром Гаусса, чтобы избавиться от шумов.

cv::GaussianBlur( currentFrame, m_bluredImage, cv::Size( 3, 3 ), -1 );

//Из сглаженного текущего кадра (m_bluredImage ) вычитаем предыдущий (m_previousImage).
//Если искомые изображения были в градациях серого, то и значения пикселей
//в разности (mask) будут изменяться от нуля до 255(при восьми битной глубине цвета).

cv::absdiff( m_bluredImage, m_previousImage, mask );

//Сравниваем значения полученной разности с некоторым пороговым
//значением (MOTION_THRESHOLD). Если значение пикселя больше порогового,
//то этот пиксель принадлежит движущемуся объекту, иначе отбрасываем его.
//Теперь мы получили бинарное изображение (mask), где ноль означает, что 
//пиксель не движется, отличное от нуля значение – пиксель движется.

cv::threshold( mask, mask, MOTION_THRESHOLD, 255, cv::THRESH_BINARY );

//Применяем морфологические операции закрытия и открытия,
//чтобы избавиться от движущихся регионов малого размера (шумы камеры).
//Полученное изображение (mask) и есть движущийся контур.

cv::morphologyEx( mask, mask, cv::MORPH_CLOSE, cv::Mat() );
cv::morphologyEx( mask, mask, cv::MORPH_OPEN, m_openingKernel,
cv::Point( -1, -1 ), 1, cv::BORDER_CONSTANT, cv::Scalar( 0 ) );

//Наносим бинарное изображение на так называемое изображение истории движения
//(motionHistoryImage). На нём нарисованы движущиеся контуры за последние, например,
//200 мс (m_motionHistoryDuration). Контуры были получены через постоянные промежутки
//времени. Интенсивность пикселей контура обратно пропорциональна времени, которое
//прошло от измерения контура до данного момента. Т.е. чем раньше был получен
//движущийся контур, тем он бледнее изображён на изображение истории движения.

cv::updateMotionHistory( mask, m_motionHistoryImage, timestamp, m_motionHistoryDuration );

//Выделяем регионы (targets) с различными движениями на изображение истории движения. 

cv::segmentMotion(m_motionHistoryImage, m_segmask, targets, timestamp, m_maxMotionGradient);

//Отбрасываем все регионы, площадь которых меньше некоторого значения (MIN_CONTOUR_AREA).

std::vector<cv::Rect>::const_iterator it = targets.begin();

for(it = targets.begin(); it != targets.end(); ++it) {
if(cv::countNonZero(mask(*it)) < MIN_CONTOUR_AREA) 
targets.erase(it);
}
//Сохраняем сглаженный текущий кадр как предыдущий кадр.
m_bluredImage.copyTo( m_previousImage );
}
На этапе выполнения возникает ошибка:
"Expression: vector iterator not dereferencable."
Облазил весь интеренет, ничего не нашёл. Одна надежда на вас)) Помогите, пожалуйста!!!!!