RegionAssist.cpp 11.1 KB
//#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];
			}
		}
	
	}
}