/************************************************************* /* name: help.cpp /* Description: 辅助函数集合 /* Purpose:满足以下条件,合并两个框: /* 1 大框中包含小框 2 框交叉 3 框相邻 /* Update Time: by zl 20160307 **************************************************************/ #include "help.h" #include #include #include #include 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 &ForegroundArray) { //printf("\n ====== MergeNeighborBox =========\n"); vector::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::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 &ForegroundArray) { vector::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::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; }