help.cpp
6.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*************************************************************
/* 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;
}