#include "MfcLabel.h" #ifdef OPENCV_USE void MfcLabel::mfcLabel::AnalysisCvCoutour( std::vector>* Coutours, std::vector* Coutour_hier, int heircount) { fPolygon polygon; polygon.iInnerCount = 0; ReceiveCvCoutour(&(*Coutours)[heircount], false, &(polygon.Outer)); if ((*Coutour_hier)[heircount][2] != -1) { int innerindex = (*Coutour_hier)[heircount][2]; //doѭ��ֱ�Ӱ����е�inner������������ do { fRing temp_ring; ReceiveCvCoutour(&(*Coutours)[innerindex], false, &temp_ring); polygon.Inner.push_back(temp_ring); polygon.iInnerCount++; innerindex = (*Coutour_hier)[innerindex][0]; }while (innerindex != -1); } polygons.push_back(polygon); if ((*Coutour_hier)[heircount][0] != -1) { AnalysisCvCoutour(Coutours, Coutour_hier, (*Coutour_hier)[heircount][0]); } return ; } bool MfcLabel::mfcLabel::ReceiveCvCoutour(std::vector* coutour, bool Notinner, MfcLabel::fRing* ring) { if (coutour == NULL) return false; int coutourlength = coutour->size(); delete[] ring->pPoints; ring->m_nPointsCount = coutourlength; ring->pPoints = new fPoint[coutourlength]; for (int i = 0; i < coutourlength; i++) { ring->pPoints[i].x = float((*coutour)[i].x); ring->pPoints[i].y = float((*coutour)[i].y); } ring->ComputeBox(); return true; } #endif bool MfcLabel::mfcLabel::Empty() { if (iPolyCount == 0) return true; else return false; } #ifdef AFX_WIN BOOL MfcLabel::mfcLabel::ShowLabelInCDC(CDC* pDC) { return FALSE; } BOOL MfcLabel::mfcLabel::Serialize_S() { CFile outfile((CString)filePath.c_str(), CFile::modeWrite | CFile::modeCreate); CArchive ar(&outfile, CArchive::store); Serialize_StringS(ar, modelName); ar << score; Serialize_StringS(ar, filePath); ar << iPolyCount; for (int i = 0; i < iPolyCount; i++) { Serialize_fpolygonS(ar, &polygons[i]); } ar.Close(); outfile.Close(); return 1; } BOOL MfcLabel::mfcLabel::Serialize_L() { CFileFind finder; if (!finder.FindFile((CString)filePath.c_str())) { return 0; } CFile file((CString)filePath.c_str(), CFile::modeRead); CArchive ar(&file, CArchive::load); Serialize_StringL(ar, modelName); ar >> score; Serialize_StringL(ar, filePath); ar >> iPolyCount; polygons.resize(iPolyCount); for (int i = 0; i < iPolyCount; i++) { Serialize_fpolygonL(ar, &polygons[i]); } ar.Close(); return 1; } void MfcLabel::mfcLabel::Serialize_StringS(CArchive& ar, std::string& szString) { int length = szString.length(); ar << length; for (int i = 0; i < length; i++) { ar << szString[i]; } return; } void MfcLabel::mfcLabel::Serialize_StringL(CArchive & ar, std::string& szString) { int length = 0; ar >> length; szString.resize(length); for (int i = 0; i < length; i++) { ar >> szString[i]; } return; } void MfcLabel::mfcLabel::Serialize_fPointArrayS(CArchive & ar, fRing * pfsend) { int size = pfsend->m_nPointsCount; ar << size; for (int i = 0; i < size; i++) { ar << pfsend->pPoints[i].x; ar << pfsend->pPoints[i].y; } return; } void MfcLabel::mfcLabel::Serialize_fPointArrayL(CArchive & ar, fRing * pfreceive) { int size = 0; ar >> size; pfreceive->m_nPointsCount = size; pfreceive->pPoints = new fPoint[size]; for (int i = 0; i < size; i++) { ar >> pfreceive->pPoints[i].x; ar >> pfreceive->pPoints[i].y; } return; } void MfcLabel::mfcLabel::Serialize_fpolygonS(CArchive & ar, fPolygon * pfsend) { Serialize_StringS(ar, pfsend->name); ar << pfsend->score; Serialize_fPointArrayS(ar, &pfsend->Outer); int size = pfsend->iInnerCount; ar << size; for (int i = 0; i < size; i++) { Serialize_fPointArrayS(ar, &pfsend->Inner[i]); } return; } void MfcLabel::mfcLabel::Serialize_fpolygonL(CArchive & ar, fPolygon * pfreceive) { Serialize_StringL(ar, pfreceive->name); ar >> pfreceive->score; Serialize_fPointArrayL(ar, &pfreceive->Outer); ar >> pfreceive->iInnerCount; pfreceive->Inner.resize(pfreceive->iInnerCount); for (int i = 0; i < pfreceive->iInnerCount; i++) { Serialize_fPointArrayL(ar, &pfreceive->Inner[i]); } return; } #endif // AFX_WIN MfcLabel::fPoint MfcLabel::fRing::GetTwoSegmentIntersectPt(fPoint FstStartPt, fPoint FstEndPt, fPoint SecStartPt, fPoint SecEndPt) { double x; double y; MfcLabel::fPoint result(-1, -1); if (MfcLabel::fRing::JudgeTwoSegmentIntersect(FstStartPt, FstEndPt, SecStartPt, SecEndPt)) { const float WEIGHT_EPS = 1e-5f; double k = (FstStartPt.y - FstEndPt.y) / (FstStartPt.x - FstEndPt.x+ WEIGHT_EPS); double b = FstStartPt.y - k * FstStartPt.x; double k1 = (SecStartPt.y - SecEndPt.y) / (SecStartPt.x - SecEndPt.x+ WEIGHT_EPS); double b1 = SecStartPt.y - k1 * SecStartPt.x; x = (b1 - b) / (k - k1); y = k * x + b; result.x = float(x); result.y = float(y); } return result; } MfcLabel::fRing MfcLabel::fRing::GetTwoRingIntersectRing(fRing & FstRing, fRing & SecRing) { //���ȼ��һ�����������Ƿ����㹻��ĵ� if (FstRing.size() < 3 || SecRing.size() < 3) { return fRing(); } long x, y; //�������ν��� std::vector InterPtVec; for (int i = 0; i < FstRing.size(); i++) { // int poly1_next_idx = (i + 1) % FstRing.size(); for (int j = 0; j < SecRing.size(); j++) { int poly2_next_idx = (j + 1) % SecRing.size(); fPoint InterPt = GetTwoSegmentIntersectPt(FstRing.pPoints[i], FstRing.pPoints[poly1_next_idx], SecRing.pPoints[j], SecRing.pPoints[poly2_next_idx]); if (abs(InterPt.x - (-1))>FLT_EPSILON || abs(InterPt.y - (-1))>FLT_EPSILON) { InterPtVec.push_back(InterPt); } } } //���������ڲ��� for (int i = 0; i < FstRing.size(); i++) { if (SecRing.JudgePtInRingOrNot(FstRing.pPoints[i])) { InterPtVec.push_back(FstRing.pPoints[i]); } } for (int i = 0; i < SecRing.size(); i++) { if (FstRing.JudgePtInRingOrNot(SecRing.pPoints[i])) { InterPtVec.push_back(SecRing.pPoints[i]); } } if (InterPtVec.size() <= 0) return MfcLabel::fRing(); //�㼯���� ClockwiseSortPoints(InterPtVec); //������ת��ΪfRing�����õ� MfcLabel::fRing ResRing; ResRing.m_nPointsCount =int( InterPtVec.size()); ResRing.pPoints = new MfcLabel::fPoint[ResRing.m_nPointsCount]; for (int i = 0; i < ResRing.m_nPointsCount; i++) ResRing.pPoints[i] = InterPtVec[i]; ResRing.ComputeBox(); return ResRing; } //����a���ڵ�b,����a�ڵ�b˳ʱ�뷽��,����true,���򷵻�false bool MfcLabel::fRing::PointCmp(const fPoint & a, const fPoint & b, const fPoint & center) { if (a.x >= 0 && b.x < 0) return true; if (a.x == 0 && b.x == 0) return a.y > b.y; //����OA������OB�IJ�� int det =int( (a.x - center.x) * (b.y - center.y) )-int( (b.x - center.x) * (a.y - center.y)); if (det < 0) return true; if (det > 0) return false; //����OA������OB���ߣ��Ծ����жϴ�С int d1 = int((a.x - center.x) * (a.x - center.x)) + int((a.y - center.y) * (a.y - center.y)); int d2 = int((b.x - center.x) * (b.x - center.y)) + int((b.y - center.y) * (b.y - center.y)); return d1 > d2; } void MfcLabel::fRing::ClockwiseSortPoints(std::vector& vPoints) { //�������� MfcLabel::fPoint center; double x = 0, y = 0; for (int i = 0; i < vPoints.size(); i++) { x += vPoints[i].x; y += vPoints[i].y; } center.x = (int)x / vPoints.size(); center.y = (int)y / vPoints.size(); //ð������ for (int i = 0; i < vPoints.size() - 1; i++) { for (int j = 0; j < vPoints.size(); j++) { if (j< vPoints.size() - 1) { if (PointCmp(vPoints[j], vPoints[j + 1], center)) { MfcLabel::fPoint tmp = vPoints[j]; vPoints[j] = vPoints[j + 1]; vPoints[j + 1] = tmp; } } else { if (PointCmp(vPoints[j], vPoints[0], center)) { MfcLabel::fPoint tmp = vPoints[j]; vPoints[j] = vPoints[0]; vPoints[0] = tmp; } } } } } float MfcLabel::fRing::Area() { if (m_nPointsCount < 3) return 0.0; double s = pPoints[0].y * (pPoints[m_nPointsCount - 1].x - pPoints[1].x); for (int i = 1; i < m_nPointsCount; ++i) s += pPoints[i].y * (pPoints[i - 1].x - pPoints[(i + 1) % m_nPointsCount].x); return fabs(float(s * 0.5)); } bool MfcLabel::fRect::JudgePtInRectBoxOrNot(fPoint TestPt) { if (TestPt.x > Right || TestPt.x < Left || TestPt.y > Bottom || TestPt.y < Top) return false; else return true; } /*************************************************************************************************************************************** �������ƣ�JudgePointInContour �����������жϵ��Ƿ��������ڲ��ĺ��� ��������� Point ���жϵĵ� ����ֵ�� BOOL 1���������ڲ� ��1���������� ��0 ���������� ˵���� ��1���ú�����һ��Ҫ�󣬼��ж�֮ǰ����Ҫ����һ�ΰ�Χ���жϣ�����õ���������Χ���ڲ������������õ�ˮƽ���߳����㹻�������������� ������ܳ��ֵ����������֮�⣬����̽�����޷����������������е������ ***************************************************************************************************************************************/ bool MfcLabel::fRing::JudgePtInRingOrNot(fPoint TestPt) { double dbRadio = 2 * (RectBox.Right - RectBox.Left);//���߳��� fPoint OrigPt = TestPt;//������ʼ�� fPoint EndPt(TestPt.x + float(dbRadio), TestPt.y);//���߽����� int nInterCount = 0;//������� int nContourVecLength = (int)m_nPointsCount;//����������������� std::vector> SegIntersectPtVec;//�������ڵıߵ���ź��Ƿ�Ϊ������������� std::pair SegIntersectPt;//�ɶԵĽṹ std::vector ExpandPtVec;//�������ʹ�õ���չ���� //������������3���ߣ��򲻹��ɶ�����İ�Χ��ֱ�ӷ���false if (nContourVecLength < 3) { return false; } if (TestPt.x < RectBox.Left || TestPt.x > RectBox.Right || TestPt.y < RectBox.Top || TestPt.y > RectBox.Bottom) return false; //Ϊ��������߼������ʼ��ExpandPtVec����������Contour������ǰ����չ2���㣬��ѭ���ķ�ʽend->0 ��������쳣��ԭ��, //������չ����ij���ΪnContourLength+4 ExpandPtVec.push_back(pPoints[nContourVecLength - 2]); ExpandPtVec.push_back(pPoints[nContourVecLength - 1]); for (int i = 0; i < nContourVecLength; i++) { ExpandPtVec.push_back(pPoints[i]); } ExpandPtVec.push_back(pPoints[0]); ExpandPtVec.push_back(pPoints[1]); //ͨ����������Ƿ����߶��� for (int i = 2; i < nContourVecLength + 2; i++) { double Product = (OrigPt.x - ExpandPtVec[i].x) * (ExpandPtVec[i + 1].y - ExpandPtVec[i].y) - (ExpandPtVec[i + 1].x - ExpandPtVec[i].x) * (OrigPt.y - ExpandPtVec[i].y); if (fabs(Product) < DBL_EPSILON) { return true; } } //��������Χ�ڵ������߳����������ߵ�����Ƿ�����������ݲ�ͬ������ñ�־λ for (int i = 2; i < nContourVecLength + 2; i++) { //��������������ϵ��ཻ������Ժ������� if (JudgeTwoSegmentIntersect(OrigPt, EndPt, ExpandPtVec[i], ExpandPtVec[i + 1])) { //�ص���Խˮƽ����� if (ExpandPtVec[i].y == ExpandPtVec[i + 1].y) { SegIntersectPt.first = i; SegIntersectPt.second = true; SegIntersectPtVec.push_back(SegIntersectPt); } //��Խ���������� else if (OrigPt.y == ExpandPtVec[i].y || OrigPt.y == ExpandPtVec[i + 1].y) { SegIntersectPt.first = i; SegIntersectPt.second = true; SegIntersectPtVec.push_back(SegIntersectPt); } //��ͨ�Ĵ�Խ�����ߵ���� else { SegIntersectPt.first = i; SegIntersectPt.second = false; SegIntersectPtVec.push_back(SegIntersectPt); } } } //�������õı�־λ�ж�������������������ص���Խˮƽ�����������Խ�������������е��ظ����ֵı���Ϊ��ȵıߣ��Ա�����ļ������ж�ȥ���ظ� int nInterVecLength = (int)SegIntersectPtVec.size(); for (int i = 0; i < nInterVecLength; i++) { if (i != (nInterVecLength - 1) && SegIntersectPtVec[i].second && SegIntersectPtVec[i + 1].second) { if (SegIntersectPtVec[i].first + 1 == SegIntersectPtVec[i + 1].first) SegIntersectPtVec[i].first = SegIntersectPtVec[i + 1].first; } else if (SegIntersectPtVec[i].second && SegIntersectPtVec[0].second) { if (SegIntersectPtVec[i].first + 1 == SegIntersectPtVec[0].first) SegIntersectPtVec[i].first = SegIntersectPtVec[0].first; } } //��ʼ�����ܹ��еĽ������ for (int i = 0; i < nInterVecLength; i++) { //�����ʶΪFalse˵������ͨ��Խ�����ֱ�ӽ��㣫1 if (!SegIntersectPtVec[i].second) { nInterCount += 1; } else { //ͨ����һ���ҵ��Ĵ�Խ����Ϊ�����Ļ�ʯ�����ҳ��ô�Խ���ڴ�Խ�������ڵı߽磬�´�ѭ����Խ���õ㴦����һ���� int j = SegIntersectPtVec[i].first; while (SegIntersectPtVec[i].first == j) { if (i == nInterVecLength - 1) { i++; break; } i++; } i--; //��������д��������ﴦ�����ص���Խˮƽ������� if (ExpandPtVec[j].y == ExpandPtVec[j + 1].y) { if ( (ExpandPtVec[j - 1].y > OrigPt.y) && (ExpandPtVec[j + 2].y > OrigPt.y)) { nInterCount += 2; } else if ((ExpandPtVec[j - 1].y < OrigPt.y) && (ExpandPtVec[j + 2].y < OrigPt.y)) { nInterCount += 2; } else if ((ExpandPtVec[j - 1].y < OrigPt.y) && (ExpandPtVec[j + 2].y > OrigPt.y)) { nInterCount += 1; } else if ((ExpandPtVec[j - 1].y > OrigPt.y) && (ExpandPtVec[j + 2].y < OrigPt.y)) { nInterCount += 1; } } else { //��������д��������ﴦ������Խ������������ if ( (ExpandPtVec[j - 1].y > OrigPt.y) && (ExpandPtVec[j + 1].y > OrigPt.y)) { nInterCount += 2; } else if ((ExpandPtVec[j - 1].y < OrigPt.y) && (ExpandPtVec[j + 1].y < OrigPt.y)) { nInterCount += 2; } else if ((ExpandPtVec[j - 1].y < OrigPt.y) && (ExpandPtVec[j + 1].y > OrigPt.y)) { nInterCount += 1; } else if ((ExpandPtVec[j - 1].y > OrigPt.y) && (ExpandPtVec[j + 1].y < OrigPt.y)) { nInterCount += 1; } } } } std::vector().swap(ExpandPtVec); //����Ϊż�����ж�Ϊ���������⣬����Ϊ�������ж����������� if (nInterCount % 2 == 0) { return false; } return true; } bool MfcLabel::fRing::JudgeRingIntersectOrNot(fRing & TestRing) { //�����ж�����ring��Box�Ƿ��ཻ if (JudgeRectBoxIntersectOrNot(TestRing.RectBox, RectBox)) { for (int referLine = 0; referLine < m_nPointsCount; referLine++) { int nNextReferPtIndex = (referLine + 1) % m_nPointsCount; for (int testLine = 0; testLine < TestRing.m_nPointsCount; testLine++) { int nNextTestPtIndex = (testLine + 1) % TestRing.m_nPointsCount; if (JudgeTwoSegmentIntersect(pPoints[referLine], pPoints[nNextReferPtIndex], TestRing.pPoints[testLine], TestRing.pPoints[nNextTestPtIndex])) return true; else continue; } } } return false; } bool MfcLabel::fRing::JudgeTwoSegmentIntersect(fPoint& FirstLineStartPt, fPoint& FirstLineEndPt, fPoint& SecondLineStartPt, fPoint& SecondLineEndPt) { //�������������߶ε��Ƿ��ų��ʵ�顣 fRect test, refer; test = GetRectWithTwoPoint(FirstLineStartPt, FirstLineEndPt); refer = GetRectWithTwoPoint(SecondLineStartPt, SecondLineEndPt); if (!JudgeRectBoxIntersectOrNot(test, refer)) { return false; } //todo��Ҫ�޸� //��Ҫ����ֱ���໥�����ſ��� if (FirstLineStartPt.VectorSub(SecondLineStartPt).GetVectorProduct(SecondLineEndPt.VectorSub(SecondLineStartPt)) * SecondLineEndPt.VectorSub(SecondLineStartPt).GetVectorProduct(FirstLineEndPt.VectorSub(SecondLineStartPt)) >= -DBL_EPSILON) { if (SecondLineStartPt.VectorSub(FirstLineStartPt).GetVectorProduct(FirstLineEndPt.VectorSub(FirstLineStartPt)) * FirstLineEndPt.VectorSub(FirstLineStartPt).GetVectorProduct(SecondLineEndPt.VectorSub(FirstLineStartPt)) >= -DBL_EPSILON) return true; else return false; } else return false; } MfcLabel::fRect MfcLabel::fRing::GetRectWithTwoPoint(fPoint& Pt1, fPoint& Pt2) { fRect TwoPtRcbox; if (Pt1.x <= Pt2.x) { TwoPtRcbox.Left = (long)Pt1.x; TwoPtRcbox.Right = (long)Pt2.x; } else { TwoPtRcbox.Left = (long)Pt2.x; TwoPtRcbox.Right = (long)Pt1.x; } //���Pt1����Pt2���ϱߣ���Crect �����±߽�ȷ�� if (Pt1.y <= Pt2.y) { TwoPtRcbox.Top = (long)Pt1.y; TwoPtRcbox.Bottom = (long)Pt2.y; } else { TwoPtRcbox.Top = (long)Pt2.y; TwoPtRcbox.Bottom = (long)Pt1.y; } return TwoPtRcbox; } bool MfcLabel::fRing::JudgeRectBoxIntersectOrNot(fRect& Rect1, fRect& Rect2) { if (Rect1.RightRect2.Right || Rect1.Top > Rect2.Bottom || Rect1.Bottom < Rect2.Top) { return false; } return true; } double MfcLabel::fPoint::GetVectorProduct(fPoint B) { return x * B.y - B.x * y; } MfcLabel::fPoint MfcLabel::fPoint::VectorSub(fPoint B) { return fPoint(x-B.x,y-B.y); }