Проблема с концептуализацией использования класса в проекте отслеживания

#c #class #oop #opencv #tracking

#c #класс #ооп #opencv #отслеживание

Вопрос:

У меня действительно возникли некоторые проблемы с концептуализацией моей проблемы с использованием классов, в надежде, что кто-то более опытный сможет мне помочь.

Я обрабатываю кадры из видеопотока, и в каждом новом кадре я идентифицирую головы людей под камерой и обводю их прямоугольником (это работает нормально). Затем эти прямоугольники сохраняются в векторе переменных RECT.

Я создал базовый класс с 2 атрибутами, идентификационный номер (1,2,3,4 …) и историю отслеживания.

Итак, что я хочу делать с каждым новым прямоугольником, который загружается в кадр, это проверять, не перекрывается ли он с любым из прямоугольников из предыдущего кадра (я сделаю этот код похожим на функцию Matlabs RectInt).

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

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

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

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

 #include <iostream>
#include <stdlib.h>
#include <vector>
#include "windows.h"
#include <opencv2opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv/cv.h>
#include "opencv2/imgproc.hpp"
#include <opencv2/highgui.hpp>
#include <stdio.h>
using namespace std;

class Person
{
public:
    Person(int x);
    ~Person();
    vector<RECT>* processrectangles;
    void Person::InitialiseRectangles(vector<RECT>*);
    void Person::addhistory(RECT);
private:
    int IDnumber;
    vector<RECT> history;
};

Person::Person(int x)
{
    IDnumber = x;
}

Person::~Person()
{
}
void Person::InitialiseRectangles(vector<RECT>* processrectangles) {
    RECT head;
    head.top = 187;
    head.bottom = 218;
    head.left = 183;
    head.right = 209;
    processrectangles->push_back(head);
    head.top = 177;
    head.bottom = 205;
    head.left = 185;
    head.right = 212;
    processrectangles->push_back(head);
    head.top = 156;
    head.bottom = 186;
    head.left = 191;
    head.right = 217;
    processrectangles->push_back(head);
    head.top = 142;
    head.bottom = 172;
    head.left = 193;
    head.right = 221;
    processrectangles->push_back(head);
    head.top = 128;
    head.bottom = 159;
    head.left = 197;
    head.right = 223;
    processrectangles->push_back(head);
}

void Person::addhistory(RECT inpt) { //I dont know how to call this specific to the variables ID number
    history.push_back(inpt);
    //This is simply to limit the history to 15 elements
    if (history.size()>15)
    {
        history.erase(history.begin());
    }
}

int main() {
    int NextID = 1;
    int counter = 1;
    cv::Point pt1, pt2;
    vector<RECT> processrectangles;
    processrectangles.clear();

    //Loads a plain black image
    cv::Mat img;
    const stringamp; image_name = "E:\James Mallett\Documents\Skripsie\JG Mallett 2016\HeadData-CBSR\Black\black-1.png";
    cout << image_name << endl;
    img=cv::imread(image_name,1);

    Person Start(1); // I know this initialises with an ID of 1

    Start.InitialiseRectangles(amp;processrectangles);//This was done to simplify my much larger project
    
    for (RECT constamp; rect : processrectangles)
    {
        // rect is the one Rectangle being processed in this loop, hopefully attaching it to an existing ID
        // or creating its own one
        std::cout << "Rect number: " << counter << std::endl;
        std::cout << "rect.top: " << rect.top << std::endl;
        std::cout << "rect.bottom: " << rect.bottom << std::endl;
        std::cout << "rect.left: " << rect.left << std::endl;
        std::cout << "rect.right: " << rect.right << std::endl;
        pt1.x = rect.left;//Define the points so that drawing is possible
        pt1.y = rect.top;
        pt2.x = rect.right;
        pt2.y = rect.bottom;

        cv::rectangle(img, pt1,pt2, CV_RGB(0, 255, 255), 1);
        cv::imshow("display", img);
        cv::waitKey(1);

        // What I want to try and do, but don't know how:
        //------------------------------------------------------------------------------
        //Check how many instances of Person there are (This is for interest sake)
        //------------------------------------------------------------------------------
        //I want to load the most recent rectangles from the  history of all elements of the Person Class-type, one by one,
        //As they are loaded one-by-one I will check If the rect being processed has an intersecting area with them (Not part of this quesiton)
        //If there is, I will assume they are from the same person and will add it to the history of that specific person, and skip the rest of the loop
        //----------------------------------------------------------------------------------
        //NOTE: I have already made an add history function that works I assume everything is the same object
        //----------------------------------------------------------------------------------
        //If it does not match any of them, start a new Person with the NextID and add the rectangle to its history
        // then increment NextID for the next person that is made

        //-----------------------------------

        //Then loop and do the same with the next rectangle

        system("pause");
        counter  ;
    }
    cv::destroyAllWindows;
    return 0;
}
  

введите описание изображения здесь

В приведенной выше последовательности прямоугольников это будет идентифицировано под идентификатором 1. Как только я смогу правильно запустить его с помощью этого, я увеличу его, чтобы он мог работать с несколькими последовательностями / людьми в одном кадре

Комментарии:

1. Я не вижу здесь ничего сложного. Вы собираетесь сохранить прямоугольник, связанный с каждым фреймом. Затем вам нужно будет сверить каждый прямоугольник со всеми предыдущими прямоугольниками. Здесь нет ничего потрясающего. Теперь это будет не очень эффективно. Через некоторое время все резко замедлится. Но это то, что вы хотите сделать, и пока вы решаете, что вам нужно искать все предыдущие прямоугольники, нет волшебной палочки, чтобы заставить их исчезнуть. Вы должны их искать.

2. Я думаю, вы, возможно, неправильно истолковали. Я планирую проверить новый прямоугольник на сходство только с самыми последними записями в истории различных объектов (каждый со своим собственным идентификатором), поэтому, если присутствует 4 объекта, он будет проверять только самые последние из них. В чем я не уверен, так это в том, что: А) Как найти последние записи для каждого используемого идентификатора, Б) Как правильно создавать новые объекты с новой историей (я думаю, связанные со структурой классов) и В) Как показать количество созданных объектов? (т. Е. Проверить количество идентификаторовкоторые используются)

3. Опять же, я не вижу здесь ничего сложного. A: вы только что сказали, что сохраняете только последний прямоугольник для каждого объекта, проблема решена; B: вектор или карта всех объектов, поэтому просто добавьте новую запись в вектор или карту; C: см. B — и вектор, и карта имеют size() .

4. Хорошо. Опять же, я сохраняю каждый прямоугольник в истории каждого конкретного объекта (см. Код, длина истории 15 местоположений). А затем при анализе каждого нового прямоугольника просматривайте все идентификаторы и просматривайте их самую последнюю историю (я не знаю, как выполнить этот поиск, отсюда и мой вопрос). То, что я искал, было скорее подтверждением того, что мой класс и функции были изложены правильно, и небольшим руководством по фактическому структурированию и вызову этих функций.