数据的均匀化分割算法(网格划分法、四叉树法(含C++代码))

news2024/11/17 2:38:05

数据的均匀化分割主要是指在分割过程中尽可能均匀地将数据点分布在各个子区域中,以保持数据分布的平衡和优化数据结构的性能。以下是几种可以实现数据均匀化分割的方法:

一. 网格划分法

1. 基本概念

        虽然传统的网格划分法不是动态调整的,但通过设计可以实现均匀的空间分割。例如,可以根据数据点的分布密度来调整网格的划分粒度,使得每个网格单元内包含的数据点数量尽量均匀。

        具体的,二维网格划分是一种对二维空间进行均匀分割的技术,用于将这种空间划分为多个小的、有时是规则的区域或单元,称为“网格”或“格子”。在图像处理中,二维网格划分可以用于将图像划分成小块进行局部分析或并行处理,从而加速图像处理任务如滤波、特征检测等。

2. 示例

  我有一组特征点存储在 std::vector<cv::KeyPoint> 类型的变量 vToDistributeKeys 中。这些特征点位于一张大小为宽1276像素、高378像素的图片上。为了在二维空间上实现点的均匀分布,我需要将图片分割成一个6x6的网格(共36个方块)。在每个方块内,我希望只保留具有最大置信度的特征点,并删除该方块内的其他点。下面是实现这一功能的具体C++代码。

#include <iostream>
#include <vector>
#include <opencv2/core/types.hpp>

// 将特征点按网格均匀分布,每个网格只保留置信度最高的特征点
std::vector<cv::KeyPoint> distributeAndFilterKeys(const std::vector<cv::KeyPoint>& keypoints, int width, int height, int gridRows, int gridCols) {
    // 计算每个网格的尺寸
    int cellWidth = width / gridCols;
    int cellHeight = height / gridRows;
    
    // 初始化网格,用于存储每个网格的最高置信度的特征点
    std::vector<std::vector<cv::KeyPoint>> grid(gridRows, std::vector<cv::KeyPoint>(gridCols));

    // 遍历所有特征点
    for (const auto& keypoint : keypoints) {
        int gridX = keypoint.pt.x / cellWidth;
        int gridY = keypoint.pt.y / cellHeight;

        // 确保网格索引不越界
        if (gridX >= gridCols) gridX = gridCols - 1;
        if (gridY >= gridRows) gridY = gridRows - 1;

        // 检查当前网格是否已有特征点,或者当前特征点置信度是否更高
        if (!grid[gridY][gridX].empty() && grid[gridY][gridX][0].response < keypoint.response) {
            grid[gridY][gridX][0] = keypoint;
        } else if (grid[gridY][gridX].empty()) {
            grid[gridY][gridX].push_back(keypoint);
        }
    }

    // 收集所有网格中的最佳特征点
    std::vector<cv::KeyPoint> filteredKeyPoints;
    for (int y = 0; y < gridRows; ++y) {
        for (int x = 0; x < gridCols; ++x) {
            if (!grid[y][x].empty()) {
                filteredKeyPoints.push_back(grid[y][x][0]);
            }
        }
    }

    return filteredKeyPoints;
}

int main() {
    // 假设的特征点数据
    std::vector<cv::KeyPoint> keypoints = {
        {cv::Point2f(100, 50), 1.f, -1, 0.8},
        {cv::Point2f(120, 60), 1.f, -1, 0.9},
        {cv::Point2f(130, 55), 1.f, -1, 0.95},
        // 添加更多点以测试
    };

    // 图片尺寸和网格配置
    int width = 1276;
    int height = 378;
    int gridRows = 6;
    int gridCols = 6;

    // 处理特征点
    std::vector<cv::KeyPoint> filteredKeyPoints = distributeAndFilterKeys(keypoints, width, height, gridRows, gridCols);

    // 输出结果
    for (const auto& kp : filteredKeyPoints) {
        std::cout << "Keypoint at (" << kp.pt.x << ", " << kp.pt.y << ") with response: " << kp.response << std::endl;
    }

    return 0;
}

二. 四叉树均匀化与非极大值抑制结合使用

在实际应用中,可以先对ORB特征点进行四叉树均匀化,然后再对每个子区域内的特征点进行非极大值抑制。这样可以在保证特征点分布均匀性的同时,提高特征点的质量和稳定性,最终得到更优的特征点集合。

1. 四叉树的基本概念

        在图像中,某些区域可能存在大量的特征点,而其他区域可能只有很少的特征点。这种不均匀分布会影响特征点的代表性和匹配效果。

        首先把一幅图案或一个幅面分割成多个分区或者部分。如果某个子区域内的特征点数量少于某个预设阈值,或者已经达到了分割的最小尺度,则这个子区域不再进行分割。如果特征点过于密集,则继续将这个区域分割成四个更小的子区域,并递归地对每个子区域进行同样的分割过程,直至每个子区域内的特征点数量满足预设条件。

        通过控制划分的停止条件(如特征点数量少于阈值、达到最小分割尺寸等),可以在保证足够的特征点总数的同时,让特征点在图像的不同区域内尽可能均匀分布。

        在划分完成后,每个子区域内可能包含多个特征点。为了进一步提高均匀性和代表性,可以在每个子区域内只保留响应值最大的特征点,去除其他的特征点。

2. 非极大值抑制

        非极大值抑制是一种常用的特征点后处理方法,主要用于去除临近区域内响应值较低的特征点,保留局部最大的特征点。其基本原理是,对于每个特征点,检查其周围邻域内是否存在响应值更大的特征点。如果存在,则将当前特征点去除;如果不存在,则保留当前特征点。

3. 示例

      一组特征点存储在 std::vector<cv::KeyPoint> 类型的变量 vToDistributeKeys 中。这些特征点分布在一张宽为1276像素、高为378像素的图片上。要求将图片分割成至少25个区域。

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

// 定义四叉树节点结构体
struct QuadTreeNode {
    cv::Rect rect;  // 节点代表的区域
    std::vector<cv::KeyPoint> keypoints;  // 节点内的特征点
    QuadTreeNode* children[4];  // 子节点指针

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

// 递归建立四叉树
void buildQuadTree(QuadTreeNode* node, const std::vector<cv::KeyPoint>& keypoints, int minPoints, int maxLevel, int level) {
    if (level >= maxLevel || node->keypoints.size() <= minPoints) {
        return;
    }

    // 将当前节点划分为四个子区域
    int halfWidth = node->rect.width / 2;
    int halfHeight = node->rect.height / 2;
    cv::Rect childRects[4] = {
        cv::Rect(node->rect.x, node->rect.y, halfWidth, halfHeight),
        cv::Rect(node->rect.x + halfWidth, node->rect.y, halfWidth, halfHeight),
        cv::Rect(node->rect.x, node->rect.y + halfHeight, halfWidth, halfHeight),
        cv::Rect(node->rect.x + halfWidth, node->rect.y + halfHeight, halfWidth, halfHeight)
    };

    // 为每个子区域创建子节点
    for (int i = 0; i < 4; i++) {
        node->children[i] = new QuadTreeNode(childRects[i]);
    }

    // 将特征点分配到子节点中
    for (const auto& keypoint : node->keypoints) {
        for (int i = 0; i < 4; i++) {
            if (node->children[i]->rect.contains(keypoint.pt)) {
                node->children[i]->keypoints.push_back(keypoint);
                break;
            }
        }
    }

    // 递归建立子节点的四叉树
    for (int i = 0; i < 4; i++) {
        buildQuadTree(node->children[i], node->children[i]->keypoints, minPoints, maxLevel, level + 1);
    }
}

// 非极大值抑制
void nonMaximumSuppression(std::vector<cv::KeyPoint>& keypoints, float radius) {
    std::vector<cv::KeyPoint> nmsKeypoints;
    std::sort(keypoints.begin(), keypoints.end(), [](const cv::KeyPoint& a, const cv::KeyPoint& b) {
        return a.response > b.response;
    });

    std::vector<bool> mask(keypoints.size(), true);
    for (size_t i = 0; i < keypoints.size(); i++) {
        if (mask[i]) {
            nmsKeypoints.push_back(keypoints[i]);
            for (size_t j = i + 1; j < keypoints.size(); j++) {
                if (cv::norm(keypoints[i].pt - keypoints[j].pt) <= radius) {
                    mask[j] = false;
                }
            }
        }
    }

    keypoints = nmsKeypoints;
}

// 四叉树均匀化结合非极大值抑制
void quadTreeUniformNMS(std::vector<cv::KeyPoint>& keypoints, int minPoints, int maxLevel, float nmsRadius) {
    // 创建根节点
    QuadTreeNode* root = new QuadTreeNode(cv::Rect(0, 0, 1276, 378));
    root->keypoints = keypoints;

    // 建立四叉树
    buildQuadTree(root, keypoints, minPoints, maxLevel, 0);

    // 对每个叶子节点进行非极大值抑制
    std::vector<cv::KeyPoint> uniformKeypoints;
    std::function<void(QuadTreeNode*)> traverseQuadTree = [&](QuadTreeNode* node) {
        if (node->children[0] == nullptr) {
            nonMaximumSuppression(node->keypoints, nmsRadius);
            uniformKeypoints.insert(uniformKeypoints.end(), node->keypoints.begin(), node->keypoints.end());
        } else {
            for (int i = 0; i < 4; i++) {
                traverseQuadTree(node->children[i]);
            }
        }
    };
    traverseQuadTree(root);

    keypoints = uniformKeypoints;

    // 释放内存
    std::function<void(QuadTreeNode*)> deleteQuadTree = [&](QuadTreeNode* node) {
        if (node->children[0] != nullptr) {
            for (int i = 0; i < 4; i++) {
                deleteQuadTree(node->children[i]);
                delete node->children[i];
            }
        }
    };
    deleteQuadTree(root);
    delete root;
}

int main() {
    std::vector<cv::KeyPoint> vToDistributeKeys;
    // ... 初始化 vToDistributeKeys ...

    int minPoints = 1;  // 每个区域最少特征点数量
    int maxLevel = 5;  // 最大分割层数
    float nmsRadius = 10.0f;  // 非极大值抑制半径

    quadTreeUniformNMS(vToDistributeKeys, minPoints, maxLevel, nmsRadius);

    // ... 使用均匀化后的特征点 vToDistributeKeys ...

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1664741.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件验收计划书-验收规程(Word原件)

编写软件验收计划是软件开发过程中的一个关键步骤&#xff0c;其重要性体现在以下几个方面&#xff1a; 明确验收标准&#xff1a;软件验收计划详细列出了验收的标准、测试方法、测试环境等&#xff0c;确保所有相关人员对验收的期望和要求有清晰的认识。这有助于避免在验收阶段…

Ansible---自动化运维工具

一、Ansible概述 1.1 Ansible简介 Ansible是一款自动化运维工具&#xff0c;通过ssh对目标主机进行配置、应用部署、任务执行、编排调度等操作。它简化了复杂的环境管理和自动化任务&#xff0c;提高了工作效率和一致性&#xff0c;同时&#xff0c;Ansible的剧本(playbooks)…

centos7.9升级4.19内核

centos默认的内核版本是3.10 通过命令 uname -a 输出系统的详细信息 在部署k8s集群时使用默认的3.10版本的内核&#xff0c;容易出各种奇奇怪怪的问题、可以理解为docker和k8s与该内核版本不兼容&#xff0c;所以在部署k8s集群时&#xff0c;务必要升级内核&#xff0c;这里…

【论文笔记 | 异步联邦】FedSA

FedSA&#xff1a;一种处理 non-IID 数据 的 过时感知 异步联邦算法 1. 论文信息 FedSA&#xff1a;A staleness-aware asynchronous Federated Learning algorithm with non-IID data&#xff0c;Future Generation Computer Systems&#xff0c;2021.7&#xff0c;ccfc 是…

即插即用篇 | YOLOv8引入局部自注意力 HaloAttention | 为参数高效的视觉主干网络扩展局部自注意力

本改进已集成到 YOLOv8-Magic 框架。 我们提出了Axial Transformers,这是一个基于自注意力的自回归模型,用于图像和其他组织为高维张量的数据。现有的自回归模型要么因高维数据的计算资源需求过大而受到限制,要么为了减少资源需求而在分布表达性或实现的便捷性上做出妥协。相…

05-10 周五 FastBuild 容器启动引起超时问题定位与解决

05-10 周五 FastBuild 容器启动超时问题 时间版本修改人描述2024年5月11日16:45:33V0.1宋全恒新建文档2024年5月11日22:37:21V1.0宋全恒完成解决方案的撰写&#xff0c;包括问题分析&#xff0c;docker命令 简介 关于FastBuild的优化&#xff0c;已经撰写了多个博客&#xff0…

C#知识|无边框的WinForm窗体,如何拖动位置?

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 上一节时练习做了一个简单的登录窗体界面&#xff0c;为了美观设置成了无边框&#xff0c; 当运行起来&#xff0c;发现无边框的窗体无法用鼠标拖动位置&#xff0c; 本节记录通过添加代码实现无边框窗体实现移动&…

IDEA创建springboot项目时不能选择java 8或者java 11等等版本的问题,解决方案

文章目录 1. Project JDK 和 Java 的区别2. 没有 java 8 或 java 11 等版本2.1 方案一2.2 方案二2.3 方案三 1. Project JDK 和 Java 的区别 我们在利用 idea 创建 spring boot 项目时&#xff0c;会有以上两个选项&#xff0c;这两个选项有什么区别&#xff1f; 答&#xff…

二、jacoco代码覆盖率工具

jacoco代码覆盖率工具 一、jacoco介绍二、常见的java代码覆盖率工具三、为什么选择jacoco四、jacoco的特点五、Jacoco 支持的覆盖率指标六、那些暂未支持的覆盖率指标七、jacoco技术原理八、Jacoco 下载与配置九、jacoco主要文件十、jacoco使用流程 一、jacoco介绍 JaCoCo 是一…

【GESP】2023年12月图形化二级 -- 小杨报数

小杨报数 【题目描述】 小杨需要从 1 1 1到 N N N报数。在报数过程中&#xff0c;小杨希望跳过 M M M的倍数。例如&#xff0c;如果 N 5 N5 N5&#xff0c; M 2 M2 M2&#xff0c;那么小杨就需要依次报出 1 1 1&#xff0c; 3 3 3&#xff0c; 5 5 5。 默认小猫角色和白色背…

LED液晶显示屏(LCD/TFT)抗干扰太阳光模拟器

LED&液晶显示屏(LCD/TFT)抗干扰太阳光模拟器&#xff1a;解决驾驶员视线问题 在驾车过程中&#xff0c;太阳光的干扰是一个常见的问题。特别是在高速公路等需要高度集中注意力的情况下&#xff0c;太阳光的干扰会严重影响驾驶员的视线&#xff0c;增加驾驶风险。为了解决这…

eNSP中小型园区网络拓扑搭建(上)

→b站直通车&#xff0c;感谢大佬← →eNSP中小型园区网络拓扑搭建&#xff08;下&#xff09;← 不带配置命令的拓扑图已上传~ 项目背景&#xff1a; 某公司准备新建一张网络供企业办公使用。写字楼共3层&#xff0c;一层会客大厅、二层行政部及市场部、三层研发部。一层设…

容器监控与日志管理

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、Docker监控工具 二、容器日志工具docker logs 三、第三方日志工具 四、容器日志驱动 五、示例 5.1、查看容器中运行的进程的信息 5.2、查看…

TEINet: Towards an Efficient Architecture for Video Recognition 论文阅读

TEINet: Towards an Efficient Architecture for Video Recognition 论文阅读 Abstract1 Introduction2 Related Work3 Method3.1 Motion Enhanced Module3.2 Temporal Interaction Module3.3 TEINet 4 Experiments5 Conclusion阅读总结 文章信息; 原文链接&#xff1a;https:…

BUU-[极客大挑战 2019]Http

考察点 信息收集 http构造请求数据包 题目 解题步骤 参考文章&#xff1a;https://zhuanlan.zhihu.com/p/367051798 查看源代码 发现有一个a标签&#xff0c;但是οnclick"return false"就是点击后不会去跳转到Secret.php的页面 所以我就自己拼接url http://no…

工业机器人应用实践之玻璃涂胶(篇二)

工业机器人 接上篇文章&#xff0c;浅谈一下实践应用&#xff0c;具体以玻璃涂胶为例&#xff1a; 了解工业机器人在玻璃涂胶领域的应用认识工具坐标系的标定方法掌握计时指令的应用掌握人机交互指令的应用掌握等待类指令用法&#xff08;WaitDI、WaitUnitl 等&#xff09;认…

表面的相似,本质的不同

韩信与韩王信&#xff0c;两个韩信的结局都是被刘邦所杀&#xff0c;似乎结局类似。但是&#xff0c;略加分析&#xff0c;就会发现其中存在本质的区别。 韩信属于必杀。他的王位是要来的&#xff0c;有居功自傲的本意&#xff0c;功高震主而且毫不避讳。而且年轻&#xff0c;…

REFORMER: 更高效的TRANSFORMER模型

大型Transformer模型通常在许多任务上都能达到最先进的结果&#xff0c;但是训练这些模型的成本可能会非常高昂&#xff0c;特别是在处理长序列时。我们引入了两种技术来提高Transformer的效率。首先&#xff0c;我们用一种使用局部敏感哈希的点积注意力替换了原来的点积注意力…

Apache ECharts

Apache ECharts介绍&#xff1a; Apache ECharts 是一款基于 Javascript 的数据可视化图表库&#xff0c;提供直观&#xff0c;生动&#xff0c;可交互&#xff0c;可个性化定制的数据可视化图表。 官网地址&#xff1a;https://echarts.apache.org/zh/index.html Apache ECh…

Django简介

Django 1.安装Django pip install djangopython的包的分布 \python- python.exe- Scripts- pip.exe- django-admin.exe [工具&#xff0c;创建django项目]- Lib- 内置模块- site-packages [安装的包]- pymysql- flask- django [框架的源码]2.创建项目 Django项目会有…