123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769 |
- #include "ContourModifyExport.h"
- extern "C" bool GetRotationTransMat(const MyPoint pointFix, const MyPoint pointMoveBef, const MyPoint pointMoveAft, double * rotMatDatas)
- {
- try
- {
- Point2f center = Point2f(pointFix.x, pointFix.y);
- float angleBef = fastAtan2(pointMoveBef.y - pointFix.y, pointMoveBef.x - pointFix.x);
- float angleAft = fastAtan2(pointMoveAft.y - pointFix.y, pointMoveAft.x - pointFix.x);
- // 因为fastAtan2求出来的角度,从x正方向起,越往逆时针方向转,角度值越大
- // 但rotate矩阵中需要输入顺时针转的角度,因此这里的rotate要用bef-aft
- double rotate = angleBef - angleAft;
- double distanceBef = DistanceBetweenTwoPoints(pointMoveBef, pointFix);
- double distanceAft = DistanceBetweenTwoPoints(pointMoveAft, pointFix);
- double scale = distanceAft / distanceBef;
- Mat rotMat = getRotationMatrix2D(center, rotate, scale);
- rotMatDatas[0] = rotMat.at<double>(0, 0);
- rotMatDatas[1] = rotMat.at<double>(0, 1);
- rotMatDatas[2] = rotMat.at<double>(0, 2);
- rotMatDatas[3] = rotMat.at<double>(1, 0);
- rotMatDatas[4] = rotMat.at<double>(1, 1);
- rotMatDatas[5] = rotMat.at<double>(1, 2);
- return true;
- }
- catch (...)
- {
- return false;
- }
- }
- extern "C" bool RotateAndScalePoints(double* rotMatDatas, const int pointNum, MyPoint * pointsBef, MyPoint * pointsAft)
- {
- try
- {
- Mat rotMat(2, 3, CV_64FC1);
- rotMat.at<double>(0, 0) = rotMatDatas[0];
- rotMat.at<double>(0, 1) = rotMatDatas[1];
- rotMat.at<double>(0, 2) = rotMatDatas[2];
- rotMat.at<double>(1, 0) = rotMatDatas[3];
- rotMat.at<double>(1, 1) = rotMatDatas[4];
- rotMat.at<double>(1, 2) = rotMatDatas[5];
- std::vector<Point2f> vectBef(pointNum);
- std::vector<Point2f> vectAft(pointNum);
- for(int ni=0; ni<pointNum; ni++)
- {
- vectBef[ni].x = pointsBef[ni].x;
- vectBef[ni].y = pointsBef[ni].y;
- }
- transform(vectBef, vectAft, rotMat);
- for (int ni = 0; ni < pointNum; ni++)
- {
- pointsAft[ni].x = vectAft[ni].x;
- pointsAft[ni].y = vectAft[ni].y;
- }
- return true;
- }
- catch (...)
- {
- return false;
- }
- }
- extern "C" bool RotatePoints(const MyPoint pointCenter, double angle, const int pointNum, MyPoint * pointsBef, MyPoint * pointsAft)
- {
- try
- {
- Point2f center = Point2f(pointCenter.x, pointCenter.y);
- Mat rotMat = getRotationMatrix2D(center, angle, 1);
- std::vector<Point2f> vectBef(pointNum);
- std::vector<Point2f> vectAft(pointNum);
- for (int ni = 0; ni < pointNum; ni++)
- {
- vectBef[ni].x = pointsBef[ni].x;
- vectBef[ni].y = pointsBef[ni].y;
- }
- transform(vectBef, vectAft, rotMat);
- for (int ni = 0; ni < pointNum; ni++)
- {
- pointsAft[ni].x = vectAft[ni].x;
- pointsAft[ni].y = vectAft[ni].y;
- }
- return true;
- }
- catch (...)
- {
- return false;
- }
- }
- extern "C" bool AngleBetweenTwoLine(const MyPoint pointOrigin, const MyPoint pointAnyDir, const MyPoint pointXDir, double& angle)
- {
- try
- {
- float angleX = fastAtan2(pointXDir.y - pointOrigin.y, pointXDir.x - pointOrigin.x);
- float angleCur = fastAtan2(pointAnyDir.y - pointOrigin.y, pointAnyDir.x - pointOrigin.x);
- // 因为fastAtan2求出来的角度,从x正方向起,越往逆时针方向转,角度值越大
- angle = angleCur - angleX;
- if(angle < 0)
- {
- angle += 360;
- }
- return true;
- }
- catch (...)
- {
- return false;
- }
- }
- extern "C" bool ContourArea(const MyPoint * points,const int pointNum, int& area)
- {
- try
- {
- if(pointNum<=0)
- {
- return false;
- }
- MyRect boundBox = ContourBoundBox(points, pointNum);
- std::vector<Point> contour(pointNum);
- int x, y;
- for (int ni = 0; ni < pointNum; ni++)
- {
- x = points[ni].x;
- y = points[ni].y;
- contour[ni].x = x - boundBox.left;
- contour[ni].y = y - boundBox.top;
- }
- Mat img = Mat::zeros(boundBox.bottom - boundBox.top +1, boundBox.right - boundBox.left + 1, CV_8UC1);
- std::vector<std::vector<Point>> contours;
- contours.push_back(contour);
- cv::drawContours(img, contours,0, 255, FILLED, LINE_8);
- area = cv::countNonZero(img);
- img.release();
- return true;
- }
- catch (...)
- {
- return false;
- }
- }
- extern "C" bool GetContourPointByPoint(const MyPoint * pointsBef, const int pointNum, MyPoint * pointsAft, int& pointNumAft)
- {
- try
- {
- int kernelSize = 5;
- int blurSize = 3;
- int boundBoxExpandSize = max(kernelSize,blurSize) * 2+1;
- if (pointNum <= 0)
- {
- return false;
- }
- MyRect boundBox = ContourBoundBox(pointsBef, pointNum);
- boundBox.top -= boundBoxExpandSize;
- boundBox.left -= boundBoxExpandSize;
- boundBox.right += boundBoxExpandSize;
- boundBox.bottom += boundBoxExpandSize;
- std::vector<Point> contour(pointNum);
- int x, y;
- for (int ni = 0; ni < pointNum; ni++)
- {
- x = pointsBef[ni].x;
- y = pointsBef[ni].y;
- contour[ni].x = x - boundBox.left;
- contour[ni].y = y - boundBox.top;
- }
- Size imgSize = Size(boundBox.right - boundBox.left + 1,boundBox.bottom - boundBox.top + 1);
- Mat img = Mat::zeros(imgSize, CV_8UC1);
- std::vector<std::vector<Point>> contours;
- contours.push_back(contour);
- cv::drawContours(img, contours, 0,255, FILLED, LINE_AA);
- cv::medianBlur(img, img, blurSize);
- cv::threshold(img, img, 128, 255, THRESH_BINARY);
- std::vector<std::vector<Point>> contoursFound;
- std::vector<Vec4i> hierarchy;
- cv::findContours(img, contoursFound, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE);
- int maxArea = 0;
- int index = -1;
- for(size_t ni=0; ni<contoursFound.size();ni++)
- {
- Mat imgSingleContour = Mat::zeros(imgSize, CV_8UC1);
- drawContours(imgSingleContour, contoursFound, ni, 255, FILLED, 0);
- int area = countNonZero(imgSingleContour);
- imgSingleContour.release();
- if(area > maxArea)
- {
- index = ni;
- maxArea = area;
- }
- }
- if(index!=-1)
- {
- std::vector<Point> contourSel = contoursFound[index];
- int len = contourSel.size();
- for(int ni=0; ni<len;ni++)
- {
- pointsAft[ni].x = contourSel[ni].x + boundBox.left;
- pointsAft[ni].y = contourSel[ni].y + boundBox.top;
- }
- pointNumAft = len;
- }
- img.release();
- return true;
- }
- catch (...)
- {
- return false;
- }
- }
- extern "C" bool GetContourWithLineAA(const MyPoint * pointsBef, const int pointNum, MyPoint * pointsAft, int& pointNumAft)
- {
- try
- {
- int boundBoxExpandSize = 1;
- if (pointNum <= 0)
- {
- return false;
- }
- MyRect boundBox = ContourBoundBox(pointsBef, pointNum);
- boundBox.top -= boundBoxExpandSize;
- boundBox.left -= boundBoxExpandSize;
- boundBox.right += boundBoxExpandSize;
- boundBox.bottom += boundBoxExpandSize;
- std::vector<Point> contour(pointNum);
- int x, y;
- for (int ni = 0; ni < pointNum; ni++)
- {
- x = pointsBef[ni].x;
- y = pointsBef[ni].y;
- contour[ni].x = x - boundBox.left;
- contour[ni].y = y - boundBox.top;
- }
- Size imgSize = Size(boundBox.right - boundBox.left + 1, boundBox.bottom - boundBox.top + 1);
- Mat img = Mat::zeros(imgSize, CV_8UC1);
- std::vector<std::vector<Point>> contours;
- contours.push_back(contour);
- cv::drawContours(img, contours, 0, 255, 1, LINE_AA);
- cv::threshold(img, img, 128, 255, THRESH_BINARY);
- std::vector<std::vector<Point>> contoursFound;
- std::vector<Vec4i> hierarchy;
- cv::findContours(img, contoursFound, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE);
- int maxArea = 0;
- int index = -1;
- for (size_t ni = 0; ni < contoursFound.size(); ni++)
- {
- Mat imgSingleContour = Mat::zeros(imgSize, CV_8UC1);
- drawContours(imgSingleContour, contoursFound, ni, 255, 1, LINE_AA);
- int area = countNonZero(imgSingleContour);
- imgSingleContour.release();
- if (area > maxArea)
- {
- index = ni;
- maxArea = area;
- }
- }
- if (index != -1)
- {
- std::vector<Point> contourSel = contoursFound[index];
- int len = contourSel.size();
- for (int ni = 0; ni < len; ni++)
- {
- pointsAft[ni].x = contourSel[ni].x + boundBox.left;
- pointsAft[ni].y = contourSel[ni].y + boundBox.top;
- }
- pointNumAft = len;
- }
- img.release();
- return true;
- }
- catch (...)
- {
- return false;
- }
- }
- extern "C" bool GetContourPointByPointEliminateSelfCross(const MyPoint * pointsBef, const int pointNum, MyPoint * pointsAft, int& pointNumAft)
- {
- try
- {
- int blurSize = 3;
- int boundBoxExpandSize = blurSize * 2 + 1;
- if (pointNum <= 0)
- {
- return false;
- }
- // 插值,让轮廓线至少是逐像素相连的
- std::vector<MyPoint> pointsPixelByPixel;
- MyPoint pointPre, pointNi;
- for(int ni=0; ni<pointNum; ni++)
- {
- pointNi = pointsBef[ni];
- // 第0个点,直接添加
- if(ni==0)
- {
- pointsPixelByPixel.push_back(pointNi);
- pointPre = pointNi;
- continue;
- }
- // 判断当前点与之前点的距离,如果小于等于0,则不添加,如果不相邻,则需要插入多个点
- AddPointsPixelByPixel(pointsPixelByPixel, pointNi, pointPre);
- pointPre = pointNi;
- // 最后一个点,再需要判断与第0个点的距离
- if (ni == pointNum)
- {
- AddPointsPixelByPixel(pointsPixelByPixel, pointsBef[0], pointNi);
- }
- }
- // 判断每个点和之前已添加的轮廓点是否交叉,如果交叉,则记录下来
- // 为了避免将临近点检测成交叉区域,只在当前点往回退7个点后才开始判断
- // 为了避免在同一个位置连续添加多个点,添加一个点后,跳过临近点
- int preStartCount = 8;
- int newPointCount = pointsPixelByPixel.size();
- std::vector<std::pair<int,int>> crossPoints;
- for(int ni=0; ni< newPointCount;ni++)
- {
- int closePointIndex = 0;
- if(CheckIfContourSelfCrossed(pointsPixelByPixel, ni, preStartCount, closePointIndex))
- {
- MyPoint pointNow = pointsPixelByPixel[closePointIndex];
- // 起点和终点必须闭合,因此不要把起点和终点误判为一对交叉点
- MyPoint pointStart= pointsPixelByPixel[0];
- MyPoint pointEnd = pointsPixelByPixel[newPointCount-1];
- double distanceToStart = DistanceBetweenTwoPoints(pointNow, pointStart);
- double distanceToEnd = DistanceBetweenTwoPoints(pointNow, pointEnd);
- if(distanceToStart<1.5 && distanceToEnd<1.5)
- {
- continue;
- }
- int existCount = crossPoints.size();
- if(existCount>0)
- {
- // 不要在一个位置处重复添加交叉点对
- int prePointFirst = crossPoints[existCount - 1].first;
- int prePointSecond = crossPoints[existCount - 1].second;
- MyPoint pointPre = pointsPixelByPixel[prePointSecond];
- double distance = DistanceBetweenTwoPoints(pointNow, pointPre);
- if(ni - prePointFirst <preStartCount && distance<1.5)
- {
- continue;
- }
- }
- std::pair<int, int> cross;
- cross.first = ni;
- cross.second = closePointIndex;
- crossPoints.push_back(cross);
- }
- }
- // 整理所有交叉点,组成一对一对的,这一对轮廓线中,可以删除将较长的那一组中间的所有点吸附到较短的那一条上
- int crossPointCount = crossPoints.size();
- if(crossPointCount >0)
- {
- // 未完成,自交叉的可能情况比较多,暂未找到合适的方法清除掉自交叉的部分
- }
- // 计算所有轮廓点的外边框
- MyRect boundBox = ContourBoundBox(pointsBef, pointNum);
- boundBox.top -= boundBoxExpandSize;
- boundBox.left -= boundBoxExpandSize;
- boundBox.right += boundBoxExpandSize;
- boundBox.bottom += boundBoxExpandSize;
- std::vector<Point> contour(pointNum);
- int x, y;
- for (int ni = 0; ni < pointNum; ni++)
- {
- x = pointsBef[ni].x;
- y = pointsBef[ni].y;
- contour[ni].x = x - boundBox.left;
- contour[ni].y = y - boundBox.top;
- }
- Size imgSize = Size(boundBox.right - boundBox.left + 1, boundBox.bottom - boundBox.top + 1);
- Mat img = Mat::zeros(imgSize, CV_8UC1);
- std::vector<std::vector<Point>> contours;
- contours.push_back(contour);
- cv::drawContours(img, contours, 0, 255, FILLED, LINE_AA);
- cv::medianBlur(img, img, blurSize);
- cv::threshold(img, img, 128, 255, THRESH_BINARY);
- std::vector<std::vector<Point>> contoursFound;
- std::vector<Vec4i> hierarchy;
- cv::findContours(img, contoursFound, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE);
- int maxArea = 0;
- int index = -1;
- for (size_t ni = 0; ni < contoursFound.size(); ni++)
- {
- Mat imgSingleContour = Mat::zeros(imgSize, CV_8UC1);
- drawContours(imgSingleContour, contoursFound, ni, 255, FILLED, 0);
- int area = countNonZero(imgSingleContour);
- imgSingleContour.release();
- if (area > maxArea)
- {
- index = ni;
- }
- }
- if (index != -1)
- {
- std::vector<Point> contourSel = contoursFound[index];
- int len = contourSel.size();
- for (int ni = 0; ni < len; ni++)
- {
- pointsAft[ni].x = contourSel[ni].x + boundBox.left;
- pointsAft[ni].y = contourSel[ni].y + boundBox.top;
- }
- pointNumAft = len;
- }
- img.release();
- return true;
- }
- catch (...)
- {
- return false;
- }
- }
- extern "C" bool LineContourIntersection(const MyPoint * points, const int pointNum, const MyPoint lineStart, const MyPoint lineEnd,
- const int touchDistance, bool extended, InterecttionsResults & results)
- {
- try
- {
- if (pointNum <= 0)
- {
- return false;
- }
- // 遍历轮廓上的点,当该点和直线的距离小于阈值,则认为是符合要求的点
- std::vector<InterecttionsDetails> intersections;
- double distanceStartToEnd = DistanceBetweenTwoPoints(lineStart, lineEnd);
- for(int ni=0;ni<pointNum;ni++)
- {
- MyPoint pointNi = points[ni];
- // 与start的距离
- double distanceToStart = DistanceBetweenTwoPoints(lineStart, pointNi);
- // 与end的距离
- double distanceToEnd= DistanceBetweenTwoPoints(lineEnd, pointNi);
- // 与start的夹角
- double angleWithStart = 0;
- AngleBetweenTwoLine(lineStart, pointNi, lineEnd, angleWithStart);
- if(angleWithStart>180)
- {
- angleWithStart = 360 - angleWithStart;
- }
- // 与直线的距离
- double distanceToLine = sin(DegToRad(angleWithStart)) * distanceToStart;
- if(distanceToLine <=touchDistance)
- {
- if(extended || distanceToEnd< touchDistance || distanceToStart<= touchDistance ||
- abs(distanceToEnd +distanceToStart - distanceStartToEnd)<=touchDistance )
- {
- InterecttionsDetails intersection;
- intersection.indexInContour = ni;
- intersection.distanceToLineStart = distanceToStart;
- intersection.distanceToLineEnd = distanceToEnd;
- intersections.push_back(intersection);
- }
- }
- }
- // 如果一个交点都没有,直接退出
- if (intersections.size() <= 0)
- {
- results.intersectWithLineStart = false;
- results.intersectWithLineEnd = false;
- results.indexInContourIntersectionStart = -1;
- results.indexInContourIntersectionEnd = -1;
- return true;
- }
- // 将交点按其与起点的距离排序
- sort(intersections.begin(), intersections.end(), SortIntersectionByDistanceToStartIncrease);
- // 找到离起点近的那个交点(必须是离start比离end近)
- std::vector<InterecttionsDetails> selected;
- if (intersections[0].distanceToLineStart <= intersections[0].distanceToLineEnd)
- {
- selected.push_back(intersections[0]);
- }
- // 将交点按其与终点的距离排序
- sort(intersections.begin(), intersections.end(), SortIntersectionByDistanceToEndIncrease);
- if (selected.size() > 0)
- {
- // 顺序将所有临近点删除
- std::vector<int> adjacent;
- bool preSearch = true;
- bool backSearch = true;
- int preIndex = selected[0].indexInContour;
- int backIndex = selected[0].indexInContour;
- adjacent.push_back(selected[0].indexInContour);
- while (preSearch || backSearch)
- {
- // 向前搜索
- if (preSearch)
- {
- // 循环自减(index 小于0时,需要注意反向)
- preIndex -= 1;
- if (preIndex < 0)
- {
- preIndex += pointNum;
- }
- bool contains = false;
- for (auto intersection : intersections)
- {
- if(intersection.indexInContour == preIndex)
- {
- contains = true;
- adjacent.push_back(preIndex);
- break;
- }
- }
- preSearch = contains;
- }
- // 向后搜索
- if (backSearch)
- {
- // 循环自增(index 大于keyPointNum时,需要注意反向)
- backIndex += 1;
- if(backIndex >= pointNum)
- {
- backIndex -= pointNum;
- }
- bool contains = false;
- for (auto intersection : intersections)
- {
- if (intersection.indexInContour == backIndex)
- {
- contains = true;
- adjacent.push_back(backIndex);
- break;
- }
- }
- backSearch = contains;
- if(adjacent.size()>= intersections.size())
- {
- break;
- }
- }
- }
- int pointToAddIndex = intersections[0].indexInContour;
- bool add = true;
- for (auto value : adjacent)
- {
- if(value == pointToAddIndex)
- {
- add = false;
- break;
- }
- }
- if(add)
- {
- selected.push_back(intersections[0]);
- }
- }
- else
- {
- if (intersections[0].distanceToLineEnd < intersections[0].distanceToLineStart)
- {
- selected.push_back(intersections[0]);
- }
- }
- if(selected.size()<=0)
- {
- results.intersectWithLineStart = false;
- results.intersectWithLineEnd = false;
- results.indexInContourIntersectionStart = -1;
- results.indexInContourIntersectionEnd = -1;
- return true;
- }
- else if(selected.size() == 2)
- {
- results.intersectWithLineStart = true;
- results.intersectWithLineEnd = true;
- results.indexInContourIntersectionStart = selected[0].indexInContour;
- results.indexInContourIntersectionEnd = selected[1].indexInContour;
- return true;
- }
- else
- {
- if(selected[0].distanceToLineStart <= selected[0].distanceToLineEnd)
- {
- results.intersectWithLineStart = true;
- results.intersectWithLineEnd = false;
- results.indexInContourIntersectionStart = selected[0].indexInContour;
- results.indexInContourIntersectionEnd = -1;
- }
- else
- {
- results.intersectWithLineEnd = true;
- results.intersectWithLineStart = false;
- results.indexInContourIntersectionEnd = selected[1].indexInContour;
- results.indexInContourIntersectionStart = -1;
- }
- return false;
- }
- }
- catch (...)
- {
- return false;
- }
- }
- MyRect ContourBoundBox(const MyPoint* points, const int pointNum)
- {
- int left = points[0].x;
- int right = points[0].x;
- int top = points[0].y;
- int bottom = points[0].y;
- int x, y;
- for (int ni = 1; ni < pointNum; ni++)
- {
- x = points[ni].x;
- y = points[ni].y;
- if (x < left)
- {
- left = x;
- }
- if(x>right)
- {
- right = x;
- }
- if(y<top)
- {
- top = y;
- }
- if(y>bottom)
- {
- bottom = y;
- }
- }
- MyRect boundBox;
- boundBox.left = left;
- boundBox.right = right;
- boundBox.top = top;
- boundBox.bottom = bottom;
- return boundBox;
- }
- double DistanceBetweenTwoPoints(const MyPoint pointOne, const MyPoint pointOther)
- {
- return sqrt(powf((pointOne.x - pointOther.x), 2) + powf((pointOne.y - pointOther.y), 2));
- }
- double DistanceBetweenTwoRect(const MyRect rectOne, const MyRect rectOther)
- {
- int left = max(rectOne.left, rectOther.left);
- int top = max(rectOne.top, rectOther.top);
- int right = min(rectOne.right, rectOther.right);
- int bottom = min(rectOne.bottom, rectOther.bottom);
- // 两个矩形有交集
- if(left<=right && top <=bottom)
- {
- return 0;
- }
- // x方向有平行区域
- if(left<=right)
- {
- return abs(bottom - top);
- }
- // y 方向有平行区域
- if(top<=bottom)
- {
- return abs(right - left);
- }
- // 没有交集,则left,top,right,bottom 构成的两个点之间的距离就是最短距离
- int disw = left - right;
- int dish = bottom - top;
- return sqrt(powf(disw, 2) + powf(dish, 2));
- }
- bool SortPointByDistanceIncrease(std::pair<double, MyPoint>a, std::pair<double, MyPoint>b)
- {
- return a.first < b.first;
- }
- bool SortIntersectionByDistanceToStartIncrease(InterecttionsDetails a, InterecttionsDetails b)
- {
- return a.distanceToLineStart < b.distanceToLineStart;
- }
- bool SortIntersectionByDistanceToEndIncrease(InterecttionsDetails a, InterecttionsDetails b)
- {
- return a.distanceToLineEnd < b.distanceToLineEnd;
- }
- bool AddPointsPixelByPixel(std::vector<MyPoint>& contours, MyPoint pointToAdd, MyPoint pointPre)
- {
- double distance = DistanceBetweenTwoPoints(pointToAdd, pointPre);
- // 距离为0,不添加
- if(distance<=0)
- {
- return false;
- }
- // 距离小于等于根号2,可以直接添加,不用插值
- if(distance < 1.5)
- {
- contours.push_back(pointToAdd);
- return true;
- }
- // 距离大于根号2,需要插值
- int deltaX = pointToAdd.x - pointPre.x;
- int deltaY = pointToAdd.y - pointPre.y;
- int deltaXAbs = abs(deltaX);
- int deltaYAbs = abs(deltaY);
- double ratio;
- // 看沿着哪个方向插值
- // x方向的差异较大,则沿着x方向插值
- if(deltaXAbs >deltaYAbs)
- {
- for(int ni=1; ni<deltaXAbs; ni++)
- {
- ratio = (double)ni / deltaXAbs;
- MyPoint pointNi;
- pointNi.x = pointPre.x + (int)(ratio * deltaX);
- pointNi.y = pointPre.y + (int)(ratio * deltaY);
- contours.push_back(pointNi);
- }
- contours.push_back(pointToAdd);
- }
- // y方向差异较大,则沿着y方向插值
- else
- {
- for (int ni = 1; ni < deltaYAbs; ni++)
- {
- ratio = (double)ni / deltaYAbs;
- MyPoint pointNi;
- pointNi.x = pointPre.x + (int)(ratio * deltaX);
- pointNi.y = pointPre.y + (int)(ratio * deltaY);
- contours.push_back(pointNi);
- }
- contours.push_back(pointToAdd);
- }
- return true;
- }
- bool CheckIfContourSelfCrossed(std::vector<MyPoint> contours, int curIndex, int preStartCount,int& indexOfClosePoint)
- {
- if(curIndex < preStartCount)
- {
- return false;
- }
- MyPoint pointCur = contours[curIndex];
- for(int ni=curIndex - preStartCount; ni>=0; ni--)
- {
- double distance = DistanceBetweenTwoPoints(pointCur, contours[ni]);
- if(distance<=1.5)
- {
- indexOfClosePoint = ni;
- return true;
- }
- }
- return false;
- }
|