算法,越线检测,检测目标是否与线接触,检测目标第一次与线接触

1,touch_line_detect.h

#ifndef __TOUCH_LINE_DETECT_H__ 
#define __TOUCH_LINE_DETECT_H__ 

#include 
#include 

/*
typedef struct {
    double x1;
    double y1;
    double x2;
    double y2;
}Line;

typedef struct {
    cv::Rect region;
    int object_id;
}CrossLineObject;
typedef std::vector CrossLineObjects;

typedef struct {
    int touch_flag;
    int first_touch;
}CrossLineOutputObject;
typedef std::vector CrossLineOutputObjects;

*/

typedef struct {
    std::string identity_code;

    // integerated from IdentityStatus
    bool existed; 
    int missed_num;
    int first_touch;
    int touch_flag;
}T_Passager;

class TouchLineDetect {
    private:
        byavs::Line m_line;
        byavs::CrossLineOutputObjects m_cross_out_list;
        std::vector<T_Passager> m_history_passagers;
        std::vector<T_Passager> m_latestframe_passagers;
    public:
        int set_line(byavs::Line line);
        int set_latestframe_passagers(byavs::CrossLineObjects obj_list);
        int check_passager_touchline();
        bool intersection(const byavs::Line &l1, const byavs::Line &l2);
        int touch_detect(cv::Rect region);
        byavs::CrossLineOutputObjects get_cross_out_list();
};

#endif

2,touch_line_detect.h

#include "touch_line_detect.h"


bool TouchLineDetect::intersection(const byavs::Line &l1, const byavs::Line &l2)
{
    //快速排斥实验
    if ((l1.x1 > l1.x2 ? l1.x1 : l1.x2) < (l2.x1 < l2.x2 ? l2.x1 : l2.x2) ||
        (l1.y1 > l1.y2 ? l1.y1 : l1.y2) < (l2.y1 < l2.y2 ? l2.y1 : l2.y2) ||
        (l2.x1 > l2.x2 ? l2.x1 : l2.x2) < (l1.x1 < l1.x2 ? l1.x1 : l1.x2) ||
        (l2.y1 > l2.y2 ? l2.y1 : l2.y2) < (l1.y1 < l1.y2 ? l1.y1 : l1.y2))
    {
        return false;
    }
    //跨立实验
    if ((((l1.x1 - l2.x1)*(l2.y2 - l2.y1) - (l1.y1 - l2.y1)*(l2.x2 - l2.x1))*
        ((l1.x2 - l2.x1)*(l2.y2 - l2.y1) - (l1.y2 - l2.y1)*(l2.x2 - l2.x1))) > 0 ||
        (((l2.x1 - l1.x1)*(l1.y2 - l1.y1) - (l2.y1 - l1.y1)*(l1.x2 - l1.x1))*
        ((l2.x2 - l1.x1)*(l1.y2 - l1.y1) - (l2.y2 - l1.y1)*(l1.x2 - l1.x1))) > 0)
    {
        return false;
    }
    return true;
}
int TouchLineDetect::touch_detect(cv::Rect region) {
    byavs::Line l1, l2;
    l1.x1 = region.x;
    l1.y1 = region.y;
    l1.x2 = region.x + region.width;
    l1.y2 = region.y + region.height;

    l2.x1 = region.x + region.width;
    l2.y1 = region.y;
    l2.x2 = region.x;
    l2.y2 = region.y + region.height;
    bool back_value = (intersection(l1, m_line) || intersection(l2, m_line));
/*
    std::cout << "1111111111111111111111111111111111111111111111:"
        << " m_line:[("<< m_line.x1<<","<< m_line.y1 << "),("
        <
    return back_value;
}
/*
 * set the crossline
 */
int TouchLineDetect::set_line(byavs::Line line) {
    m_line = line;
    return 0;
}

int TouchLineDetect::set_latestframe_passagers(byavs::CrossLineObjects obj_list) {
    m_latestframe_passagers.clear();

    for(int i=0; i<obj_list.size(); i++) {
        T_Passager passager;
        passager.identity_code = std::to_string(obj_list[i].object_id);
        passager.existed = false;
        passager.missed_num = 0;
        passager.first_touch = 1;
        passager.touch_flag = touch_detect(obj_list[i].region);

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

// check the passages is touching the crossline with history_passager and 
// latestframe_passsagers
int TouchLineDetect::check_passager_touchline() { 
    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<T_Passager>::iterator h = m_history_passagers.begin(); 
                h != m_history_passagers.end(); ++h) {
            h->existed = false;
            std::vector<T_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(l->touch_flag && !h->touch_flag) {
                        l->first_touch = 1;
                    }else{
                        l->first_touch = 0;
                    }
                    h->touch_flag = l->touch_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;
}

byavs::CrossLineOutputObjects TouchLineDetect::get_cross_out_list() {
    m_cross_out_list.clear();
    std::vector<T_Passager>::iterator l;
    for(l=m_latestframe_passagers.begin(); l!=m_latestframe_passagers.end();++l) {
        byavs::CrossLineOutputObject out_obj;
        out_obj.touch_flag = l->touch_flag;
        out_obj.first_touch = l->first_touch;
        m_cross_out_list.push_back(out_obj);
    }
    return m_cross_out_list;
}

/*
int TouchLineDetect::run() {
        TouchLineDetect m_touch_line;

        byavs::Line cross_line;
        ...
        ...

        m_touch_line.set_line(cross_line);

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

            // touch line
            m_touch_line.set_latestframe_passagers(obj_list);
            m_touch_line.check_passager_touchline();
            output_ret.cross_out_list = m_touch_line.get_cross_out_list();
        }
}
*/

你可能感兴趣的:(算法,算法,越线检测,检测目标是否与线接触,检测目标第一次与线接触)