Leetcode questions written by myself

topic

Give you a set of two-dimensional cv::Point2d points. These points are evenly distributed in the image. There are also some two-dimensional bounding boxes cv::Rect in the image. How to quickly determine whether these points are within these bounding boxes? Requirements There are two sets of input data, one is the points within the bounding box, and the other is the points not within the bounding box. The required implementation time complexity is O(n)

parse

To quickly determine whether a set of points is within a set of bounding boxes in O(n) time, you can use a Spatial Partition Tree or similar data structure to optimize this problem. Here is one solution:

  1. Create a spatial segmentation tree (such as a quadtree) to segment the image into multiple sub-regions. These sub-areas can be further subdivided as needed until the appropriate depth is achieved.

  2. Traverse all bounding boxes, test each bounding box for intersection with the spatial segmentation tree, and place the bounding box into the sub-region that intersects it. This can be achieved by comparing the position of the bounding box with the position of the subregion.

  3. Then, iterate over your set of points. For each point, you can quickly determine which subregion it belongs to, since each point only needs to be compared to part of the spatial partitioning tree. If a point lies within a bounding box, it must lie within the subregion of that bounding box. This allows you to quickly locate the bounding box that may contain the point.

  4. Finally, for each point, only the bounding box within the subregion it is located needs to be tested to determine whether it is within the bounding box. This will significantly reduce the number of bounding boxes that must be tested, thus achieving O(n) time complexity.

The key to this algorithm is to use spatial partitioning trees to reduce the number of tests, thereby improving the efficiency of search. In actual implementation, you need to consider how to build and maintain this tree and how to implement intersection testing with bounding boxes. But this method will help you quickly determine whether a set of points is within a set of bounding boxes in O(n) time.

code

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

// 定义空间分割树节点
struct QuadTreeNode {
    
    
    Rect boundary; // 区域的边界框
    vector<Point2d> points; // 区域内的点
    QuadTreeNode* children[4]; // 四个象限的子节点

    QuadTreeNode(const Rect& rect) : boundary(rect) {
    
    
        for (int i = 0; i < 4; i++) {
    
    
            children[i] = nullptr;
        }
    }

    // 插入一个点
    void insert(const Point2d& point) {
    
    
        // 如果该节点没有子节点,直接插入点
        if (children[0] == nullptr) {
    
    
            points.push_back(point);
            return;
        }

        // 否则,根据点的位置将点插入子节点中
        for (int i = 0; i < 4; i++) {
    
    
            if (children[i]->boundary.contains(point)) {
    
    
                children[i]->insert(point);
                return;
            }
        }
    }
};

// 判断点是否在边界框内
bool isPointInRect(const Point2d& point, const Rect& boundary) {
    
    
    return (point.x >= boundary.x && point.x <= boundary.x + boundary.width &&
            point.y >= boundary.y && point.y <= boundary.y + boundary.height);
}

// 快速检查一组点是否在一组边界框内
void checkPointsInRectangles(const vector<Point2d>& points, const vector<Rect>& rectangles) {
    
    
    QuadTreeNode* root = new QuadTreeNode(Rect(Point(0, 0), Point(100, 100))); // 假设整个图像大小为100x100

    // 插入边界框内的点
    for (const Rect& rect : rectangles) {
    
    
        for (const Point2d& point : points) {
    
    
            if (rect.contains(point)) {
    
    
                root->insert(point);
            }
        }
    }

    // 遍历所有的点并检查是否在边界框内
    for (const Point2d& point : points) {
    
    
        bool isInside = false;

        // 如果点在根节点内,则进一步检查
        if (root->boundary.contains(point)) {
    
    
            for (int i = 0; i < 4; i++) {
    
    
                if (root->children[i] != nullptr) {
    
    
                    // 检查点是否在子节点内
                    if (isPointInRect(point, root->children[i]->boundary)) {
    
    
                        for (const Point2d& p : root->children[i]->points) {
    
    
                            if (p == point) {
    
    
                                isInside = true;
                                break;
                            }
                        }
                    }
                    if (isInside) break;
                }
            }
        }

        if (isInside) {
    
    
            cout << "Point (" << point.x << ", " << point.y << ") is inside a rectangle." << endl;
        } else {
    
    
            cout << "Point (" << point.x << ", " << point.y << ") is not inside any rectangle." << endl;
        }
    }
}

int main() {
    
    
    vector<Point2d> pointsInRect; // 存放在边界框内的点
    vector<Point2d> pointsOutsideRect; // 存放不在边界框内的点

    // 填充点集合(示例)
    pointsInRect.push_back(Point2d(30, 30));
    pointsInRect.push_back(Point2d(10, 10));
    pointsOutsideRect.push_back(Point2d(80, 80));
    pointsOutsideRect.push_back(Point2d(5, 90));

    vector<Rect> rectangles; // 存放边界框

    // 填充边界框集合(示例)
    rectangles.push_back(Rect(20, 20, 20, 20));
    rectangles.push_back(Rect(5, 5, 10, 10));

    // 检查点是否在边界框内
    checkPointsInRectangles(pointsInRect, rectangles);
    checkPointsInRectangles(pointsOutsideRect, rectangles);

    return 0;
}

おすすめ

転載: blog.csdn.net/CCCrunner/article/details/134011822