#include "MSRegionSurveilanceBase.h" IRegionSurveillanceBase::IRegionSurveillanceBase() { pRegion = nullptr; pAlarmInfo = nullptr; } int IRegionSurveillanceBase::rs_init(const rs_param & param) { GlobelWidth = param.image.w_; GlobelHeight = param.image.h_; return init(param); } int IRegionSurveillanceBase::rs_init_region(int numROI, region_info* region_infos, bool iflog) { fstream file;//用于输出日志 if (numROI > MAXROINUM) { return 0; } for (int i = 0; i < numROI; i++) { if (iflog) { file.open("log.txt", ios::app); file << i << ": "; printAlarmType(&file, region_infos[i].alarm_human); file << "P1(" << region_infos[i].p_roi[0].x_ << "," << region_infos[i].p_roi[0].y_ << "), P2(" << region_infos[i].p_roi[1].x_ << "," << region_infos[i].p_roi[1].y_ << ")"; } if (region_infos[i].alarm_human) { region_infos[i].finaldir = rs_get_arrowdir(region_infos[i].p_roi[0], region_infos[i].p_roi[1], region_infos[i].dir_point);//确定方向计算,箭头端点坐标 if (iflog) file << ", DirPoint(" << region_infos[i].dir_point.x_ << "," << region_infos[i].dir_point.y_ << ")"; region_infos[i].arrow_start_point = pStart; //箭头的起始端点 箭头指向正方形 region_infos[i].arrow_end_point = pEnd; //箭头的终止端点 箭头指向正方形 } if (iflog) { file << endl; file.close(); } } m_numROI = numROI; if (pRegion == NULL) { pRegion = new bool*[MAXROINUM]; memset(pRegion, 0, sizeof(bool*) * MAXROINUM); } if (pAlarmInfo == NULL) { pAlarmInfo = new int[MAXROINUM]; memset(pAlarmInfo, 0, sizeof(int) * MAXROINUM); } for (int i = 0; i < MAXROINUM; i++) { if (pRegion[i] == NULL) { pRegion[i] = new bool[(GlobelHeight+10) * (GlobelWidth+10)]; } memset(pRegion[i], 0, sizeof(bool) * (GlobelWidth+10) * (GlobelHeight+10)); if (i <= m_numROI) { pAlarmInfo[i] = region_infos[i].alarm_human; } else { pAlarmInfo[i] = 0; } } // 对每一个待观察的ROI进行监测 for (int i = 0; i < numROI; i++) { // 对每一个感兴趣区域进行标志 感兴趣区域pRegion值为1 其余为0 vibeMask(region_infos[i].point_num, region_infos[i].p_roi, pRegion[i]); } return 1; } void IRegionSurveillanceBase::RSrelease() { for (int i = 0; i < MAXROINUM; i++) { if (pRegion[i] != NULL) { delete[] pRegion[i]; } } if (pRegion != NULL) { delete[] pRegion; pRegion = NULL; } if (pAlarmInfo != NULL) { delete[] pAlarmInfo; pAlarmInfo = NULL; } release(); vec_traceinfo.clear(); } int IRegionSurveillanceBase::rs_get_arrowdir(const sy_point &p_roi0, const sy_point &p_roi1, const sy_point &dir) { float distance = (float)abs(p_roi0.y_ - p_roi1.y_); //获取方向 float k1, k2; //k1为原线段的斜率 if (p_roi0.y_ > p_roi1.y_) //在拌线靠近图像下方的端点处画箭头 { pStart.x_ = p_roi0.x_; pStart.y_ = p_roi0.y_; } else { pStart.x_ = p_roi1.x_; pStart.y_ = p_roi1.y_; } if (p_roi0.x_ != p_roi1.x_) //若不为一根垂直线 { k1 = (float)(p_roi0.y_ - p_roi1.y_) / (float)(p_roi0.x_ - p_roi1.x_); if (k1 != 0) //若不为一根平行线 { k2 = -1 / k1; float b = p_roi1.y_ - k1 * p_roi1.x_;//y = kx + b 坐标系一图像左上顶点为原点,向右为x正方形 向下为y正方向 if ((k1 < 0 && (float)((float)dir.y_ - k1 * (float)dir.x_ - b) < 0) || (k1 > 0 && (float)((float)dir.y_ - k1 * (float)dir.x_ - b) > 0)) { if (distance < 30) //当两点y值差异较小时,垂线比较陡 若减去20 可能导致箭头太长 { pEnd.x_ = pStart.x_ - 2; } else pEnd.x_ = pStart.x_ - 20; } else { if (distance < 30) { pEnd.x_ = pStart.x_ + 2; } else pEnd.x_ = pStart.x_ + 20; } pEnd.y_ = (int)((pEnd.x_ - pStart.x_) * k2 + pStart.y_); } else //若为水平线 { pEnd.x_ = pStart.x_; if (dir.y_ > pStart.y_) pEnd.y_ = pStart.y_ + 20; else pEnd.y_ = pStart.y_ - 20; } } else //若为垂直线 { pEnd.y_ = pStart.y_; if (dir.x_ > pStart.x_) pEnd.x_ = pStart.x_ + 20; else pEnd.x_ = pStart.x_ - 20; } //防止越界 pEnd.x_ = pEnd.x_ >= 0 ? pEnd.x_ : 0; pEnd.x_ = pEnd.x_ <= GlobelWidth ? pEnd.x_ : GlobelWidth; pEnd.y_ = pEnd.y_ >= 0 ? pEnd.y_ : 0; pEnd.y_ = pEnd.y_ <= GlobelHeight ? pEnd.y_ : GlobelHeight; if (p_roi0.x_ == p_roi1.x_) //若为垂直线 { if (pEnd.x_ > pStart.x_) return 1; else return 0; } else if (k1 <= 0) //若不为垂直线且斜率小于等于0(含水平线情况) { if ((pStart.x_ != pEnd.x_ && pEnd.x_ > pStart.x_) || (pStart.x_ == pEnd.x_ && pEnd.y_ > pStart.y_)) return 0; else return 1; } else { if ((pStart.x_ != pEnd.x_ && pEnd.x_ > pStart.x_) || (pStart.x_ == pEnd.x_ && pEnd.y_ > pStart.y_)) return 1; else return 0; } } void IRegionSurveillanceBase::vibeMask(int num, sy_point *pPointList, bool *pRegion) { if (num == 2) { double s; int i, x, y; int xs, ys; int dx, dy; dx = pPointList[1].x_ - pPointList[0].x_; if (dx < 0) { dx = -dx; } dy = pPointList[1].y_ - pPointList[0].y_; if (dy < 0) { dy = -dy; } if (dy < dx) { //draw according to x-y s = (double)(pPointList[1].y_ - pPointList[0].y_) / (pPointList[1].x_ - pPointList[0].x_); if (pPointList[0].x_ < pPointList[1].x_) { xs = pPointList[0].x_; ys = pPointList[0].y_; } else { xs = pPointList[1].x_; ys = pPointList[1].y_; } for (i = 0; i <= dx; i++) { x = i + xs; y = (int)((double)i * s) + ys; if (x > -1 && x < GlobelWidth && y > -1 && y < GlobelHeight) { pRegion[GlobelWidth * y + x] = 1; } } } else { //draw according to y-x s = (double)(pPointList[1].x_ - pPointList[0].x_) / (pPointList[1].y_ - pPointList[0].y_); if (pPointList[0].y_ < pPointList[1].y_) { xs = pPointList[0].x_; ys = pPointList[0].y_; } else { xs = pPointList[1].x_; ys = pPointList[1].y_; } for (i = 0; i <= dy; i++) { y = i + ys; x = (int)((double)i * s) + xs; if (y > -1 && y < GlobelHeight && x > -1 && x < GlobelWidth) { pRegion[GlobelWidth * y + x] = 1; } } } } else if (num >= 3) { sy_point LineMin; sy_point LineMax; for (int k = 0; k < num; k++) { int startp = k; int endp = k + 1; if (startp == num - 1) { endp = 0; } if (abs(pPointList[startp].x_ - pPointList[endp].x_) >= abs(pPointList[startp].y_ - pPointList[endp].y_)) { if (pPointList[startp].x_ < pPointList[endp].x_) { LineMin = pPointList[startp]; LineMax = pPointList[endp]; for (int x = LineMin.x_; x <= LineMax.x_; x++) { int y = (int)(((LineMin.y_ - LineMax.y_) / (double)(LineMin.x_ - LineMax.x_)) * (double)(x - LineMin.x_) + 0.5 + (double)LineMin.y_); //pRegion[GlobelWidth * y + x] = 1; //原程序存在越界 苏晓芸修改如下 if (y > -1 && y < GlobelHeight && x > -1 && x < GlobelWidth) { pRegion[GlobelWidth * y + x] = 1; } } } else if (pPointList[startp].x_ > pPointList[endp].x_) { LineMin = pPointList[endp]; LineMax = pPointList[startp]; for (int x = LineMin.x_; x <= LineMax.x_; x++) { int y = (int)(((LineMin.y_ - LineMax.y_) / (double)(LineMin.x_ - LineMax.x_)) * (double)(x - LineMin.x_) + 0.5 + (double)LineMin.y_); //pRegion[GlobelWidth * y + x] = 1; //原程序存在越界 苏晓芸修改如下 if (y > -1 && y < GlobelHeight && x > -1 && x < GlobelWidth) { pRegion[GlobelWidth * y + x] = 1; } } } else { int YMin = (pPointList[startp].y_ < pPointList[endp].y_) ? pPointList[startp].y_ : pPointList[endp].y_; int YMax = (pPointList[startp].y_ < pPointList[endp].y_) ? pPointList[endp].y_ : pPointList[startp].y_; for (int i = YMin; i <= YMax; i++) { //pRegion[GlobelWidth * i + pPointList[startp].x_] = 1; //原程序存在越界 苏晓芸修改如下 if (i > -1 && i < GlobelHeight && pPointList[startp].x_ > -1 && pPointList[startp].x_ < GlobelWidth) { pRegion[GlobelWidth * i + pPointList[startp].x_] = 1; } } } } else { if (pPointList[startp].y_ < pPointList[endp].y_) { LineMin = pPointList[startp]; LineMax = pPointList[endp]; for (int y = LineMin.y_; y <= LineMax.y_; y++) { int x = (int)(((LineMin.x_ - LineMax.x_) / (double)(LineMin.y_ - LineMax.y_)) * (double)(y - LineMin.y_) + 0.5 + (double)LineMin.x_); //pRegion[GlobelWidth * y + x] = 1; //原程序存在越界 苏晓芸修改如下 if (y > -1 && y < GlobelHeight && x > -1 && x < GlobelWidth) { pRegion[GlobelWidth * y + x] = 1; } } } else if (pPointList[startp].y_ > pPointList[endp].y_) { LineMin = pPointList[endp]; LineMax = pPointList[startp]; for (int y = LineMin.y_; y <= LineMax.y_; y++) { int x = (int)(((LineMin.x_ - LineMax.x_) / (double)(LineMin.y_ - LineMax.y_)) * (double)(y - LineMin.y_) + 0.5 + (double)LineMin.x_); //pRegion[GlobelWidth * y + x] = 1; //原程序存在越界 苏晓芸修改如下 if (y > -1 && y < GlobelHeight && x > -1 && x < GlobelWidth) { pRegion[GlobelWidth * y + x] = 1; } } } else { int XMin = (pPointList[startp].x_ < pPointList[endp].x_) ? pPointList[startp].x_ : pPointList[endp].x_; int XMax = (pPointList[startp].x_ < pPointList[endp].x_) ? pPointList[endp].x_ : pPointList[startp].x_; for (int i = XMin; i <= XMax; i++) { //pRegion[GlobelWidth * pPointList[startp].y_ + i] = 1; //原程序存在越界 苏晓芸修改如下 if (pPointList[startp].y_ > -1 && pPointList[startp].y_ < GlobelHeight && i > -1 && i < GlobelWidth) { pRegion[GlobelWidth * pPointList[startp].y_ + i] = 1; } } } } } // 修改标记方式 将区域边缘标志置为0 for (int i = 0; i < GlobelHeight; i++) { for (int j = 0; j < GlobelWidth; j++) { if (pRegion[GlobelWidth * i + j] == 0) { pRegion[GlobelWidth * i + j] = 1; } else { pRegion[GlobelWidth * i + j] = 0; } } } sy_point StartPoint; int SumX = 0; int SumY = 0; for (int k = 0; k < num; k++) { SumX = SumX + pPointList[k].x_; SumY = SumY + pPointList[k].y_; } StartPoint.x_ = SumX / num; StartPoint.y_ = SumY / num; bool *pMaskMap = new bool[GlobelWidth * GlobelHeight]; bool *pMaskMapS = new bool[GlobelWidth * GlobelHeight]; memset(pMaskMap, 0, sizeof(bool) * GlobelWidth * GlobelHeight); memset(pMaskMapS, 0, sizeof(bool) * GlobelWidth * GlobelHeight); pMaskMap[GlobelWidth * StartPoint.y_ + StartPoint.x_] = 1; int msum = 1; while (msum != 0) { msum = 0; for (int i = 0; i < GlobelHeight; i++) { for (int j = 0; j < GlobelWidth; j++) { msum = msum + pMaskMap[GlobelWidth * i + j] - pMaskMapS[GlobelWidth * i + j]; pMaskMapS[GlobelWidth * i + j] = pMaskMap[GlobelWidth * i + j]; } } for (int i = 0; i < GlobelHeight; i++) { for (int j = 0; j < GlobelWidth; j++) { if ((i <= 0) || (i >= GlobelHeight - 1) || (j <= 0) || (j >= GlobelWidth - 1)) { continue; } if (pMaskMapS[GlobelWidth * i + j] == 1) { pMaskMap[GlobelWidth * i + j + 1] = 1; pMaskMap[GlobelWidth * i + j - 1] = 1; pMaskMap[GlobelWidth * (i + 1) + j] = 1; pMaskMap[GlobelWidth * (i - 1) + j] = 1; } } } for (int i = 0; i < GlobelHeight; i++) { for (int j = 0; j < GlobelWidth; j++) { pMaskMap[GlobelWidth * i + j] = pMaskMap[GlobelWidth * i + j] && pRegion[GlobelWidth * i + j]; } } } memcpy(pRegion, pMaskMap, sizeof(bool) * GlobelWidth * GlobelHeight); delete[] pMaskMap; delete[] pMaskMapS; } } /****************************************************************************** * Function: RSRegion * Description: 感兴趣区域设置 * Calls: vibeMask * Called By: main * Input: numROI ROI个数 pRegionInfo ROI区域 iflog true:输出日志 false:不输出日志 * Output: pRegion 10个ROI指针(bool)每个大小为(图像宽*图像高)感兴趣区域值为1 其余为0 //regionAlarm 10个ROI 报警标志(bool) pAlarmInfo 10个ROI 报警标志(int) * Return: 3 1 *******************************************************************************/ void IRegionSurveillanceBase::printAlarmType(std::fstream *file, int style_human) { switch (style_human) { case 1: *file << "进入禁区, "; // break; //case 2: *file << "离开禁区, "; /* break; case 3:*/ *file << "单向越界, "; /* break; case 4:*/ *file << "双向越界, "; /* break; case 5:*/ *file << "徘徊, "; // break; //case 6: //*file << "丢包, "; break; default: break; } } void IRegionSurveillanceBase::AddTaskTracker(const int taskID, const double rWidth, const double rHeight) { taskTrackers.TaskID = taskID; taskTrackers.ratioWidth = rWidth; taskTrackers.ratioHeight = rHeight; } void IRegionSurveillanceBase::AccessToRestrictedAreas(const VPT_Result & vptResult, const region_info* region_infos, rs_result *result) //进入禁区 { // 只要目标外接矩形有一个点进入区域则报警 for (int ii = 0; ii < m_numROI; ii++) //区域 { for (int i = 0; i < vptResult.objCount; ++i) //目标 { if (pRegion[ii][GlobelWidth * vptResult.obj[i].center_y + vptResult.obj[i].center_x] && \ pRegion[ii][GlobelWidth * vptResult.obj[i].center_y + vptResult.obj[i].center_x + 1] && \ pRegion[ii][GlobelWidth * vptResult.obj[i].center_y + vptResult.obj[i].center_x - 1] && \ pRegion[ii][GlobelWidth * (vptResult.obj[i].center_y + 1) + vptResult.obj[i].center_x] && \ pRegion[ii][GlobelWidth * (vptResult.obj[i].center_y - 1) + vptResult.obj[i].center_x]) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][0] = 1; } } } return; } void IRegionSurveillanceBase::LeaveTheRestrictedAreas(const VPT_Result & vptResult, const region_info* region_infos, rs_result *result) //离开禁区 { for (int ii = 0; ii < m_numROI; ii++) //区域 { for (int i = 0; i < vptResult.objCount; ++i) //目标 { int tar_size = result->obj_infos[i].trace.trace_num; if (tar_size > 4) { sy_point PredictionPoint; PredictionPoint.x_ = vptResult.obj[i].center_x - result->obj_infos[i].trace.obj_trace[tar_size - 4].x_ + vptResult.obj[i].center_x; PredictionPoint.y_ = vptResult.obj[i].center_y - result->obj_infos[i].trace.obj_trace[tar_size - 4].y_ + vptResult.obj[i].center_y; if (pRegion[ii][GlobelWidth * vptResult.obj[i].bottom + vptResult.obj[i].left] || \ pRegion[ii][GlobelWidth * vptResult.obj[i].top + vptResult.obj[i].left] || \ pRegion[ii][GlobelWidth * vptResult.obj[i].top + vptResult.obj[i].right] || \ pRegion[ii][GlobelWidth * vptResult.obj[i].bottom + vptResult.obj[i].right]) { if (pRegion[ii][GlobelWidth * vptResult.obj[i].center_y + vptResult.obj[i].center_x] == false && pRegion[ii][GlobelWidth * PredictionPoint.y_ + PredictionPoint.x_] == false) { bool flag = 0; int j; j = tar_size - 1; while (j >= 0 && j >= tar_size - (vptResult.obj[i].right - vptResult.obj[i].left) / 2) { if (pRegion[ii][GlobelWidth * (int)(result->obj_infos[i].trace.obj_trace[j].y_) + (result->obj_infos[i].trace.obj_trace[j].x_)]) { flag = 1; break; } j--; } if (flag == 1) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][1] = 2; return; } } } } } } return; } void IRegionSurveillanceBase::OneWayCrossBorder(const VPT_Result & vptResult, const region_info* region_infos, rs_result *result) //单向越界 { for (int ii = 0; ii < m_numROI; ii++) //区域 { for (int i = 0; i < vptResult.objCount; ++i) //目标 { int tar_size = result->obj_infos[i].trace.trace_num; for (int iy = vptResult.obj[i].top; iy <= vptResult.obj[i].bottom; iy++) { for (int ix = vptResult.obj[i].left; ix <= vptResult.obj[i].right; ix++) { if (pRegion[ii][GlobelWidth * iy + ix] && tar_size >= 4) { int point_x, point_y; point_x = result->obj_infos[i].trace.obj_trace[tar_size - 4].x_; point_y = result->obj_infos[i].trace.obj_trace[tar_size - 4].y_; if (ii >= 0 && ii < m_numROI && region_infos[ii].point_num >= 2) { if (abs(region_infos[ii].p_roi[0].x_ - region_infos[ii].p_roi[1].x_) >= 1) { double k, b; k = (double)(region_infos[ii].p_roi[0].y_ - region_infos[ii].p_roi[1].y_) / (region_infos[ii].p_roi[0].x_ - region_infos[ii].p_roi[1].x_); b = (double)(region_infos[ii].p_roi[0].x_ * region_infos[ii].p_roi[1].y_ - region_infos[ii].p_roi[1].x_ * region_infos[ii].p_roi[0].y_) / (region_infos[ii].p_roi[0].x_ - region_infos[ii].p_roi[1].x_); double dist_c, dist_p; dist_c = fabs(k * result->obj_infos[i].trace.obj_trace[tar_size - 1].x_ - result->obj_infos[i].trace.obj_trace[tar_size - 1].y_ + b) / sqrt(k * k + 1.0); dist_p = fabs(k * point_x - point_y + b) / sqrt(k * k + 1.0); if (abs(dist_c - dist_p) < 10) { int pre_index = tar_size - 5; while (pre_index >= 0) { point_x = result->obj_infos[i].trace.obj_trace[pre_index].x_; point_y = result->obj_infos[i].trace.obj_trace[pre_index].y_; dist_p = fabs(k * point_x - point_y + b) / sqrt(k * k + 1.0); pre_index = pre_index - 1; if (abs(dist_c - dist_p) >= 10) { break; } } } if (abs(dist_c - dist_p) < 10) { result->obj_infos[i].pb_alarm_state[ii] = false; result->obj_infos[i].pb_alarm_type[ii][2] = 0; return; } bool flag_c, flag_p; if (k * result->obj_infos[i].trace.obj_trace[tar_size - 1].x_ + b >= result->obj_infos[i].trace.obj_trace[tar_size - 1].y_) { flag_c = 1; } else { flag_c = 0; } if (k *point_x + b >= point_y) { flag_p = 1; } else { flag_p = 0; } //if (region_infos[ii].dir == 1) if (region_infos[ii].finaldir == 1) //by zl 20150914 { if (flag_c * flag_p == 1) { if (dist_c <= dist_p) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } } else if (flag_c == 0 && flag_p == 1) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } else if (flag_c == 0 && flag_p == 0) { if (dist_p <= dist_c) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } } } else { if (flag_c == 0 && flag_p == 0) { if (dist_c <= dist_p) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } } else if (flag_c == 1 && flag_p == 0) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } else if (flag_c == 1 && flag_p == 1) { if (dist_p <= dist_c) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } } } } else { double k, b; k = 0; b = (double)(region_infos[ii].p_roi[0].x_); double dist_c, dist_p; dist_c = fabs(result->obj_infos[i].trace.obj_trace[tar_size - 1].x_ - b); dist_p = fabs(point_x - b); if (abs(dist_c - dist_p) < 10) { int pre_index = tar_size - 5; while (pre_index >= 0) { point_x = result->obj_infos[i].trace.obj_trace[pre_index].x_; dist_p = fabs(point_x - b); pre_index = pre_index - 1; if (abs(dist_c - dist_p) >= 10) { break; } } } bool flag_c, flag_p; if (result->obj_infos[i].trace.obj_trace[tar_size - 1].x_ >= b) { flag_c = 1; } else { flag_c = 0; } if (point_x >= b) { flag_p = 1; } else { flag_p = 0; } if (abs(dist_c - dist_p) < 10) { result->obj_infos[i].pb_alarm_state[ii] = false; result->obj_infos[i].pb_alarm_type[ii][2] = 0; return; } //if (region_infos[ii].dir == 1) if (region_infos[ii].finaldir == 1) //by zl 20150914 { if (flag_c * flag_p == 1) { if (dist_c <= dist_p) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } } else if (flag_c == 0 && flag_p == 1) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } else if (flag_c == 0 && flag_p == 0) { if (dist_p <= dist_c) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } } } else { if (flag_c == 0 && flag_p == 0) { if (dist_c <= dist_p) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } } else if (flag_c == 1 && flag_p == 0) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } else if (flag_c == 1 && flag_p == 1) { if (dist_p <= dist_c) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][2] = 3; return; } } } } } } } } } } return; } void IRegionSurveillanceBase::TwoWayCrossBorder(const VPT_Result & vptResult, const region_info* region_infos, rs_result *result) //双向越界 { // 只要目标外接矩形有一个点进入区域则报警 for (int ii = 0; ii < m_numROI; ii++) //区域 { for (int i = 0; i < vptResult.objCount; ++i) //目标 { for (int iy = vptResult.obj[i].top; iy <= vptResult.obj[i].bottom; iy++) { for (int ix = vptResult.obj[i].left; ix <= vptResult.obj[i].right; ix++) { if (pRegion[ii][GlobelWidth * iy + ix]) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][3] = 4; } } } } } return; } void IRegionSurveillanceBase::WanderMonitoring(const VPT_Result & vptResult, const region_info* region_infos, rs_result *result) //徘徊 { for (int ii = 0; ii < m_numROI; ii++) //区域 { for (int i = 0; i < vptResult.objCount; ++i) //目标 { bool flag = 0; if ((pRegion[ii][GlobelWidth * vptResult.obj[i].bottom + vptResult.obj[i].left] || \ pRegion[ii][GlobelWidth * vptResult.obj[i].top + vptResult.obj[i].left] || \ pRegion[ii][GlobelWidth * vptResult.obj[i].top + vptResult.obj[i].right] || \ pRegion[ii][GlobelWidth * vptResult.obj[i].bottom + vptResult.obj[i].right]) && (pRegion[ii][GlobelWidth * vptResult.obj[i].center_y + vptResult.obj[i].center_x])) { if (mp_stayinfo[ii][vptResult.obj[i].id].nFrameCurr == 0) { mp_stayinfo[ii][vptResult.obj[i].id].nFrameCurr = 1; mp_stayinfo[ii][vptResult.obj[i].id].lastFrame = 0; } else { if (mp_stayinfo[ii][vptResult.obj[i].id].lastFrame <= 5) { mp_stayinfo[ii][vptResult.obj[i].id].nFrameCurr++; mp_stayinfo[ii][vptResult.obj[i].id].lastFrame = 0; } else { mp_stayinfo[ii][vptResult.obj[i].id].nFrameCurr = 0; mp_stayinfo[ii][vptResult.obj[i].id].lastFrame = 0; } } if (mp_stayinfo[ii][vptResult.obj[i].id].nFrameCurr >= region_infos[ii].frame_num) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][4] = 5; flag = 1; } } if (flag == 0) { result->obj_infos[i].pb_alarm_state[ii] = false; result->obj_infos[i].pb_alarm_type[ii][4] = 0; } mp_stayinfo[ii][vptResult.obj[i].id].lastFrame++; } } return; } void IRegionSurveillanceBase::StayMonitoring(const VPT_Result & vptResult, const region_info* region_infos, rs_result *result) //丢包 { for (int ii = 0; ii < m_numROI; ii++) //区域 { for (int i = 0; i < vptResult.objCount; ++i) //目标 { int tar_size = result->obj_infos[i].trace.trace_num; int cur_dis; bool flag = 0; if (pRegion[ii][GlobelWidth * vptResult.obj[i].bottom + vptResult.obj[i].left] || \ pRegion[ii][GlobelWidth * vptResult.obj[i].top + vptResult.obj[i].left] || \ pRegion[ii][GlobelWidth * vptResult.obj[i].top + vptResult.obj[i].right] || \ pRegion[ii][GlobelWidth * vptResult.obj[i].bottom + vptResult.obj[i].right]) { if (pRegion[ii][GlobelWidth * vptResult.obj[i].center_y + vptResult.obj[i].center_x]) { if (mp_stayinfo[ii][vptResult.obj[i].id].nFrameCurr == 0) { mp_stayinfo[ii][vptResult.obj[i].id].nFrameCurr = 1; mp_stayinfo[ii][vptResult.obj[i].id].lastFrame = 0; } else { if (tar_size >= 2) { cur_dis = (result->obj_infos[i].trace.obj_trace[tar_size - 1].x_ - result->obj_infos[i].trace.obj_trace[tar_size - 2].x_)*(result->obj_infos[i].trace.obj_trace[tar_size - 1].x_ - result->obj_infos[i].trace.obj_trace[tar_size - 2].x_) + (result->obj_infos[i].trace.obj_trace[tar_size - 1].y_ - result->obj_infos[i].trace.obj_trace[tar_size - 2].y_)*(result->obj_infos[i].trace.obj_trace[tar_size - 1].y_ - result->obj_infos[i].trace.obj_trace[tar_size - 2].y_); } else { cur_dis = 0; } if (mp_stayinfo[ii][vptResult.obj[i].id].lastFrame <= 5 && cur_dis <= tar_size * tar_size) { mp_stayinfo[ii][vptResult.obj[i].id].nFrameCurr++; mp_stayinfo[ii][vptResult.obj[i].id].lastFrame = 0; } else { mp_stayinfo[ii][vptResult.obj[i].id].nFrameCurr = 0; mp_stayinfo[ii][vptResult.obj[i].id].lastFrame = 0; } } if (mp_stayinfo[ii][vptResult.obj[i].id].nFrameCurr >= region_infos[ii].frame_num) { result->obj_infos[i].pb_alarm_state[ii] = true; result->obj_infos[i].pb_alarm_type[ii][5] = 6; } } } if (flag == 0) { result->obj_infos[i].pb_alarm_state[ii] = false; result->obj_infos[i].pb_alarm_type[ii][5] = 0; } mp_stayinfo[ii][vptResult.obj[i].id].lastFrame++; } } return; } int IRegionSurveillanceBase::rs_detect(const sy_img &img_data, region_info* region_infos, int region_count, rs_result *result) { VPT_Result vptResult; detect(img_data, vptResult); for (int i = 0; i < vptResult.objCount; i++) //更新轨迹 { bool matching = false; for (auto &item : vec_traceinfo) { if (item.id == vptResult.obj[i].id) { if (item.num < MAXTRACENUM) { ++item.num; sy_point point; point.x_ = vptResult.obj[i].center_x; point.y_ = vptResult.obj[i].center_y; item.trace_obj.push_back(point); } else { sy_point point; point.x_ = vptResult.obj[i].center_x; point.y_ = vptResult.obj[i].center_y; item.trace_obj.push_back(point); item.trace_obj.pop_front(); } matching = true; } } if (matching == false) { TraceInfo traceinf; traceinf.id = vptResult.obj[i].id; traceinf.num = 1; sy_point point; point.x_ = vptResult.obj[i].center_x; point.y_ = vptResult.obj[i].center_y; traceinf.trace_obj.push_back(point); vec_traceinfo.push_back(traceinf); } } result->obj_count = vptResult.objCount; for (int i = 0; i < result->obj_count; i++) { memset(result->obj_infos[i].pb_alarm_state, 0, MAXROINUM * sizeof(bool)); memset(result->obj_infos[i].pb_alarm_type, 0, MAXROINUM * sizeof(int)); result->obj_infos[i].tar_box.left_ = vptResult.obj[i].left; result->obj_infos[i].tar_box.top_ = vptResult.obj[i].top; result->obj_infos[i].tar_box.width_ = vptResult.obj[i].right - vptResult.obj[i].left; result->obj_infos[i].tar_box.height_ = vptResult.obj[i].bottom - vptResult.obj[i].top; result->obj_infos[i].curPos.x_ = vptResult.obj[i].center_x; result->obj_infos[i].curPos.y_ = vptResult.obj[i].center_y; result->obj_infos[i].unique_id = vptResult.obj[i].id; for (auto &item : vec_traceinfo) { if (item.id == vptResult.obj[i].id) { result->obj_infos[i].trace.trace_num = item.num; for (int j = 0; j < item.num; ++j) { result->obj_infos[i].trace.obj_trace[j] = item.trace_obj[j]; } } } } for (int i = 0; i < m_numROI; i++) { // 1进入禁区 2离开禁区 3单向越界 4双向越界 5徘徊 6丢包 switch (pAlarmInfo[i]) { case 1: AccessToRestrictedAreas(vptResult, region_infos, result); //进入禁区 /* break; case 2:*/ LeaveTheRestrictedAreas(vptResult, region_infos, result); //离开禁区 /* break; case 3:*/ OneWayCrossBorder(vptResult, region_infos, result); //单向越界 /* break; case 4:*/ TwoWayCrossBorder(vptResult, region_infos, result); //双向越界 /* break; case 5:*/ WanderMonitoring(vptResult, region_infos, result); //徘徊 /* break; case 6:*/ //StayMonitoring(vptResult, region_infos, result); //丢包 break; default: break; } } return 1; }