help.cpp 6.07 KB
/*************************************************************
/* name: help.cpp															
/* Description: 辅助函数集合
/* Purpose:满足以下条件,合并两个框: 
/*			1 大框中包含小框 2 框交叉 3 框相邻
/* Update Time: by zl 20160307
**************************************************************/
#include "help.h"
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
//排序
bool SortByPoint(const CForeground &C1,const CForeground  &C2)
{  
	bool sign = false;
	if(C1.m_rtConnect.left < C2.m_rtConnect.left)
		return true;
	else if (C1.m_rtConnect.left == C2.m_rtConnect.left)
	{
		if(C1.m_rtConnect.top <= C2.m_rtConnect.top)
			return true;
		else
			return false;
	}
	else
		return false;
}

//判断x是否在边界内
bool InRange(int x, int boundary1, int boundary2)
{
	int max_b = boundary1 >= boundary2 ? boundary1 : boundary2;
	int min_b = boundary1 < boundary2 ? boundary1 : boundary2;
	if (x <= max_b && x >= min_b)
		return true;
	else
		return false;
}

//相邻或者包含
bool NeighbourorSub(CForeground c1, CForeground c2)
{
	//c2中心点在c1内部 需要合并 返回true
	/*if (c2.m_ptCenter.x < c1.m_rtConnect.right && InRange(c2.m_ptCenter.y, c1.m_rtConnect.top, c1.m_rtConnect.bottom))
	return true;
	else */
	//输入条件为c2一定在c1的右侧 因此若交叉或者包含 c2的左下点 或者 右上点 肯定至少有一个在c1的内部
	if (c2.m_rtConnect.left <= c1.m_rtConnect.right)
	{
		//包含或者交叉
		if (InRange(c2.m_rtConnect.bottom, c1.m_rtConnect.top, c1.m_rtConnect.bottom) || InRange(c2.m_rtConnect.top, c1.m_rtConnect.top, c1.m_rtConnect.bottom))
			return true;
		//上方邻近 或者 下方邻近
		else if (abs(c1.m_rtConnect.top - c2.m_rtConnect.bottom) < MergeMinDistance || abs(c1.m_rtConnect.bottom - c2.m_rtConnect.top) < MergeMinDistance)
			return true;
	}
	else if (InRange(c2.m_rtConnect.bottom, c1.m_rtConnect.top, c1.m_rtConnect.bottom) || InRange(c2.m_rtConnect.top, c1.m_rtConnect.top, c1.m_rtConnect.bottom))
	{
		if((abs(c1.m_rtConnect.right - c2.m_rtConnect.left) < MergeMinDistance))	//c2 在 c1 右侧 邻近
			return true;
	}

	return false;
}

//合并
void MergeNeighborBox(vector<CForeground> &ForegroundArray)
{
	//printf("\n ====== MergeNeighborBox =========\n");
	vector<CForeground>::iterator iter1 = ForegroundArray.begin();
	for(; iter1 != ForegroundArray.end() - 1 && iter1 != ForegroundArray.end(); iter1++)
	{
		//printf("%d %d %d %d\n", iter1->m_rtConnect.left, iter1->m_rtConnect.top, iter1->m_rtConnect.right, iter1->m_rtConnect.bottom);
		vector<CForeground>::iterator iter2 = iter1 + 1; 
		for (; iter2 != ForegroundArray.end(); )
		{
			//printf("   %d %d %d %d\n", iter2->m_rtConnect.left, iter2->m_rtConnect.top, iter2->m_rtConnect.right, iter2->m_rtConnect.bottom);

			//if ((x2 <= iter1->m_rtConnect.right && y2 <= iter1->m_rtConnect.bottom && y2 >= iter1->m_rtConnect.top) ||	//大框含小框状况
			//	(iter2->m_rtConnect.left <= iter1->m_rtConnect.right && iter2->m_rtConnect.bottom <= iter1->m_rtConnect.bottom && iter2->m_rtConnect.bottom >= iter1->m_rtConnect.top) || //框交叉 左上角在第一个框内
			//	(iter2->m_rtConnect.left <= iter1->m_rtConnect.right && iter2->m_rtConnect.top <= iter1->m_rtConnect.bottom && iter2->m_rtConnect.top >= iter1->m_rtConnect.top) ||//框交叉 左下角在第一个框内
			//	iter2->m_rtConnect.left <= iter1->m_ptCenter.x && abs(iter2->m_rtConnect.bottom - iter1->m_rtConnect.top) < 10 ||//距离较近的
			//	iter2->m_rtConnect.left <= iter1->m_ptCenter.x && abs(iter2->m_rtConnect.top - iter1->m_rtConnect.bottom) < 10 ||
			//	distance < 20	//距离较近的
			//	)
			if (NeighbourorSub(*iter1, *iter2))
			{
				//合并
				iter1->m_rtConnect.left = min(iter1->m_rtConnect.left, iter2->m_rtConnect.left);
				iter1->m_rtConnect.bottom = max(iter1->m_rtConnect.bottom, iter2->m_rtConnect.bottom);
				iter1->m_rtConnect.right = max(iter1->m_rtConnect.right, iter2->m_rtConnect.right);
				iter1->m_rtConnect.top = min(iter1->m_rtConnect.top, iter2->m_rtConnect.top);
				iter1->m_ptCenter.x = (iter1->m_rtConnect.right + iter1->m_rtConnect.left) / 2;
				iter1->m_ptCenter.y = (iter1->m_rtConnect.bottom + iter1->m_rtConnect.top) / 2;
				//删除一个
				iter2 = ForegroundArray.erase(iter2);
				iter1 = iter2;
				iter1--;
			}
			else
				iter2++;	
			//else
			//	break;	//由于ForegroundArray按x坐标排列 所以认为如果当前可以合并,则有可能下一个也需要合并;
						//但若当前不符合合并 则下一个也不会符合(为了减少计算次数)
			
		}
	}
}


int ifOverlapBox(CForeground iter1, CForeground iter2)
{
	if (iter1.m_rtConnect.left <= iter2.m_rtConnect.left &&iter1.m_rtConnect.top <= iter2.m_rtConnect.top
		&& iter1.m_rtConnect.right >= iter2.m_rtConnect.right && iter1.m_rtConnect.bottom >= iter2.m_rtConnect.bottom)
		return 2;
	else if (iter1.m_rtConnect.left >= iter2.m_rtConnect.left &&iter1.m_rtConnect.top >= iter2.m_rtConnect.top
		&& iter1.m_rtConnect.right <= iter2.m_rtConnect.right && iter1.m_rtConnect.bottom <= iter2.m_rtConnect.bottom)
		return 1;
	else return 0;
}


//合并之后 去除完全重叠的
void DislodgeOverlapBox(vector<CForeground> &ForegroundArray)
{
	vector<CForeground>::iterator iter1 = ForegroundArray.begin();
	for (; iter1 != ForegroundArray.end() - 1 && iter1 != ForegroundArray.end(); iter1++)
	{
		//printf("%d %d %d %d\n", iter1->m_rtConnect.left, iter1->m_rtConnect.top, iter1->m_rtConnect.right, iter1->m_rtConnect.bottom);
		vector<CForeground>::iterator iter2 = iter1 + 1;
		for (; iter2 != ForegroundArray.end(); )
		{
			//printf("   %d %d %d %d\n", iter2->m_rtConnect.left, iter2->m_rtConnect.top, iter2->m_rtConnect.right, iter2->m_rtConnect.bottom);

			int overlap_box = ifOverlapBox(*iter1, *iter2);
			if (!overlap_box)
			{
				iter2++;
				continue;
			}
			else if (overlap_box == 1)   //iter1 包围 iter2,删除iter2
			{
				iter2 = ForegroundArray.erase(iter2);
			}
			else   ////iter2 包围 iter1,删除iter1
			{
				iter1 = ForegroundArray.erase(iter1);
				break;
			}
		}
	}
}

int checkTime()
{
	struct tm* info;
	int nYear, nMonth, nDay;
	time_t raw;
	time(&raw);
	info = localtime(&raw);
	nYear = info->tm_year + 1900;
	nMonth = info->tm_mon + 1;
	nDay = info->tm_mday;
	if (nYear != 2020)//2017年1月1日版本过期
	{
		printf("版本过期!\n");
		return -1;
	}
	else
		return 1;
}