#include "StdAfx.h" #include "PageMatcher.h" #include "Affine2DEstimator0.h" #include "Affine2DEstimator.h" #include "CrossDetector.h" namespace identify{ CPageMatcher::CPageMatcher(void) { } CPageMatcher::~CPageMatcher(void) { } int CPageMatcher::Identifi(const IplImage * src, int shemaIndex, MATCH_REUSLT& match_result) { //旋转4个角度查找定位点(逆时针旋转 0度,90度,180度,270度) 并矫正 const int rotation[4] = { ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270 }; std::vector match_reuslts; int ret; for(std::size_t dir = 0; dir < 4; dir++) { MATCH_REUSLT result; ret = Identifi(src, shemaIndex, rotation[dir], result); if (ret == IDF_SUCCESS)match_reuslts.push_back(result); } match_result.matched_count = 0; int max_matched_count = 0; int max_matched_index = -1; for (std::size_t i = 0; i < match_reuslts.size(); i++) { if (max_matched_count < match_reuslts[i].matched_count){ max_matched_index = i; max_matched_count = match_reuslts[i].matched_count; } } if (max_matched_index<0){ return IDF_FAILURE; } match_result = match_reuslts[max_matched_index]; return IDF_SUCCESS; } int CPageMatcher::Identifi(const IplImage * src, int shemaIndex, const int rotation, MATCH_REUSLT& result) { const ISCH_SCHEMA_PAGE& schemaPage = (*schemaPages)[shemaIndex]; result.matched = false; int ret = BaseCheck(src, schemaPage); if (ret != IDF_SUCCESS)return ret; //估计比例 double estimate_scale = sqrt((double)(src->width*src->width + src->height*src->height)) / sqrt((double)(schemaPage.width*schemaPage.width + schemaPage.height*schemaPage.height)); //长宽不相等,进行长宽校验 if (abs(1 - max(schemaPage.width, schemaPage.height) / (double)min(schemaPage.width, schemaPage.height))>0.15){ if (rotation&(ROTATION_0 | ROTATION_180))//旋转0度或者180度 { if ((schemaPage.width > schemaPage.height) != (src->width > src->height))return IDF_FAILURE; } if (rotation&(ROTATION_90 | ROTATION_270)){ if ((schemaPage.width > schemaPage.height) != (src->width < src->height))return IDF_FAILURE; } } //记录对应关系属于哪个定位点、定位区、或交叉点 int first_index = 0; vector relationIndex; vector relationKey; vector relationValue; /********************************查找定位点*********************************************/ ret = FindLoacteByLocatePoint(src, schemaPage, estimate_scale, rotation, relationKey, relationValue, relationIndex, first_index); first_index += schemaPage.locatePoints.size(); if (ret != IDF_SUCCESS) return ret; /********************************查找模糊定位区*****************************************/ ret = FindLoacteByLocateArea(src, schemaPage, estimate_scale, rotation, relationKey, relationValue, relationIndex, first_index); first_index += schemaPage.locateAreas.size(); if (ret != IDF_SUCCESS) return ret; /********************************查找交叉点定位点***************************************/ ret = FindLoacteByLocateCross(src, schemaPage, estimate_scale, rotation, relationKey, relationValue, relationIndex, first_index); first_index += schemaPage.locateCrosses.size(); if (ret != IDF_SUCCESS) return ret; /********************************确认定位信息*********************************************/ int inliner_count; cv::Mat _inliner; ret = ConfirmLocateInfo(relationKey, relationValue, inliner_count, _inliner); if (ret != IDF_SUCCESS) return ret; std::map m; for(std::size_t kk = 0; kk < relationIndex.size(); kk++) { if (_inliner.at(0, kk))m[relationIndex[kk]]++; } int matched_count = m.size(); m_pageDirection = rotation; result.matched = true; result.schema_index = shemaIndex; result.dir = rotation; result.matched_count = matched_count; result.scale = m_Scaler0; result.total_count = schemaPage.locatePoints.size() + schemaPage.locateAreas.size() +schemaPage.locateCrosses.size();; memcpy(result.transfrom, m_AffineTransform.data, sizeof(result.transfrom)); return IDF_SUCCESS; } int CPageMatcher::FindLoacteByLocateArea(const IplImage * src, const ISCH_SCHEMA_PAGE& schemaPage, const double estimate_scale, const int rotation, vector& relationKey, vector& relationValue, vector &relationIndex, int first_index) { IplImage t; cvInitImageHeader(&t, cvSize(src->width, src->height), src->depth, src->nChannels, src->origin, src->align); cvSetData(&t, src->imageData, src->widthStep); IplImage * img = &t; for(std::size_t i = 0; i < schemaPage.locateAreas.size(); i++) { cvResetImageROI(img); int left, top, right, bottom; const ISCH_SCHEMA_LOCATE_AREA& locateArea = schemaPage.locateAreas[i].locate_area; const vector& locateAreaKeys = schemaPage.locateAreas[i].locateAreasKeyPoints; const CvPoint locateAreaOffset = schemaPage.locateAreas[i].locateAreasOffset; const Mat& locateAreaDescriptor = schemaPage.locateAreas[i].locateAreasDescriptor; double tw = locateArea.width + 100, th = locateArea.height + 100; switch (rotation){ case ROTATION_0: left = cv::max(0, (int)(locateArea.centerx*estimate_scale - tw / 2.0 + 0.5)); top = cv::max(0, (int)(locateArea.centery*estimate_scale - tw / 2.0 + 0.5)); right = min(img->width, (int)(locateArea.centerx*estimate_scale + tw / 2.0 + 0.5)); bottom = min(img->height, (int)(locateArea.centery*estimate_scale + th / 2.0 + 0.5)); break; case ROTATION_90: left = max(0, (int)(locateArea.centery*estimate_scale - th / 2.0 + 0.5)); top = max(0, (int)((schemaPage.width - locateArea.centerx)*estimate_scale - tw / 2.0 + 0.5)); right = min(img->width, (int)(locateArea.centery*estimate_scale + th / 2.0 + 0.5)); bottom = min(img->height, (int)((schemaPage.width - locateArea.centerx)*estimate_scale + tw / 2.0 + 0.5)); break; case ROTATION_180: left = max(0, (int)((schemaPage.width - locateArea.centerx)*estimate_scale - tw / 2.0 + 0.5)); top = max(0, (int)((schemaPage.height - locateArea.centery)*estimate_scale - th / 2.0 + 0.5)); right = min(img->width, (int)((schemaPage.width - locateArea.centerx)*estimate_scale + tw / 2.0 + 0.5)); bottom = min(img->height, (int)((schemaPage.height - locateArea.centery)*estimate_scale + th / 2.0 + 0.5)); break; case ROTATION_270: left = max(0, (int)((schemaPage.height - locateArea.centery)*estimate_scale - th / 2.0 + 0.5)); top = max(0, (int)(locateArea.centerx*estimate_scale - tw / 2.0 + 0.5)); right = min(img->width, (int)((schemaPage.height - locateArea.centery)*estimate_scale + th / 2.0 + 0.5)); bottom = min(img->height, (int)(locateArea.centerx*estimate_scale + tw / 2.0 + 0.5)); break; } cvSetImageROI(img, cvRect(left, top, right - left + 1, bottom - top + 1)); IplImage * grayImg = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1); if (img->nChannels == 3)cvCvtColor(img, grayImg, CV_BGR2GRAY); else cvCopy(img, grayImg); cvSmooth(grayImg, grayImg, CV_GAUSSIAN, 5); Mat m_m = cv::cvarrToMat(grayImg, false); std::vector keyPoints; Mat descriptor; Ptr pDetector = SurfFeatureDetector::create();// 这里我们用了SURF特征点 pDetector->detect(m_m, keyPoints); Ptr pExtractor = SurfDescriptorExtractor::create(); // 提取SURF描述向量 pExtractor->compute(m_m, keyPoints, descriptor); vector Matches; PtrpMatcher = new FlannBasedMatcher; // 使用Flann匹配算法 if (descriptor.rows > 0 && locateAreaDescriptor.rows > 0)pMatcher->match(descriptor, locateAreaDescriptor, Matches); if (Matches.size() >= 3){ vector _from; vector _to; for(std::size_t n = 0; n < Matches.size(); n++) { _to.push_back(keyPoints[Matches[n].queryIdx].pt); _from.push_back(locateAreaKeys[Matches[n].trainIdx].pt); } // Show result Mat _out; Mat _inliers; int su = estimateAffine2D0(_from, _to, _out, _inliers, 2); if (su > cv::max(5.0, locateAreaKeys.size()*0.1)){ double centerx = locateArea.centerx - locateAreaOffset.x;//locateArea.width/2.0; double centery = locateArea.centery - locateAreaOffset.y;//locateArea.height/2.0; double x = _out.at(0, 0)*centerx + _out.at(0, 1)*centery + _out.at(0, 2); double y = _out.at(1, 0)*centerx + _out.at(1, 1)*centery + _out.at(1, 2); if (0 <= x&&x < grayImg->width && 0 <= y&&y < grayImg->height){ relationKey.push_back(cvPoint2D32f(centerx + locateAreaOffset.x, centery + locateAreaOffset.y)); relationValue.push_back(cvPoint2D32f(x + left, y + top)); relationIndex.push_back(first_index + i); } } } cvReleaseImage(&grayImg); } return IDF_SUCCESS; } int CPageMatcher::ConfirmLocateInfo(vector& relationKey, vector& relationValue, int& inliner_count, cv::Mat& _inliner) { if (relationKey.size() < 3) return IDF_NOTFOUND_ENOUGH_LOCATEPOINT; Mat _out; Mat _inliers; vector _from; vector _to; for(std::size_t i = 0; i < relationKey.size(); i++) { _from.push_back(relationKey[i]); _to.push_back(relationValue[i]); } /*模型估计*/ int su = estimateAffine2D(_from, _to, _out, _inliers, 4); if (su < 3) return IDF_FAILURE; if (su >= 3){ m_AffineTransform = _out; Point2f src[3] = { Point2f(0, 0), Point2f(1000, 0), Point2f(0, 1000) }; Point2f dst[3] = { warpAffinePoint(src[0], &m_AffineTransform), warpAffinePoint(src[1], &m_AffineTransform), warpAffinePoint(src[2], &m_AffineTransform) }; double d_src[3] = { GetDistance(src[0], src[1]), GetDistance(src[0], src[2]), GetDistance(src[1], src[2]) }; double d_dst[3] = { GetDistance(dst[0], dst[1]), GetDistance(dst[0], dst[2]), GetDistance(dst[1], dst[2]) }; double scales[3] = { d_dst[0] / d_src[0], d_dst[1] / d_src[1], d_dst[2] / d_src[2] }; double dscale[3] = { abs(scales[0] - scales[1]), abs(scales[0] - scales[2]), abs(scales[1] - scales[2]) }; double scale = max(max(dscale[0], dscale[1]), dscale[2]); if (scale > 0.15)return IDF_FAILURE; m_AffineTransformInverseMatrix = getAffineTransform(dst, src); m_Scaler0 = d_dst[0] / d_src[0]; inliner_count = su; _inliner = _inliers; } return IDF_SUCCESS; } int CPageMatcher::FindLoacteByLocatePoint(const IplImage * src, const ISCH_SCHEMA_PAGE& schemaPage, const double estimate_scale, const int rotation, vector &relationKey, vector& relationValue, vector &relationIndex, int first_index) { #if _DEBUG cvSaveImage("D:\\binary_cvDilate.png", src); #endif IplImage t; cvInitImageHeader(&t, cvSize(src->width, src->height), src->depth, src->nChannels, src->origin, src->align); cvSetData(&t, src->imageData, src->widthStep); IplImage * img = &t; int tw = (int)(400 * estimate_scale); int th = (int)(400 * estimate_scale); int left, top, right, bottom; CvRect rect; IplImage* dst = cvCreateImage(cvSize(tw + 10, th + 10), IPL_DEPTH_8U, 1); CvSeq* contour = NULL; CvMemStorage * storage = cvCreateMemStorage(); vector> locatePointContour(schemaPage.locatePoints.size()); for(std::size_t i = 0; i < schemaPage.locatePoints.size(); i++) { const identify::schema::ISCH_SCHEMA_LOCATE_POINT& locatePoint = schemaPage.locatePoints[i]; switch (rotation){ case ROTATION_0: left = max(0, (int)(locatePoint.centerx*estimate_scale - tw / 2.0 + 0.5)); top = max(0, (int)(locatePoint.centery*estimate_scale - tw / 2.0 + 0.5)); right = min(img->width, (int)(locatePoint.centerx*estimate_scale + tw / 2.0 + 0.5)); bottom = min(img->height, (int)(locatePoint.centery*estimate_scale + th / 2.0 + 0.5)); rect = cvRect(left, top, right - left, bottom - top); break; case ROTATION_90: left = max(0, (int)(locatePoint.centery*estimate_scale - tw / 2.0 + 0.5)); top = max(0, (int)((schemaPage.width - locatePoint.centerx)*estimate_scale - tw / 2.0 + 0.5)); right = min(img->width, (int)(locatePoint.centery*estimate_scale + tw / 2.0 + 0.5)); bottom = min(img->height, (int)((schemaPage.width - locatePoint.centerx)*estimate_scale + th / 2.0 + 0.5)); rect = cvRect(left, top, right - left, bottom - top); break; case ROTATION_180: left = max(0, (int)((schemaPage.width - locatePoint.centerx)*estimate_scale - tw / 2.0 + 0.5)); top = max(0, (int)((schemaPage.height - locatePoint.centery)*estimate_scale - tw / 2.0 + 0.5)); right = min(img->width, (int)((schemaPage.width - locatePoint.centerx)*estimate_scale + tw / 2.0 + 0.5)); bottom = min(img->height, (int)((schemaPage.height - locatePoint.centery)*estimate_scale + th / 2.0 + 0.5)); rect = cvRect(left, top, right - left, bottom - top); break; case ROTATION_270: left = max(0, (int)((schemaPage.height - locatePoint.centery)*estimate_scale - tw / 2.0 + 0.5)); top = max(0, (int)(locatePoint.centerx*estimate_scale - tw / 2.0 + 0.5)); right = min(img->width, (int)((schemaPage.height - locatePoint.centery)*estimate_scale + tw / 2.0 + 0.5)); bottom = min(img->height, (int)(locatePoint.centerx*estimate_scale + th / 2.0 + 0.5)); rect = cvRect(left, top, right - left, bottom - top); break; } cvSetImageROI(img, rect); cvSet(dst, cvScalarAll(255)); cvSetImageROI(dst, cvRect(5, 5, rect.width, rect.height)); if (img->nChannels == 3)cvCvtColor(img, dst, CV_BGR2GRAY); else cvCopy(img, dst); cvResetImageROI(dst); cvThreshold(dst, dst, 160, 255, CV_THRESH_BINARY_INV); //cvAdaptiveThreshold(dst,dst,255,CV_ADAPTIVE_THRESH_MEAN_C,CV_THRESH_BINARY,5,-40); int an = 2; IplConvKernel * element = cvCreateStructuringElementEx(an * 2 + 1, an * 2 + 1, an, an, CV_SHAPE_RECT, 0);//创建结构元素 cvDilate(dst, dst, element, 1);//膨胀图像 cvErode(dst, dst, element, 1);//腐蚀图像 cvErode(dst, dst, element, 1);//腐蚀图像 /*cvSaveImage("D:\\binary_cvErode.png",dst);*/ cvDilate(dst, dst, element, 1);//膨胀图像 /*cvSaveImage("D:\\binary_cvDilate.png",dst);*/ cvReleaseStructuringElement(&element); int contours = cvFindContours(dst, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(rect.x - 5, rect.y - 5)); /*cvDrawContours(dst,contour,cvScalarAll(128),cvScalarAll(128),2,1,8,cvPoint(-(rect.x-5),-(rect.y-5))); cvSaveImage("D:\\binary_Contours.png",dst);*/ vector& contourList = locatePointContour[i]; if (rotation&(ROTATION_0 | ROTATION_180)){ for (CvContour * c = (CvContour *)contour; c != 0; c = (CvContour *)c->h_next) { if (c->rect.width < min(locatePoint.width*0.8, (double)locatePoint.width - 2)*estimate_scale)continue; if (c->rect.height < min(locatePoint.height*0.8, (double)locatePoint.height - 2)*estimate_scale)continue; if (c->rect.width > max(locatePoint.width*1.2, (double)locatePoint.width + 2)*estimate_scale)continue; if (c->rect.height > max(locatePoint.height*1.2, (double)locatePoint.height + 2)*estimate_scale)continue; cvSetImageROI(img, c->rect); int area = GetBlackArea(img); if (area < c->rect.width*c->rect.height*0.75)continue; double area2 = cvContourArea(c); if (area2 < c->rect.width*c->rect.height - (c->rect.width + c->rect.height)*3.5)continue; contourList.push_back(c); } } if (rotation&(ROTATION_90 | ROTATION_270)){ for (CvContour * c = (CvContour *)contour; c != 0; c = (CvContour *)c->h_next) { if (c->rect.height < min(locatePoint.width*0.8, (double)locatePoint.width - 2)*estimate_scale)continue; if (c->rect.width < min(locatePoint.height*0.8, (double)locatePoint.height - 2)*estimate_scale)continue; if (c->rect.height > max(locatePoint.width*1.2, (double)locatePoint.width + 2)*estimate_scale)continue; if (c->rect.width > max(locatePoint.height*1.2, (double)locatePoint.height + 2)*estimate_scale)continue; cvSetImageROI(img, c->rect); int area = GetBlackArea(img); if (area < c->rect.width*c->rect.height*0.75)continue; double area2 = cvContourArea(c); if (area2 < c->rect.width*c->rect.height - (c->rect.width + c->rect.height) * 3.5)continue; contourList.push_back(c); } } } for(std::size_t i = 0; i < schemaPage.locatePoints.size(); i++) { for(std::size_t j = 0; j < locatePointContour[i].size(); j++) { CvPoint2D32f* point1 = (CvPoint2D32f*)cvMemStorageAlloc(storage, sizeof(CvPoint2D32f)); CvPoint2D32f* point2 = (CvPoint2D32f*)cvMemStorageAlloc(storage, sizeof(CvPoint2D32f)); point1->x = schemaPage.locatePoints[i].centerx; point1->y = schemaPage.locatePoints[i].centery; CvContour& ff = *locatePointContour[i][j]; point2->x = ff.rect.x + ff.rect.width / 2.; point2->y = ff.rect.y + ff.rect.height / 2.; relationKey.push_back(*point1); relationValue.push_back(*point2); relationIndex.push_back(first_index + i); } } cvReleaseMemStorage(&storage); cvReleaseImage(&dst); return IDF_SUCCESS; } inline int CPageMatcher::BaseCheck(const IplImage * src, const ISCH_SCHEMA_PAGE& schemaPage) { // cvSaveImage("d:\\d1.jpg",src); if (src->width < 200 || src->height<200){ return IDF_SIZE2SMALL; } if (abs(max(src->width, src->height) / (double)min(src->width, src->height) - max(schemaPage.width, schemaPage.height) / (double)min(schemaPage.width, schemaPage.height))>0.2){ //图像长宽比不符 return IDF_SIDERATIO; } return IDF_SUCCESS; } int CPageMatcher::Identify(const IplImage* img, MATCH_REUSLT & match_result) { if (img == NULL) return IDF_FAILURE; if (schemaPages == NULL || schemaPages->size() < 1)return IDF_MISSING_TEMPLATES; std::vector match_results; for(std::size_t schemaIndex = 0; schemaIndex < schemaPages->size(); schemaIndex++){ MATCH_REUSLT result; int r = Identifi(img, schemaIndex, result); if (r == IDF_SUCCESS){ match_results.push_back(result); } } int max_gailv = 0; int matched_index = -1; for(std::size_t i = 0; i < match_results.size(); i++) { int gailv = match_results[i].matched_count - (match_results[i].total_count - match_results[i].matched_count); if (max_gailv < gailv){ matched_index = i; max_gailv = gailv; } } if (matched_index < 0){ return IDF_CANNOT_MATCH_TEMPLATE; } match_result = match_results[matched_index]; /*int min_unmatched_count =9999999; int min_unmatched_index =-1; for(std::size_t i=0;iunmatched_count){ min_unmatched_index =i; min_unmatched_count = unmatched_count; } } if(min_unmatched_index<0){return IDF_CANNOT_MATCH_TEMPLATE;} match_result = match_results[min_unmatched_index];*/ return IDF_SUCCESS; } void CPageMatcher::SetSchemaPages(boost::shared_ptr schema) { this->schemaPages = schema; } template T2 CPageMatcher::warpAffinePoint(T1& src, Mat * map_matrix) { T2 r; r.x = map_matrix->at(0, 0)*src.x + map_matrix->at(0, 1)*src.y + map_matrix->at(0, 2); r.y = map_matrix->at(1, 0)*src.x + map_matrix->at(1, 1)*src.y + map_matrix->at(1, 2); return r; } template double CPageMatcher::GetDistance(T1 point1, T2 point2) { double dx = point1.x - point2.x; double dy = point1.y - point2.y; return sqrt(dx*dx + dy*dy); } int CPageMatcher::FindLoacteByLocateCross(const IplImage * src, const ISCH_SCHEMA_PAGE& schemaPage, const double estimate_scale, const int rotation, vector& relationKey, vector& relationValue, vector &relationIndex, int first_index) { IplImage t; cvInitImageHeader(&t, cvSize(src->width, src->height), src->depth, src->nChannels, src->origin, src->align); cvSetData(&t, src->imageData, src->widthStep); IplImage * img = &t; int tw = (int)(200 * estimate_scale); int th = (int)(200 * estimate_scale); int left, top, right, bottom; CvRect rect; for(std::size_t i = 0; i < schemaPage.locateCrosses.size(); i++) { const identify::schema::ISCH_SCHEMA_LOACTE_CROSS& locateCross = schemaPage.locateCrosses[i]; switch (rotation){ case ROTATION_0: left = max(0, (int)(locateCross.centerx*estimate_scale - tw / 2.0 + 0.5)); top = max(0, (int)(locateCross.centery*estimate_scale - tw / 2.0 + 0.5)); right = min(img->width, (int)(locateCross.centerx*estimate_scale + tw / 2.0 + 0.5)); bottom = min(img->height, (int)(locateCross.centery*estimate_scale + th / 2.0 + 0.5)); rect = cvRect(left, top, right - left, bottom - top); break; case ROTATION_90: left = max(0, (int)(locateCross.centery*estimate_scale - tw / 2.0 + 0.5)); top = max(0, (int)((schemaPage.width - locateCross.centerx)*estimate_scale - tw / 2.0 + 0.5)); right = min(img->width, (int)(locateCross.centery*estimate_scale + tw / 2.0 + 0.5)); bottom = min(img->height, (int)((schemaPage.width - locateCross.centerx)*estimate_scale + th / 2.0 + 0.5)); rect = cvRect(left, top, right - left, bottom - top); break; case ROTATION_180: left = max(0, (int)((schemaPage.width - locateCross.centerx)*estimate_scale - tw / 2.0 + 0.5)); top = max(0, (int)((schemaPage.height - locateCross.centery)*estimate_scale - tw / 2.0 + 0.5)); right = min(img->width, (int)((schemaPage.width - locateCross.centerx)*estimate_scale + tw / 2.0 + 0.5)); bottom = min(img->height, (int)((schemaPage.height - locateCross.centery)*estimate_scale + th / 2.0 + 0.5)); rect = cvRect(left, top, right - left, bottom - top); break; case ROTATION_270: left = max(0, (int)((schemaPage.height - locateCross.centery)*estimate_scale - tw / 2.0 + 0.5)); top = max(0, (int)(locateCross.centerx*estimate_scale - tw / 2.0 + 0.5)); right = min(img->width, (int)((schemaPage.height - locateCross.centery)*estimate_scale + tw / 2.0 + 0.5)); bottom = min(img->height, (int)(locateCross.centerx*estimate_scale + th / 2.0 + 0.5)); rect = cvRect(left, top, right - left, bottom - top); break; } cvSetImageROI(img, rect); CCrossDetector crossDetector; std::vector crosss; crossDetector.Detect(img, crosss); int sign_=0; switch (rotation) { case ROTATION_0: if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_UP)sign_ |= ISCH_SCHEMA_CROSS_SIGN_UP; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_DOWN)sign_ |= ISCH_SCHEMA_CROSS_SIGN_DOWN; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_LEFT)sign_ |= ISCH_SCHEMA_CROSS_SIGN_LEFT; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_RIGHT)sign_ |= ISCH_SCHEMA_CROSS_SIGN_RIGHT; break; case ROTATION_90: if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_UP)sign_ |= ISCH_SCHEMA_CROSS_SIGN_LEFT; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_DOWN)sign_ |= ISCH_SCHEMA_CROSS_SIGN_RIGHT; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_LEFT)sign_ |= ISCH_SCHEMA_CROSS_SIGN_DOWN; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_RIGHT)sign_ |= ISCH_SCHEMA_CROSS_SIGN_UP; break; case ROTATION_180: if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_UP)sign_ |= ISCH_SCHEMA_CROSS_SIGN_DOWN; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_DOWN)sign_ |= ISCH_SCHEMA_CROSS_SIGN_UP; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_LEFT)sign_ |= ISCH_SCHEMA_CROSS_SIGN_RIGHT; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_RIGHT)sign_ |= ISCH_SCHEMA_CROSS_SIGN_LEFT; break; case ROTATION_270: if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_UP)sign_ |= ISCH_SCHEMA_CROSS_SIGN_RIGHT; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_DOWN)sign_ |= ISCH_SCHEMA_CROSS_SIGN_LEFT; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_LEFT)sign_ |= ISCH_SCHEMA_CROSS_SIGN_UP; if (locateCross.sign&ISCH_SCHEMA_CROSS_SIGN_RIGHT)sign_ |= ISCH_SCHEMA_CROSS_SIGN_DOWN; break; } for(std::size_t j = 0; j < crosss.size(); j++) { if (crosss[j].sign != sign_)continue; CvPoint2D32f point1; CvPoint2D32f point2; point1.x = locateCross.centerx; point1.y = locateCross.centery; const CvCross& ff = crosss[j]; point2.x = ff.x; point2.y = ff.y; relationKey.push_back(point1); relationValue.push_back(point2); relationIndex.push_back(first_index + i); } } return IDF_SUCCESS; } }