snapshot_reprocessing.cpp 9.61 KB
#include "snapshot_reprocessing.h"

#include "../common/logger.hpp"
#include "../ai_platform/mvpt_process_assist.h"
#include "../decoder/interface/DeviceMemory.hpp"


snapshot_reprocessing::snapshot_reprocessing(int devId)
{
	algor_index_table["human"] = { (int)det_class_label_t::HUMAN };
	algor_index_table["vehicle"] = { (int)det_class_label_t::SMALL_CAR, (int)det_class_label_t::LARGE_CAR, (int)det_class_label_t::TRUCK, (int)det_class_label_t::TRACTOR, (int)det_class_label_t::MEDIUM_BUS };
}

snapshot_reprocessing::~snapshot_reprocessing()
{
}

static void box_expansion(video_object_info& obj_info, float expand_ratio, int frame_width, int frame_height){
	int origin_width = obj_info.right - obj_info.left;
	int origin_height = obj_info.bottom - obj_info.top;

	int expansion_width = origin_width * expand_ratio;
	int expansion_height = origin_height * expand_ratio;

	obj_info.left = max(obj_info.left - expansion_width, 0);
	obj_info.top = max(obj_info.top - expansion_height, 0);
	obj_info.right = min(obj_info.right + expansion_width, frame_width - 1);
	obj_info.bottom = min(obj_info.bottom + expansion_height, frame_height - 1);
}

void snapshot_reprocessing::screen_effective_snapshot(vector<onelevel_det_result> &vec_det_result){

	for (auto det_result : vec_det_result)
	{
		int effective_count = 0;
		int effective_idx = 0;
		string taskid = det_result.task_id;

		det_objinfo *tmp_det_objinfo =det_result.obj;

		for (int c = 0; c < det_result.obj_count; c++)
		{
			if (algor_index_table["human"].find(tmp_det_objinfo[c].index) != algor_index_table["human"].end() ) // modified by zsh 220714
			{
				tmp_det_objinfo[effective_idx++] = tmp_det_objinfo[c];
				effective_count++;
			}

			if (algor_index_table["vehicle"].find(tmp_det_objinfo[c].index) != algor_index_table["vehicle"].end() )
			{
				tmp_det_objinfo[effective_idx++] = tmp_det_objinfo[c];
				effective_count++;
			}
		}

		det_result.obj_count = effective_count;
	}
}

/* 获取人车物目标快照图 */
void snapshot_reprocessing::update_bestsnapshot(vector<DeviceMemory*> vec_devMem, vector<onelevel_det_result> &ol_det_result){

	VPCUtil* pVpcUtil = VPCUtil::getInstance();

	for (size_t i = 0; i < vec_devMem.size(); i++){

		onelevel_det_result det_result = ol_det_result[i];
		if (0 == det_result.obj_count){
			continue;
		}

		DeviceMemory* memPtr = vec_devMem[i];

		string task_id = memPtr->getId();
		int frame_height = memPtr->getHeight();
		int frame_width = memPtr->getWidth();

		vector<video_object_info> vec_obj_info;
		for (int c = 0; c < det_result.obj_count; c++){
		
			det_objinfo obj_info = det_result.obj[c];
			OBJ_KEY new_obj = { task_id, obj_info.id };

			int index = 0;

			/* 投票确定目标index */
			if (total_snapshot_info.find(new_obj) == total_snapshot_info.end()){
				index = obj_info.index;
			} else {
				index = total_snapshot_info[new_obj].index.index;
			}

			int cur_real_width = (obj_info.right - obj_info.left);
			int cur_real_height = (obj_info.bottom - obj_info.top);
			int cur_real_index = obj_info.index;

			int expansion_width = cur_real_width * EXPANSION_PROPORTION;
			int expansion_height = cur_real_height * EXPANSION_PROPORTION;
			// DEBUG-----------------------------------------------------------------
			// 0-行人 1-自行车 2-摩托车 3-三轮车 4-小型车 5-大车 6-卡车 7-拖拉机 8-中巴
			if(index ==0 || index ==1 || index ==2 || index ==3) { //行人和非机动车外扩指定像素即可
				expansion_width = 10;
				expansion_height = 10;
			}

			/* 若该目标第一次出现 */
			if (total_snapshot_info.find(new_obj) == total_snapshot_info.end())
			{
				if(!snapshot_legal_minarea(index, cur_real_width, cur_real_height)){
					continue;
				}

				LOG_DEBUG("add task_id {} obj_id {}", task_id, obj_info.id);

				/* 存入当前抠图目标参数 flags用于判断目标从画面什么位置出现 方便之后排除出画面边缘的快照图 */
				total_snapshot_info[new_obj].index.count++;
				total_snapshot_info[new_obj].index.index = cur_real_index;
				total_snapshot_info[new_obj].confidence = obj_info.confidence;
				total_snapshot_info[new_obj].flags[0] = obj_info.left < minDistance[0] + SCALE_OUT ? 0 : 1;           //left
				total_snapshot_info[new_obj].flags[1] = obj_info.top < minDistance[1] + SCALE_OUT ? 0 : 1;            //top
				total_snapshot_info[new_obj].flags[2] = obj_info.right > frame_width - minDistance[2] - SCALE_OUT ? 0 : 1;   //right
				total_snapshot_info[new_obj].flags[3] = obj_info.bottom > frame_height - minDistance[3] - SCALE_OUT ? 0 : 1;     //bottom

				int cur_left = max(obj_info.left - 10, 0);
				int cur_top = max(obj_info.top - 10, 0);
				int cur_right = min(obj_info.right + 10, frame_width - 1);
				int cur_bottom = min(obj_info.bottom + 10, frame_height - 1);
				total_snapshot_info[new_obj].obj_pos = { cur_left, cur_top, cur_right - cur_left, cur_bottom - cur_top }; //debug by zsh 推出的坐标外扩10像素
				total_snapshot_info[new_obj].last_area = total_snapshot_info[new_obj].max_area = (cur_right - cur_left) * (cur_bottom - cur_top);
				
				total_snapshot_info[new_obj].frameCount = memPtr->getFrameNb();

				video_object_info info;
				info.left = max(obj_info.left - expansion_width, 0);
				info.top = max(obj_info.top - expansion_height, 0);
				info.right = min(obj_info.right + expansion_width, frame_width - 1);
				info.bottom = min(obj_info.bottom + expansion_height, frame_height - 1);
				strcpy(info.task_id, task_id.c_str());
				info.object_id = obj_info.id;
				info.confidence = obj_info.confidence;
				info.index = index;

				vec_obj_info.push_back(info);
			} else {
				total_snapshot_info[new_obj].last_area = (obj_info.right - obj_info.left) * (obj_info.bottom - obj_info.top);

				//---------------------------------------------------------------
				if (!best_snapshot_judge_algor(new_obj, total_snapshot_info[new_obj], obj_info.left, obj_info.top,
					cur_real_width, cur_real_height, frame_width, frame_height))
				{
					continue;
				}
				/* 若更优于之前的快照 做快照的更新 */
				if (total_snapshot_info[new_obj].index.count == 0)
				{
					total_snapshot_info[new_obj].index.count++;
					total_snapshot_info[new_obj].index.index = cur_real_index;
				}
				else
				{
					if (total_snapshot_info[new_obj].index.index == cur_real_index)
						total_snapshot_info[new_obj].index.count++;
					else
						total_snapshot_info[new_obj].index.count--;
				}

				int cur_left = max(obj_info.left - 10, 0);
				int cur_top = max(obj_info.top - 10, 0);
				int cur_right = min(obj_info.right + 10, frame_width - 1);
				int cur_bottom = min(obj_info.bottom + 10, frame_height - 1);
				total_snapshot_info[new_obj].obj_pos = { cur_left, cur_top, cur_right - cur_left, cur_bottom - cur_top }; //debug by zsh 推出的坐标外扩10像素
				total_snapshot_info[new_obj].last_area = total_snapshot_info[new_obj].max_area = (cur_right - cur_left) * (cur_bottom - cur_top);

				total_snapshot_info[new_obj].frameCount = memPtr->getFrameNb();

				video_object_info info;
				info.left = max(obj_info.left - expansion_width, 0);
				info.top = max(obj_info.top - expansion_height, 0);
				info.right = min(obj_info.right + expansion_width, frame_width - 1);
				info.bottom = min(obj_info.bottom + expansion_height, frame_height - 1);
				strcpy(info.task_id, task_id.c_str());
				info.object_id = obj_info.id;
				info.confidence = obj_info.confidence;
				info.index = index;

				vec_obj_info.push_back(info);
			}
		}

		vector<vpc_img_info> imgList = pVpcUtil->crop_batch(memPtr, vec_obj_info);
		vec_obj_info.clear();

		for (size_t i = 0; i < imgList.size(); i++) {
			vpc_img_info obj_info = imgList[i];
			OBJ_KEY objKey = { obj_info.task_id, obj_info.object_id };
			VPCUtil::vpc_img_release(total_snapshot_info[objKey].snapShot);
			total_snapshot_info[objKey].snapShot = VPCUtil::vpc_devMem2vpcImg(memPtr);
			VPCUtil::vpc_img_release(total_snapshot_info[objKey].snapShotLittle);
			total_snapshot_info[objKey].snapShotLittle = obj_info;
		}
		imgList.clear();
	}
}

map<OBJ_KEY, OBJ_VALUE> snapshot_reprocessing::get_total_snapshot_info(){
	return total_snapshot_info;
}

/* 快照判定辅助函数 */
bool snapshot_reprocessing::best_snapshot_judge_algor(const OBJ_KEY& obj_key, const OBJ_VALUE& obj_value, int left, int top, int width, int height, int image_width, int image_height)
{
	return snapshot_legal_pos(obj_value.flags, left, top, left + width, top + height, image_width, image_height)
		&& snapshot_legal_minarea(obj_value.index.index, width, height)
		&& snapshot_legal_inarea(width, height)
		&& snapshot_legal_area(obj_value.max_area, obj_value.last_area, left, top, left + width, top + height);
	return true;
}

/* 删除指定快照 清空资源占用(使用场景:任务结束删除该路任务所有缓存快照;目标轨迹结束,分析保存完,删除该目标快照缓存)*/
void snapshot_reprocessing::release_finished_locus_snapshot(const string taskid, const int obj_id, bool bRelease)
{ 
	LOG_DEBUG("task_id {} delete obj_id {}", taskid, obj_id); //221026
	if (obj_id != -1)
	{
		OBJ_KEY cur_key = { taskid , obj_id };
		auto it = total_snapshot_info.find(cur_key);
		if (it == total_snapshot_info.end()){
			return;
		}

		if (bRelease){
			OBJ_VALUE ss = total_snapshot_info[cur_key];

			VPCUtil::vpc_img_release(ss.snapShot);
			VPCUtil::vpc_img_release(ss.snapShotLittle);
		}
		
		total_snapshot_info.erase(cur_key);
		return;
	}

	for(auto ss = total_snapshot_info.begin(); ss != total_snapshot_info.end();)
	{
		if (strcmp(ss->first.video_id.c_str(), taskid.c_str()) == 0)
		{
			if (bRelease){
				VPCUtil::vpc_img_release(ss->second.snapShot);
				VPCUtil::vpc_img_release(ss->second.snapShotLittle);
			}
			total_snapshot_info.erase(ss++);
		}
		else ss++;
	}
}