Motion Detector (opencv)

Тема в разделе "C/C++/C#", создана пользователем Drony, 22 окт 2011.

  1. Drony

    Drony Гость

    Всем привет! =)
    Только начал разбираться с 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."
    Облазил весь интеренет, ничего не нашёл. Одна надежда на вас)) Помогите, пожалуйста!!!!!
     

Поделиться этой страницей