Получение коэффициента движения с помощью updateMotionHistory и MOG2

В настоящее время я работаю над проектом по обнаружению человеческих падений (основываясь на этой статье и этой). Я делаю это с C++ и OpenCV. Я застрял с вычислением коэффициента движения, я не совсем понимаю, как он должен быть произведен:

  1. В первой статье я понимаю, что это должно быть отношение суммы всех пикселей из MHI обнаруженного большого двоичного объекта (Motion History of Image) и количества (суммы?) Всех пикселей в обнаруженном большом двоичном объекте,
  2. Во-вторых, это отношение суммы пикселей в MHI обнаруженного большого двоичного объекта и суммы всех пикселей в обнаруженном большом двоичном объекте,

Дело в том, что, что бы я ни вычислял, мой код не производит ничего, что могло бы даже приблизиться к вычислению коэффициента движения. Может быть, я плохо понимаю эти уравнения.

Мой текущий код:

#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv/cv.h>
#include <opencv2/optflow.hpp>
#include<iostream>
#include<fstream>
#include<conio.h>

#define MHI_DURATION 0.5

using namespace cv;
using namespace cv::motempl;
using namespace std;

char key;
char mode;
short frames=0;

//text file for writing Cmotion
//plik tekstowy do zapisywania wspolczynnika C
ofstream coeff("motion_coeff.txt");

//MOG2
Ptr<BackgroundSubtractorMOG2> pMOG2 = createBackgroundSubtractorMOG2(3000, 64);

int main()
{
    //initial Mat's
    //poczatkowe Mat-y
    Mat frame;
    Mat mask, bin_mask;
    Mat bg;
    Mat gray;
    Mat mhi;
    Mat eroded, dilated;

VideoCapture cap("video.mp4");
//VideoCapture cap;

//cap.open(0);

while ((char)key != 'q' && (char)key != 27) {
    key = 0;
    frames += 1;
    double timestamp = (double)clock() / CLOCKS_PER_SEC;

    //securing input
    //Zabezpieczenie przed brakiem obrazu zrodlowego
    if (!cap.isOpened()) {
        cerr << "Undefined video source!";
        exit(EXIT_FAILURE);
    }

    //securing next frame
    //Zabezpieczenie przed brakiem nastepnej ramki
    if (!cap.read(frame)) {
        cerr << "Cannot read next frame!";
        exit(EXIT_FAILURE);
    }

    //main algorithm
    //dodatkowe Mat-y i zmienne pomocnicze
    Mat eroded, dilated;
    Mat mask, bin_mask;
    double mot_coeff = 0.0;
    double mhi_sum = 0.0;
    double fg_sum = 0.0;

    //resizing mhi
    //dostosowanie formatu i wymiaru mhi
    Size size = frame.size();
    if (mhi.size() != size) {
        mhi = Mat::zeros(size, CV_32F);
    }

    //morphological cleaning
    //"oczyszczenie" obrazu  - morfologia
    erode(frame, eroded, Mat(), Point(-1, -1), 3);
    dilate(eroded, dilated, Mat(6, 6, CV_32F), Point(-1, -1), 3);

    //MOG2 applying to imgae
    //nalozenie maski do mikstur gaussowskich
    pMOG2->apply(dilated, mask);

    //threshhold
    //binaryzacja i poszukiwanie najwiekszego konturu
    threshold(mask, bin_mask, 30, 1, THRESH_BINARY);

    //calculcating MHI
    //obliczenie MHI - Motion History
    updateMotionHistory(bin_mask, mhi, timestamp, MHI_DURATION);

    //two ways on calculating Cmotion
    //policzenie bialych pikseli w obu obrazach - wykrywany ksztalt
    double white_mhi = (mhi.rows * mhi.cols) - countNonZero(mhi);
    double white_fg = (bin_mask.rows * bin_mask.cols) - countNonZero(bin_mask);
    /*for (int i = 0; i < mhi.rows; i++) {
        for (int j = 0; j < mhi.cols; j++) {
            mhi_sum += mhi.at<float>(i, j);
            fg_sum += bin_mask.at<uchar>(i, j);
        }
    }*/
    //mot_coeff = white_mhi / white_fg;
    mot_coeff = white_mhi / white_fg;

    vector<vector<Point>> contours;
    double largest_contour = 0;
    int largest_id = 0;
    findContours(bin_mask, contours, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
    for (int i = 0; i < contours.size(); i++) {
        double area = contourArea(contours[i], false);
        if (area > largest_contour) {
            largest_contour = area;
            largest_id = i;
        }
    }

    //fitting ellipse to the biggest blob
    //nalozenie elipsy na najwiekszy kontur
    if (contours.size() > 0 & contours[largest_id].size() >= 5) {
        RotatedRect ell;
        ell = fitEllipse(contours[largest_id]);
        ellipse(frame, ell, Scalar(0, 0, 255), 2, 8);
    }

    stringstream ss, ss1, ss2;
    ss << "Motion coeff: " << mot_coeff;
    ss1 << "MHI blob pixels: " << white_mhi;
    ss2 << "FG blob pixels: " << white_fg;
    //ss1 << "MHI blob pixels: " << mhi_sum;
    //ss2 << "FG blob pixels: " << fg_sum;
    putText(frame, ss.str(), Point(10, 10), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 255), 1, 8);
    putText(frame, ss1.str(), Point(10, 30), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 255), 1, 8);
    putText(frame, ss2.str(), Point(10, 50), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 255), 1, 8);


    //writing down the Cmotion to file
    coeff << "Motion coefficient at frame " << frames << ": " << mot_coeff << ", scaled: " << "\n";

    //showing results
    imshow("Original image", frame);
    imshow("MOG2 mask", mask);
    imshow("MHI", mhi);


    //przerwa na wcisniecie klawisza
    key = (char)waitKey(30);
}
cap.release();
cv::destroyAllWindows();
return 0;
}

Буду очень признателен за ваши выводы относительно алгоритма!

Заранее спасибо!

0 ответов

Другие вопросы по тегам