//#include "stdafx.h" #include "RegionAssist.h" //#include "MSRegionSurveilance.h" #include "ms_region_surveilance.h" #include "cv.h" #include "highgui.h" //using namespace cv; #define LINE_PIXEL 2 using namespace std; /************************************************************************/ /* 函数: DrawArrow() */ /* 作用: 绘制箭头 */ /* 参数: src:图像;pStart&pEnd:箭头两个端点;len:箭头两翼的长短; */ /* alpha为箭头两翼展开的幅度 */ /* 返回: 无 */ /************************************************************************/ void DrawArrow(IplImage * src, cv::Point pStart, cv::Point pEnd, int len, int alpha) { const double PI = 3.1415926; cv::Point arrow; //计算 θ 角(最简单的一种情况在下面图示中已经展示,关键在于 atan2 函数,详情见下面) double angle = atan2((double)(pStart.y - pEnd.y), (double)(pStart.x - pEnd.x)); cvLine(src, pStart, pEnd, cvScalar(0, 127, 0), 2); //黄色线 //计算箭角边的另一端的端点位置(上面的还是下面的要看箭头的指向,也就是pStart和pEnd的位置) arrow.x = pEnd.x + len * cos(angle + PI * alpha / 180); arrow.y = pEnd.y + len * sin(angle + PI * alpha / 180); cvLine(src, pEnd, arrow, cvScalar(0, 127, 0), 2); arrow.x = pEnd.x + len * cos(angle - PI * alpha / 180); arrow.y = pEnd.y + len * sin(angle - PI * alpha / 180); cvLine(src, pEnd, arrow, cvScalar(0, 127, 0), 2); } //画线 void DrawLine(unsigned char* pRGBIn, int widthStep, const sy_point & p_roi, const sy_point & dir_point) { int disX = abs(dir_point.x_ - p_roi.x_); int disY = abs(dir_point.y_ - p_roi.y_); if (disX >= disY) { if (p_roi.x_ != dir_point.x_) { sy_point p_roi_src = p_roi.x_ < dir_point.x_ ? p_roi : dir_point; sy_point p_roi_des = p_roi.x_ >= dir_point.x_ ? p_roi : dir_point; double tan = (double)(p_roi_des.y_ - p_roi_src.y_) / (double)(p_roi_des.x_ - p_roi_src.x_); for (unsigned int i = p_roi_src.x_; i <= p_roi_des.x_; ++i) { for (int j = 0; j < LINE_PIXEL; ++j) { pRGBIn[(p_roi_src.y_ + (int)(tan * (i - p_roi_src.x_)) + j)* widthStep + i * 3] = 255; pRGBIn[(p_roi_src.y_ + (int)(tan * (i - p_roi_src.x_)) + j)* widthStep + i * 3 + 1] = 0; pRGBIn[(p_roi_src.y_ + (int)(tan * (i - p_roi_src.x_)) + j)* widthStep + i * 3 + 2] = 0; } } } else { for (int j = 0; j < LINE_PIXEL; ++j) { pRGBIn[p_roi.x_* widthStep + (p_roi.y_+j) * 3] = 255; pRGBIn[p_roi.x_* widthStep + (p_roi.y_+j) * 3 + 1] = 0; pRGBIn[p_roi.x_* widthStep + (p_roi.y_+j) * 3 + 2] = 0; } } } else { if (p_roi.x_ != dir_point.x_) { sy_point p_roi_src = p_roi.y_ < dir_point.y_ ? p_roi : dir_point; sy_point p_roi_des = p_roi.y_ >= dir_point.y_ ? p_roi : dir_point; double cot = (double)(p_roi_des.x_ - p_roi_src.x_) / (double)(p_roi_des.y_ - p_roi_src.y_); for (unsigned int i = p_roi_src.y_; i <= p_roi_des.y_; ++i) { for (int j = 0; j < LINE_PIXEL; ++j) { pRGBIn[(i)* widthStep + (int)(p_roi_src.x_ + cot *(i - p_roi_src.y_)+j) * 3] = 255; pRGBIn[(i)* widthStep + (int)(p_roi_src.x_ + cot *(i - p_roi_src.y_)+j) * 3 + 1] = 0; pRGBIn[(i)* widthStep + (int)(p_roi_src.x_ + cot *(i - p_roi_src.y_)+j) * 3 + 2] = 0; } } } else { sy_point p_roi_src = p_roi.y_ < dir_point.y_ ? p_roi : dir_point; sy_point p_roi_des = p_roi.y_ >= dir_point.y_ ? p_roi : dir_point; for (unsigned int i = p_roi_src.y_; i <= p_roi_des.y_; ++i) { for (int j = 0; j < LINE_PIXEL; ++j) { pRGBIn[(i)* widthStep + (int)(p_roi_src.x_+j) * 3] = 255; pRGBIn[(i)* widthStep + (int)(p_roi_src.x_+j) * 3 + 1] = 0; pRGBIn[(i)* widthStep + (int)(p_roi_src.x_+j) * 3 + 2] = 0; } } } } } //描绘区域 void DrawRegion(unsigned char* pRGBIn, region_info* pRegionInfo, int numROI, int widthStep) { for (int i = 0; i < numROI; ++i) { for (int j = 0; j <= pRegionInfo[i].point_num-1; ++j) { if (j < pRegionInfo[i].point_num - 1) { DrawLine(pRGBIn, widthStep, pRegionInfo[i].p_roi[j], pRegionInfo[i].p_roi[j + 1]); } else if (j = pRegionInfo[i].point_num - 1) { DrawLine(pRGBIn, widthStep, pRegionInfo[i].p_roi[j], pRegionInfo[i].p_roi[0]); } } } } //外接矩形描绘 void ExternalRectangle(unsigned char* pRGBIn, int width, int height ,ms_object_info *ObjInfo, int ObjCount, int widthStep, int numROI) { int dwStep = widthStep; int i; // 前景目标外接矩形描绘 for (i = 0; i < ObjCount; i++) { //根据颜色区分报警情况 int alarm_flag = 0; for (int ii = 0; ii < numROI; ii++) { if (ObjInfo[i].pb_alarm_state[ii] == true) { alarm_flag = 1; //alarm_flag = ObjInfo[i].pb_alarm_type[ii]; break; } } if ((ObjInfo[i].tar_box.height_ + ObjInfo[i].tar_box.top_) > height- LINE_PIXEL) { continue; } if ((ObjInfo[i].tar_box.width_ + ObjInfo[i].tar_box.left_) > width - LINE_PIXEL) { continue; } // 无报警 蓝色 if (alarm_flag == 0) { /*for (int t = ObjInfo[i].tar_box.left_; t <= ObjInfo[i].tar_box.left_ + ObjInfo[i].tar_box.width_; t++) { pRGBIn[ObjInfo[i].tar_box.top_ * dwStep + t * 3] = 255; pRGBIn[ObjInfo[i].tar_box.top_ * dwStep + t * 3 + 1] = 0; pRGBIn[ObjInfo[i].tar_box.top_ * dwStep + t * 3 + 2] = 0; pRGBIn[(ObjInfo[i].tar_box.height_ + ObjInfo[i].tar_box.top_) * dwStep + t * 3] = 255; pRGBIn[(ObjInfo[i].tar_box.height_ + ObjInfo[i].tar_box.top_) * dwStep + t * 3 + 1] = 0; pRGBIn[(ObjInfo[i].tar_box.height_ + ObjInfo[i].tar_box.top_) * dwStep + t * 3 + 2] = 0; } for (int t = ObjInfo[i].tar_box.top_; t < ObjInfo[i].tar_box.height_ + ObjInfo[i].tar_box.top_; t++) { pRGBIn[t * dwStep + ObjInfo[i].tar_box.left_ * 3] = 255; pRGBIn[t * dwStep + ObjInfo[i].tar_box.left_ * 3 + 1] = 0; pRGBIn[t * dwStep + ObjInfo[i].tar_box.left_ * 3 + 2] = 0; pRGBIn[t * dwStep + (ObjInfo[i].tar_box.left_ + ObjInfo[i].tar_box.width_) * 3] = 255; pRGBIn[t * dwStep + (ObjInfo[i].tar_box.left_ + ObjInfo[i].tar_box.width_) * 3 + 1] = 0; pRGBIn[t * dwStep + (ObjInfo[i].tar_box.left_ + ObjInfo[i].tar_box.width_) * 3 + 2] = 0; }*/ } else { for (int t = ObjInfo[i].tar_box.left_; t <= ObjInfo[i].tar_box.left_ + ObjInfo[i].tar_box.width_; t++) { for (int j = 0; j < LINE_PIXEL; ++j) { pRGBIn[(ObjInfo[i].tar_box.top_+j) * dwStep + t * 3] = 0; pRGBIn[(ObjInfo[i].tar_box.top_ + j) * dwStep + t * 3 + 1] = 0; pRGBIn[(ObjInfo[i].tar_box.top_ + j) * dwStep + t * 3 + 2] = 255; pRGBIn[(ObjInfo[i].tar_box.height_ + ObjInfo[i].tar_box.top_ +j) * dwStep + t * 3] = 0; pRGBIn[(ObjInfo[i].tar_box.height_ + ObjInfo[i].tar_box.top_ +j) * dwStep + t * 3 + 1] = 0; pRGBIn[(ObjInfo[i].tar_box.height_ + ObjInfo[i].tar_box.top_ +j) * dwStep + t * 3 + 2] = 255; } } for (int t = ObjInfo[i].tar_box.top_; t < ObjInfo[i].tar_box.height_ + ObjInfo[i].tar_box.top_; t++) { for (int j = 0; j < LINE_PIXEL; ++j) { pRGBIn[(t) * dwStep + (ObjInfo[i].tar_box.left_ + j) * 3] = 0; pRGBIn[(t) * dwStep + (ObjInfo[i].tar_box.left_ + j ) * 3 + 1] = 0; pRGBIn[(t) * dwStep + (ObjInfo[i].tar_box.left_ + j) * 3 + 2] = 255; pRGBIn[(t) * dwStep + (ObjInfo[i].tar_box.left_ + ObjInfo[i].tar_box.width_ + j) * 3] = 0; pRGBIn[(t) * dwStep + (ObjInfo[i].tar_box.left_ + ObjInfo[i].tar_box.width_ + j) * 3 + 1] = 0; pRGBIn[(t) * dwStep + (ObjInfo[i].tar_box.left_ + ObjInfo[i].tar_box.width_ + j) * 3 + 2] = 255; } } } } //printf("==== end ExternalRectangle =====\n"); } // 轨迹描绘 void Trajectory(unsigned char* pRGBIn, ms_object_info *ObjInfo, int ObjCount, int width, int height, int widthStep, int numROI) { // 轨迹描绘 int dwStep = widthStep; int i; for (i = 0; i < ObjCount; i++) { unsigned char bRed = (unsigned char)((ObjInfo[i].unique_id % 3) * 85 + 85); unsigned char bGreen = (unsigned char)((ObjInfo[i].unique_id % 7) * 36 + 36); unsigned char bBlue = (unsigned char)((ObjInfo[i].unique_id % 13) * 20 + 15); int alarm_flag = 0; for (int ii = 0; ii < numROI; ii++) { if (ObjInfo[i].pb_alarm_state[ii] == true) { alarm_flag = 1; //alarm_flag = ObjInfo[i].pb_alarm_type[ii]; break; } } int dwPointNum = ObjInfo[i].trace.trace_num; sy_point ptLast = ObjInfo[i].trace.obj_trace[0]; if (alarm_flag != 0) { // 对目标的每一个匹配项进行遍历 for (int l = 1; l < dwPointNum; l++) { if (ObjInfo[i].trace.obj_trace[l].x_ == ptLast.x_ && ObjInfo[i].trace.obj_trace[l].y_ == ptLast.y_) { // Draw a point //描绘目标中心点 pRGBIn[ObjInfo[i].trace.obj_trace[l].y_ * dwStep + ObjInfo[i].trace.obj_trace[l].x_ * 3] = bBlue; pRGBIn[ObjInfo[i].trace.obj_trace[l].y_ * dwStep + ObjInfo[i].trace.obj_trace[l].x_ * 3 + 1] = bGreen; pRGBIn[ObjInfo[i].trace.obj_trace[l].y_ * dwStep + ObjInfo[i].trace.obj_trace[l].x_ * 3 + 2] = bRed; } else { // Draw line if (abs(ObjInfo[i].trace.obj_trace[l].x_ - ptLast.x_) > abs(ObjInfo[i].trace.obj_trace[l].y_ - ptLast.y_)) { double dk = ((double)ObjInfo[i].trace.obj_trace[l].y_ - ptLast.y_) / (ObjInfo[i].trace.obj_trace[l].x_ - ptLast.x_); double b = ObjInfo[i].trace.obj_trace[l].y_ - ObjInfo[i].trace.obj_trace[l].x_ * dk; int colMin = ObjInfo[i].trace.obj_trace[l].x_; int colMax = ptLast.x_; if (colMin > colMax) { int dwTemp = colMin; colMin = colMax; colMax = dwTemp; } for (int col = colMin; col <= colMax; col++) { int row = (int)(dk * col + b + 0.5); row = row < height ? row : height - 1; row = row >= 0 ? row : 0; pRGBIn[row * dwStep + col * 3] = bBlue; pRGBIn[row * dwStep + col * 3 + 1] = bGreen; pRGBIn[row * dwStep + col * 3 + 2] = bRed; if (++row < height) { pRGBIn[row * dwStep + col * 3] = bBlue; pRGBIn[row * dwStep + col * 3 + 1] = bGreen; pRGBIn[row * dwStep + col * 3 + 2] = bRed; } else if ((row -= 2) >= 0) { pRGBIn[row * dwStep + col * 3] = bBlue; pRGBIn[row * dwStep + col * 3 + 1] = bGreen; pRGBIn[row * dwStep + col * 3 + 2] = bRed; } } } else { double dk = ((double)ObjInfo[i].trace.obj_trace[l].x_ - ptLast.x_) / (ObjInfo[i].trace.obj_trace[l].y_ - ptLast.y_); double b = ObjInfo[i].trace.obj_trace[l].x_ - ObjInfo[i].trace.obj_trace[l].y_ * dk; int rowMin = ObjInfo[i].trace.obj_trace[l].y_; int rowMax = ptLast.y_; if (rowMin > rowMax) { int dwTemp = rowMin; rowMin = rowMax; rowMax = dwTemp; } for (int row = rowMin; row <= rowMax; row++) { int col = (int)(dk * row + b + 0.5); col = col < width ? col : width - 1; col = col >= 0 ? col : 0; pRGBIn[row * dwStep + col * 3] = bBlue; pRGBIn[row * dwStep + col * 3 + 1] = bGreen; pRGBIn[row * dwStep + col * 3 + 2] = bRed; if (++col < width) { pRGBIn[row * dwStep + col * 3] = bBlue; pRGBIn[row * dwStep + col * 3 + 1] = bGreen; pRGBIn[row * dwStep + col * 3 + 2] = bRed; } else if ((col -= 2) >= 0) { pRGBIn[row * dwStep + col * 3] = bBlue; pRGBIn[row * dwStep + col * 3 + 1] = bGreen; pRGBIn[row * dwStep + col * 3 + 2] = bRed; } } } } ptLast = ObjInfo[i].trace.obj_trace[l]; } } } }