Marking 3D connections based on Euclidean distances

I'm currently working on a project that is trying to group 3D points from a dataset, specifying connectivity as the minimum Euclidean distance. My algorithm now is simply a three-dimensional adaptation of a naive fill of the bay.

size_t PointSegmenter::growRegion(size_t & seed, size_t segNumber) {
    size_t numPointsLabeled = 0;

    //alias for points to avoid retyping
    vector<Point3d> & points = _img.points;
    deque<size_t> ptQueue;
    ptQueue.push_back(seed);
    points[seed].setLabel(segNumber);
    while (!ptQueue.empty()) {
        size_t currentIdx = ptQueue.front();
        ptQueue.pop_front();
        points[currentIdx].setLabel(segNumber);
        numPointsLabeled++;
        vector<int> newPoints = _img.queryRadius(currentIdx, SEGMENT_MAX_DISTANCE, MATCH_ACCURACY);
        for (int i = 0; i < (int)newPoints.size(); i++) {
            int newIdx = newPoints[i];
            Point3d &newPoint = points[newIdx];
            if(!newPoint.labeled()) {
                newPoint.setLabel(segNumber);
                ptQueue.push_back(newIdx);
            }
        }
    }

    //NOTE to whoever wrote the other code, the compiler optimizes i++ 
    //to ++i in cases like these, so please don't change them just for speed :)
    for (size_t i = seed; i < points.size(); i++) {
        if(!points[i].labeled()) {
            //search for an unlabeled point to serve as the next seed.
            seed = i;
            return numPointsLabeled;
        }
    }
    return numPointsLabeled;
}

If this code fragment is run again for a new seed, and _img.queryRadius () is a fixed-radius search with the ANN library:

vector<int> Image::queryRadius(size_t index, double range, double epsilon) {
    int k = kdTree->annkFRSearch(dataPts[index], range*range, 0);
    ANNidxArray nnIdx = new ANNidx[k];
    kdTree->annkFRSearch(dataPts[index], range*range, k, nnIdx);
    vector<int> outPoints;
    outPoints.reserve(k);
    for(int i = 0; i < k; i++) {
        outPoints.push_back(nnIdx[i]);
    }
    delete[] nnIdx;
    return outPoints;
}

My problem with this code is that it starts waaaaaaaaaaaaaaaaay too slowly for large datasets. If I’m not mistaken, this code will search for each individual point, and the search queries will do O (NlogN), which gives temporary complexity (N ^ 2 * log (N)).

, , KD, , , , .

, : ? , ?

,

, , dash-tom-bang, , . , , , ( .

, ? .

+3
3

:

  • .

  • , , , O (N) 3.

  • , O (N), O (N & alpha; (N)).

1, O (N 2) O (N log N) http://www.ncgia.ucsb.edu/conf/SANTA_FE_CD-ROM/sf_papers/lattuada_roberto/paper.html. 100- .

+3

- , "" - . , , " " . , , .

, ( "" ), "" " , .

+2

. vector<Point3d> - -, - , ( - ). , , , SEGMENT_MAX_DISTANCE, -, int, int, point.<corresponding_dimension> / SEGMENT_MAX_DISTANCE.

. .

+2

Source: https://habr.com/ru/post/1764212/


All Articles