算法,越线检测,统计两个方向越线人数

1,cross_linedetect.h

#ifndef __CROSS_LINE_DETECT_H__ 
#define __CROSS_LINE_DETECT_H__ 

#include 
#include 

#include "touch_line_detect.h"
/*
typedef struct {
    double x1;
    double y1;
    double x2;
    double y2;
}Line;
typedef struct {
    Line line;
    int lines_interval;
} CrossLineParas;
typedef struct {
    cv::Rect region;
    int object_id;
}CrossLineObject;
typedef std::vector CrossLineObjects;
typedef struct {
    std::string camID;
    CrossLineObjects cross_object_list;
    Line line;
    int lines_interval = -1; 
}CrossLineInput;
typedef std::vector CrossLineInputArray;

typedef struct {
    int touch_flag;
    int first_touch;
}CrossLineOutputObject;
typedef std::vector CrossLineOutputObjects;
typedef struct {
    int come_num;
    int go_num;
    CrossLineOutputObjects cross_out_list;
    Line line;
    int lines_interval; 
}CrossLineOutput;
typedef std::vector CrossLineOutputArray;
*/

typedef struct {
    cv::Point c1;
    cv::Point c2;
    std::string identity_code;

    // integerated from IdentityStatus
    short side_flag;
    bool existed; 
    int missed_num;
}C_Passager;

class CrossLineCount {
    private:
        // record number of people crossing from -1 to 1 and vice versa
        int m_count_neg2pos;
        int m_count_pos2neg;
        int m_count_in_total;
        int m_count_out_total;
        std::vector<C_Passager> m_history_passagers;
        std::vector<C_Passager> m_latestframe_passagers;
    private:
        // dets = None
        byavs::Line m_line;
        int m_lines_interval;
   
        
    public:
        CrossLineCount();
        int set_latestframe_passagers(byavs::CrossLineObjects obj_list);
        int set_crossline(int lines_interval, byavs::Line line);
       
        // get the related position of current object with crossline
        float get_online_x (int lines_interval, float y);
        float get_online_y (int lines_interval, float x);
        int get_relatedpos_of_latestpassagers();
        int check_passager_crossline();

        int get_count_in_total();
        int get_count_out_total();

};

#endif

2,cross_linedetect.cpp

#include "cross_line_detect.h"

/**
 * contructor for class CrossLineCount
 */
CrossLineCount::CrossLineCount() {
    m_count_neg2pos = 0;
    m_count_pos2neg = 0;
    m_count_in_total = 0;
    m_count_out_total = 0;
}


float CrossLineCount::get_online_y (int lines_interval, float x) {
    int mov_mond = lines_interval - m_lines_interval/2;
    float y_online = ((m_line.y2 - m_line.y1) / (m_line.x2 - m_line.x1)) * 
        (x - m_line.x1 + mov_mond) + m_line.y1;
    return y_online;
}

float CrossLineCount::get_online_x(int lines_interval, float y) {
    int mov_mond = lines_interval - m_lines_interval/2;
    float x_online = (m_line.x2 - m_line.x1) / (m_line.y2 -m_line.y1) * 
        (y -m_line.y1 + mov_mond) + m_line.x1;
    return x_online;
}
/*
 * set the distrance between the lines,and the crossline
 */
int CrossLineCount::set_crossline(int lines_interval, byavs::Line line) {
    m_lines_interval = lines_interval;
    m_line = line;
    return 0;
}
int CrossLineCount::set_latestframe_passagers(byavs::CrossLineObjects obj_list) {
    m_latestframe_passagers.clear();

    for(int i=0; i<obj_list.size(); i++) {
        C_Passager passager;
        passager.c1.x = obj_list[i].region.x;
        passager.c1.y = obj_list[i].region.y;
        passager.c2.x = obj_list[i].region.x + obj_list[i].region.width;
        passager.c2.y = obj_list[i].region.y + obj_list[i].region.height;
        passager.identity_code = std::to_string(obj_list[i].object_id);
        passager.side_flag = 0;
        passager.existed = false;
        passager.missed_num = 0;

        m_latestframe_passagers.push_back(passager);
    }
    return 0;
}


// get the related position of latest passages in current frame
int CrossLineCount::get_relatedpos_of_latestpassagers() {
    m_line.x2 = m_line.x1 == m_line.x2 ? (m_line.x2 + 1) : m_line.x2;
    m_line.y2 = m_line.y1 == m_line.y2 ? (m_line.y2 + 1) : m_line.y2;

    for (auto &passager : m_latestframe_passagers) {
        cv::Point centroid;
        centroid.x = int(passager.c1.x + passager.c2.x) / 2;
        centroid.y = int(passager.c1.y + passager.c2.y) / 2;
        // if the bbox's centroid is below the crossline ===> side_flag = -1
        // if the bbox's centroid is on left of crossline ===> side_flag = -1
        // otherwise ====> side_flag = 1
        if (abs((m_line.y2 - m_line.y1) / (m_line.x2 - m_line.x1)) > 1) {
            if(centroid.y >= m_line.y1 && centroid.y <= m_line.y2) {
                float y_online_1 = get_online_y(0, centroid.x);
                float y_online_2 = get_online_y(m_lines_interval, centroid.x);
                if(centroid.y <= y_online_1 && centroid.y <= y_online_2) {
                    passager.side_flag = -1;
                }
                else if(centroid.y > y_online_1 && centroid.y > y_online_2) {
                    passager.side_flag = 1;
                }
                else {
                    for(auto h = m_history_passagers.begin(); 
                            h != m_history_passagers.end(); h++) {
                        if (h->identity_code == passager.identity_code) {
                            passager.side_flag = h->side_flag;
                        }
                    }
                }
            }
        }
        else {
            if(centroid.x >= m_line.x1 && centroid.x <= m_line.x2) {
                float x_online_1 = get_online_x(0, centroid.y);
                float x_online_2 = get_online_x(m_lines_interval, centroid.y);
                if(centroid.x <= x_online_1 && centroid.x <= x_online_2) {
                    passager.side_flag = -1;
                }
                else if(centroid.x > x_online_1 && centroid.x > x_online_2) {
                    passager.side_flag = 1;
                }
                else {
                    for(auto h = m_history_passagers.begin(); 
                            h != m_history_passagers.end(); h++) {
                        if (h->identity_code == passager.identity_code) {
                            passager.side_flag = h->side_flag;
                        }
                    }
                }
            }
        }
/*
        std::cout << "1111111111111111111111111111111111111111111111111"
            << "   identity_code:"<< passager.identity_code 
            << "   c1:("<< passager.c1.x<<","<< passager.c1.y << ")"
            <<", c2:("<< passager.c2.x<< ","<< passager.c2.y<<")"
            << "   side_flag:" << passager.side_flag<
    }
    return 0;
}

// check the passages is crossing the crossline with history_passager and 
// latestframe_passsagers
int CrossLineCount::check_passager_crossline() {
    get_relatedpos_of_latestpassagers();
    m_count_neg2pos = 0;
    m_count_pos2neg = 0;
    
    if (m_latestframe_passagers.size() <= 0)
    {
//         std::cout << "m_latestframe_passagers is zero..." <
        return -1;
    }
    
    if (m_history_passagers.size() <= 0) {
        for (auto passager : m_latestframe_passagers) { 
            m_history_passagers.push_back(passager);
        }
    }else {
        for(std::vector<C_Passager>::iterator h = m_history_passagers.begin(); 
                h != m_history_passagers.end(); ++h) {
            h->existed = false;
            std::vector<C_Passager>::iterator l; 
            for (l = m_latestframe_passagers.begin(); 
                    l!=m_latestframe_passagers.end(); ++l) {
                if (h->identity_code == l->identity_code) {
                    h->existed = true;
                    l->existed = true;
                    if(h->side_flag == -1 && l->side_flag == 1) {
                        m_count_neg2pos++;
                    }else if(h->side_flag == 1 && l->side_flag == -1) {
                        m_count_pos2neg++;
                    }

                    h->c1 = l->c1;
                    h->c2 = l->c2;
                    (*h).side_flag = l->side_flag;
                }
            }
        }
        for(auto h = m_history_passagers.begin(); h != m_history_passagers.end();) {
            if (!h->existed) {
                h->missed_num++;
                if (h->missed_num > 10) {
                    m_history_passagers.erase(h); 
                    continue;
                }
            }
            ++h;
        }
        for(auto l : m_latestframe_passagers) {
            if(!l.existed) {
                m_history_passagers.insert(m_history_passagers.begin(), l);
            }
        }
    }
    return 0;
}


int CrossLineCount::get_count_in_total() {
/*
    if(m_count_pos2neg) {
        m_count_in_total += m_count_pos2neg;
        m_count_pos2neg = 0;
    }
*/
    m_count_in_total = m_count_pos2neg;
    return m_count_in_total;
}

int CrossLineCount::get_count_out_total() {
/*
    if(m_count_neg2pos) {
        m_count_out_total += m_count_neg2pos;
        m_count_neg2pos = 0;
    }
*/
    m_count_out_total = m_count_neg2pos;
    return m_count_out_total;
}
/*
int CrossLineCount::run() {
        CrossLineCount m_cross_line_count;

        byavs::Line cross_line;
        int lines_interval;
        ...
        ...

        m_cross_line_count.set_crossline(lines_interval, cross_line);

        while(true) {
            const byavs::CrossLineObjects obj_list;
            ...
            ...

            m_cross_line_count.set_latestframe_passagers(obj_list);
            m_cross_line_count.check_passager_crossline();
            output_ret.come_num = m_cross_line_count.get_count_in_total();
            output_ret.go_num = m_cross_line_count.get_count_out_total();
        }
}
*/

你可能感兴趣的:(算法)