OpenCV实现图像特征提取与匹配
一、特征检测与描述子提取
-
选择特征检测器
常用算法包括:- ORB:一种高效的替代SIFT和SURF的算法,主要用于移动机器人和增强现实等领域。适合实时应用,结合FAST关键点与BRIEF描述子。
- SIFT(尺度不变特征变换):一种用于图像特征检测与描述的经典算法,具有尺度、旋转、光照不变性等特点。计算成本较高,不适合实时应用 。(需OpenCV contrib模块)。
- SURF:是对SIFT的改进,主要用于实时应用中。(需OpenCV contrib模块)。
- BRISK:二进制描述子,速度快且对噪声鲁棒。主要用于实时应用中。
算法 特点 SIFT 尺度不变性:通过构建图像金字塔和高斯差分金字塔来检测关键点,具有较好的尺度不变性。
旋转不变性:为每个关键点分配一个基准方向,确保描述子的旋转不变性。
光照和视角变化鲁棒性:部分抵抗光照变化,对视角变化也有较好的适应性。
计算复杂度高:由于需要构建多尺度空间,计算成本较高,不适合实时应用。SURF 速度更快:通过使用Hessian矩阵近似替代SIFT中的高斯差分函数,提高了计算速度。
鲁棒性:在保持SIFT的优点基础上,进一步优化了特征点的检测和描述符的构建过程。
光照和尺度不变性:与SIFT类似,具有较好的光照和尺度不变性。ORB 速度快:基于FAST角点检测和BRIEF描述符,计算速度比SIFT和SURF快两个数量级。
旋转不变性:通过计算关键点的主方向,实现旋转不变性。
二进制描述符:使用二进制描述符,有利于加速特征匹配过程。BRISK 快速计算:通过使用圆形邻域和高效的采样模式,计算速度较快。
二进制描述符:使用二进制描述符,有利于加速特征匹配过程。
尺度不变性:通过构建多尺度空间,具有一定的尺度不变性。// ORB检测器初始化 cv::Ptr<cv::ORB> detector = cv::ORB::create(500); // 提取500个特征点 std::vector<cv::KeyPoint> keypoints1, keypoints2; cv::Mat descriptors1, descriptors2;// 检测关键点并计算描述子 detector->detectAndCompute(img1, cv::noArray(), keypoints1, descriptors1); detector->detectAndCompute(img2, cv::noArray(), keypoints2, descriptors2);
// BRISK检测器 cv::Ptr<cv::BRISK> brisk = cv::BRISK::create(); // SURF检测器 cv::Ptr<cv::xfeatures2d::SURF> surf = cv::xfeatures2d::SURF::create(400);
//SIFT// 创建 SIFT 检测器对象Ptr<SIFT> sift = SIFT::create();// 检测关键点并计算描述子std::vector<KeyPoint> keypoints;Mat descriptors;sift->detectAndCompute(img, noArray(), keypoints, descriptors);
// 初始化SURF检测器,可以选择设置不同的阈值、半径等参数double hessianThreshold = 400;int nOctaves = 4;int nOctaveLayers = 3;bool extended = false;bool upright = false;cv::Ptr<cv::xfeatures2d::SURF> detector = cv::xfeatures2d::SURF::create(hessianThreshold, nOctaves, nOctaveLayers, extended, upright);// 检测关键点和提取特征描述子std::vector<cv::KeyPoint> keypoints1, keypoints2;cv::Mat descriptors1, descriptors2;detector->detectAndCompute(img1, cv::noArray(), keypoints1, descriptors1);detector->detectAndCompute(img2, cv::noArray(), keypoints2, descriptors2);
二、特征匹配
-
暴力匹配(BFMatcher)
计算所有特征对的距离,适合小规模数据集。cv::BFMatcher matcher(cv::NORM_HAMMING); // ORB/BRIEF用汉明距离 std::vector<cv::DMatch> matches; matcher.match(descriptors1, descriptors2, matches);
-
FLANN匹配
使用近似最近邻搜索,适合大规模数据集。cv::FlannBasedMatcher matcher(new cv::flann::LshIndexParams(20, 10, 2)); matcher.match(descriptors1, descriptors2, matches);
三、匹配结果优化
-
过滤低质量匹配
通过距离阈值筛选:double min_dist = DBL_MAX, max_dist = 0; for (auto& m : matches) {if (m.distance < min_dist) min_dist = m.distance;if (m.distance > max_dist) max_dist = m.distance; } std::vector<cv::DMatch> good_matches; for (auto& m : matches) {if (m.distance < 3 * min_dist) // 经验阈值good_matches.push_back(m); }
-
可视化匹配结果
cv::Mat img_matches; cv::drawMatches(img1, keypoints1, img2, keypoints2, good_matches, img_matches); cv::imshow("Matches", img_matches); cv::waitKey(0);
四、完整流程示例
4.1 ORB
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>int main() {// 读取图像cv::Mat img1 = cv::imread("image1.jpg", cv::IMREAD_GRAYSCALE);cv::Mat img2 = cv::imread("image2.jpg", cv::IMREAD_GRAYSCALE);// 初始化ORB检测器cv::Ptr<cv::ORB> detector = cv::ORB::create(500);std::vector<cv::KeyPoint> kp1, kp2;cv::Mat desc1, desc2;detector->detectAndCompute(img1, cv::noArray(), kp1, desc1);detector->detectAndCompute(img2, cv::noArray(), kp2, desc2);// 暴力匹配cv::BFMatcher matcher(cv::NORM_HAMMING);std::vector<cv::DMatch> matches;matcher.match(desc1, desc2, matches);// 过滤匹配点double min_dist = 100;std::vector<cv::DMatch> good_matches;for (auto& m : matches) {if (m.distance < 2 * min_dist)good_matches.push_back(m);}// 可视化cv::Mat img_matches;cv::drawMatches(img1, kp1, img2, kp2, good_matches, img_matches);//可调整参数显示匹配连线颜色/粗细cv::imshow("Matches", img_matches);cv::waitKey(0);return 0;
}
关键参数说明
detector->create() 控制特征点数量(如ORB::create(500))
NORM_HAMMING 二进制描述子(ORB、BRISK)的距离计算方式
drawMatches() 可调整参数显示匹配连线颜色/粗细
4.2 SIFT
//SIFT特征提取与显示代码
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp> // SIFT 头文件using namespace cv;
using namespace cv::xfeatures2d;int main() {// 1. 读取图像Mat img = imread("image.jpg", IMREAD_GRAYSCALE);if (img.empty()) {std::cerr << "图像读取失败!" << std::endl;return -1;}// 2. 创建 SIFT 检测器对象Ptr<SIFT> sift = SIFT::create(); // 新版本接口// 3. 检测关键点并计算描述子std::vector<KeyPoint> keypoints;Mat descriptors;sift->detectAndCompute(img, noArray(), keypoints, descriptors); // 核心函数// 4. 绘制关键点(带尺度和方向)Mat img_keypoints;drawKeypoints(img, keypoints, img_keypoints, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS); // 可视化增强// 5. 显示结果imshow("SIFT 关键点", img_keypoints);waitKey(0);return 0;
}
//SIFT特征匹配代码
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp> // SIFT 头文件using namespace cv;
using namespace cv::xfeatures2d;int main()
{
// 1. 读取两幅图像并计算特征
Mat img1 = imread("image1.jpg", IMREAD_GRAYSCALE);
Mat img2 = imread("image2.jpg", IMREAD_GRAYSCALE);
std::vector<KeyPoint> kp1, kp2;
Mat desc1, desc2;
sift->detectAndCompute(img1, noArray(), kp1, desc1);
sift->detectAndCompute(img2, noArray(), kp2, desc2);// 2. 使用 FLANN 匹配器(需转换为 CV_32F)
desc1.convertTo(desc1, CV_32F);
desc2.convertTo(desc2, CV_32F);
FlannBasedMatcher matcher;
std::vector<DMatch> matches;
matcher.match(desc1, desc2, matches); // 快速近邻匹配// 3. 筛选优质匹配(阈值法)
std::sort(matches.begin(), matches.end());
const int keep = matches.size() * 0.15;
matches.erase(matches.begin() + keep, matches.end());// 4. 绘制匹配结果
Mat img_matches;
drawMatches(img1, kp1, img2, kp2, matches, img_matches);
imshow("特征匹配结果", img_matches);
waitKey(0);return 0;
}
关键参数说明
SIFT::create():创建 SIFT 检测器对象,可设置参数(如特征点数量、对比度阈值等)。
detectAndCompute():单函数完成关键点检测与描述子计算,提升效率。
drawKeypoints():DRAW_RICH_KEYPOINTS 参数绘制关键点的尺度圆和方向线。
4.3 SURF
//SURF特征描述子匹配代码
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>int main() {// 加载图片cv::Mat img1 = cv::imread("path_to_image1.jpg", cv::IMREAD_GRAYSCALE);cv::Mat img2 = cv::imread("path_to_image2.jpg", cv::IMREAD_GRAYSCALE);// 初始化SURF检测器,可以选择设置不同的阈值、半径等参数double hessianThreshold = 400;int nOctaves = 4;int nOctaveLayers = 3;bool extended = false;bool upright = false;cv::Ptr<cv::xfeatures2d::SURF> detector = cv::xfeatures2d::SURF::create(hessianThreshold, nOctaves, nOctaveLayers, extended, upright);// 检测关键点和提取特征描述子std::vector<cv::KeyPoint> keypoints1, keypoints2;cv::Mat descriptors1, descriptors2;detector->detectAndCompute(img1, cv::noArray(), keypoints1, descriptors1);detector->detectAndCompute(img2, cv::noArray(), keypoints2, descriptors2);// 使用FLANN匹配器进行特征匹配cv::FlannBasedMatcher matcher(cv::makePtr<cv::flann::LshIndexParams>(12, 20, 2));std::vector<cv::DMatch> matches;matcher.match(descriptors1, descriptors2, matches);// 根据匹配距离进行排序std::sort(matches.begin(), matches.end());// 绘制匹配结果cv::Mat matchesImage;cv::drawMatches(img1, keypoints1, img2, keypoints2, matches, matchesImage,cv::Scalar::all(-1), cv::Scalar::all(-1), std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);// 显示匹配结果图像cv::imshow("Matches", matchesImage);cv::waitKey(0);return 0;
}
4.4 BRISK
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp> // 需要 OpenCV contrib 模块using namespace cv;int main() {// 1. 读取图像Mat img1 = imread("image1.jpg", IMREAD_GRAYSCALE);Mat img2 = imread("image2.jpg", IMREAD_GRAYSCALE);// 2. 初始化 BRISK 检测器Ptr<BRISK> brisk = BRISK::create();std::vector<KeyPoint> keypoints1, keypoints2;Mat descriptors1, descriptors2;// 3. 提取关键点和描述子brisk->detectAndCompute(img1, noArray(), keypoints1, descriptors1);brisk->detectAndCompute(img2, noArray(), keypoints2, descriptors2);// 4. 使用暴力匹配器(汉明距离)BFMatcher matcher(NORM_HAMMING);std::vector<DMatch> matches;matcher.match(descriptors1, descriptors2, matches);// 5. 过滤匹配点(基于距离阈值)double min_dist = 100;for (const auto& m : matches) {if (m.distance < min_dist) min_dist = m.distance;}std::vector<DMatch> good_matches;for (const auto& m : matches) {if (m.distance < 2 * min_dist) { // 调整阈值以控制筛选严格度good_matches.push_back(m);}}// 6. 可视化关键点Mat img_kp1, img_kp2;drawKeypoints(img1, keypoints1, img_kp1, Scalar(0, 255, 0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);drawKeypoints(img2, keypoints2, img_kp2, Scalar(0, 255, 0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);imshow("BRISK Keypoints 1", img_kp1);imshow("BRISK Keypoints 2", img_kp2);// 7. 可视化匹配结果Mat img_matches;drawMatches(img1, keypoints1, img2, keypoints2, good_matches, img_matches,Scalar::all(-1), Scalar::all(-1), std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);imshow("BRISK Matches", img_matches);waitKey(0);return 0;
}
关键参数说明
1)BRISK 参数:
Ptr<BRISK> brisk = BRISK::create(
int thresh = 30, // FAST角点检测阈值
int octaves = 3, // 图像金字塔层数
float patternScale = 1.0 // 描述子采样模式缩放
);
修改 thresh 可调整检测到的关键点数量(值越小,检测到的点越多)。
2)匹配筛选:
调整 if (m.distance < 2 * min_dist) 中的倍数系数(如 2 → 3)可放宽或收紧筛选条件。
使用 RANSAC 几何验证 进一步优化匹配(参考 SIFT/SURF 代码中的 findHomography 步骤)。
相关文章:
OpenCV实现图像特征提取与匹配
一、特征检测与描述子提取 选择特征检测器 常用算法包括: ORB:一种高效的替代SIFT和SURF的算法,主要用于移动机器人和增强现实等领域。适合实时应用,结合FAST关键点与BRIEF描述子。SIFT(尺度不变特征变…...
MyBatis 的核心配置文件是干什么的? 它的结构是怎样的? 哪些是必须配置的,哪些是可选的?
MyBatis 的核心配置文件(通常命名为 mybatis-config.xml)是 MyBatis 应用程序的入口点,它定义了 MyBatis 的全局配置信息 。 核心配置文件的作用: 配置 MyBatis 的运行时行为: 通过 <settings> 标签设置全局参数ÿ…...
VLAN,DHCP实验访问物理机
目标 三层交换机完成DHCP自动分配IP地址不同vlan间完成通信DNS服务器能够解析www.baidu.com,使PC机能够访问连接真实物理机,PC机与物理机能够互相访问 步骤 一、创建VLAN,配置好PC机和交换机的IP地址 LSW1 [LSW1]vlan batch 10 20 Info: T…...
六十天前端强化训练之第十七天React Hooks 入门:useState 深度解析
欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗,谢谢大佬! 目录 一、知识讲解 1. Hooks 是什么? 2. useState 的作用 3. 基本语法解析 4. 工作原理 5. 参数详解 a) 初始值设置方式 b) 更新函数特性 6. 注意事项 7. 类组…...
解决 HTTP 请求中的编码问题:从乱码到正确传输
文章目录 解决 HTTP 请求中的编码问题:从乱码到正确传输1. **问题背景**2. **乱码问题的原因**2.1 **客户端编码问题**2.2 **请求头缺失**2.3 **服务器编码问题** 3. **解决方案**3.1 **明确指定请求体编码**3.2 **确保请求头正确**3.3 **动态获取响应编码** 4. **调…...
跨国企业网络案例分析:SD-WAN智能组网
跨国企业面临的网络问题日益增加,如全球供应链协同、跨国研发协作及实时生产数据传输等场景,对网络质量提出更高要求。本文将深度解析某跨国工业集团如何通过SD-WAN实现网络架构智能化转型。 该集团以上海全球总部为核心,构建了覆盖亚欧美三大…...
视频孪生与三维视频融合:重构工业现场的“数字视网膜“
在浙江某精密制造企业的总控中心,30米长的曲面屏上实时跳动着工厂的每个生产细节:机械臂的运动轨迹与数字模型完全同步,质检工位的操作误差被自动标记,AGV小车的行进路径在三维空间中以光带形式可视化呈现。这种虚实交融的场景并非…...
STM32Cubemx-H7-7-OLED屏幕
如何把江科大的OLED标准库文件换成hal库的文件 前言 本文讲解如在hHAL库中使用OLED,其实江科大做的文件好已经很好了 只讲操作,不讲废话,默认大家都有32基本操作 创建工程 首先创建工程 把那两个引脚设置成开漏 获取标准库文件 打开江科大O…...
FPGA为何要尽量减少组合逻辑的使用
在FPGA设计中,组合逻辑的使用确实需要谨慎,尤其是要尽量减少它的复杂性。这并不是因为组合逻辑本身不好,而是因为它在实际应用中容易引发一系列问题,而这些问题往往与FPGA的设计哲学和硬件特性相冲突。让我从几个关键点来和你聊聊…...
缓存使用的具体场景有哪些?缓存的一致性问题如何解决?缓存使用常见问题有哪些?
缓存使用场景、一致性及常见问题解析 一、缓存的核心使用场景 1. 高频读、低频写场景 典型场景:商品详情页、新闻资讯、用户基本信息。特点:数据更新频率低,但访问量极高。策略: Cache-Aside(旁路缓存)&a…...
基于 RWA 模型与 AI - Agent 协同的企业级 aPAAS 架构设计
一、引言 在企业数字化转型不断深化的当下,现实世界资产(RWA)模型与人工智能智能体(AI - Agent)的协同融合,为企业级应用平台即服务(aPAAS)架构的创新发展带来了新契机。这种架构旨在…...
基于“动手学强化学习”的知识点(一):第 14 章 SAC 算法(gym版本 >= 0.26)
第 14 章 SAC 算法(gym版本 > 0.26) 摘要SAC 算法(连续)SAC 算法(离散) 摘要 本系列知识点讲解基于动手学强化学习中的内容进行详细的疑难点分析!具体内容请阅读动手学强化学习&…...
【QT:信号和槽】
QT信号涉及的三要素:信号源、信号类型、信号的处理方式。 QT的信号槽机制: 给按钮的点击操作关联一个处理函数,用户点击按钮时触发,对应的处理函数就会执行 QT中使用connect函数将信号和槽关联起来,信号触发…...
Oracle中的INHERIT PRIVILEGES权限
Oracle中的INHERIT PRIVILEGES权限 存储过程和用户函数的AUTHID属性调用者权限vs定义者权限一个简单的示例INHERIT PRIVILEGES权限的含义INHERIT PRIVILEGES权限的安全隐患注意到Oracle 19c数据库中有如下权限信息: SQL> select grantor,grantee,table_name,privilege fro…...
Compose笔记(九)--Checkbox
这一节主要了解一下Compose中的Checkbox,它是Jetpack Compose UI框架中的一个组件,用于创建复选框功能。它允许用户从一个集合中选择一个或多个项目,可以将一个选项打开或关闭。与传统的Android View系统中的Checkbox相比,Compose…...
CSS中粘性定位
1.如何设置为粘性定位? 给元素设置posttion:sticky 即可实现粘性定位. 可以使用left, right ,top, bottom 四个属性调整位置,不过最常用的是top 值. 2.粘性定位的参考点在哪里? 离他最近的一个拥有"滚动机制"的祖先元素,即便这个祖先不是最近的真实可滚动祖先. 3.粘…...
日本IT|AWS工作内容及未来性、以及转职的所需资质和技能
AWSとは AWSはAmazon Web Services(アマゾンウェブサービス)の略称です。 名称から分かるとおり、ネットを通じた通販などを事業として行っているAmazon.com社がクラウドサービスとして運営しています。 本来であれば自分たちでインフラ環境を構築する…...
《Spring日志整合与注入技术:从入门到精通》
1.Spring与日志框架的整合 1.Spring与日志框架进行整合,日志框架就可以在控制台中,输出Spring框架运行过程中的一些重要的信息。 好处:方便了解Spring框架的运行过程,利于程序的调试。 Spring如何整合日志框架 Spring5.x整合log4j…...
如何判断一个项目用的是哪个管理器
如何判断一个项目用的是哪个管理器 npm: 如果项目中存在 package-lock.json 文件,这通常意味着项目使用 npm 作为包管理器。package-lock.json 文件会锁定项目的依赖版本,确保在不同环境中安装相同的依赖。 pnpm: 如果项目中存在 pnpm-lock.yaml 文件&a…...
软件工程概述
软件开发生命周期 软件定义时期:包括可行性研究和详细需求分析,任务是确定软件开发的总目标。 问题定义可行性研究(经济、技术、操作、社会可行性,确定问题和解决办法)需求分析(确定功能需求,性…...
文件系统 linux ─── 第19课
前面博客讲解的是内存级文件管理,接下来介绍磁盘级文件管理 文件系统分为两部分 内存级文件系统 : OS加载进程 ,进程打开文件, OS为文件创建struct file 和文件描述符表 ,将进程与打开的文件相连, struct file 内还函数有指针表, 屏蔽了底层操作的差异,struct file中还有内核级…...
一篇博客搞定时间复杂度
时间复杂度 1、什么是时间复杂度?2、推导大O的规则3、时间复杂度的计算3.1 基础题 13.2 基础题 23.3基础题 33.4进阶题 13.5进阶题 23.6 偏难题 13.7偏难题 2(递归) 前言: 算法在编写成可执行程序后,运行时要耗费时间和…...
微信小程序实现根据不同的用户角色显示不同的tabbar并且可以完整的切换tabbar
直接上图上代码吧 // login/login.js const app getApp() Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad(options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示*/onShow() {},/*** 生命周期函…...
S_on@atwk的意思
S_onatwk 可能是某种自动化或控制系统中的符号或标记,尤其在PLC(可编程逻辑控制器)编程中,类似的表达方式通常用于表示特定的信号、状态或操作。 我们可以分析这个表达式的各个部分: S_on:通常࿰…...
Liunx启动kafka并解决kafka时不时挂掉的问题
kafka启动步骤 先启动zookeeper,启动命令如下 nohup ./zookeeper-server-start.sh /home/kafka/kafka/config/zookeeper.properties > /home/kafka/kafka/zookeeper.log 2>&1 &再启动kafka,启动命令如下 nohup ./kafka-server-start.sh…...
16 | 实现简洁架构的 Store 层
提示: 所有体系课见专栏:Go 项目开发极速入门实战课;欢迎加入 云原生 AI 实战 星球,12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力(聚焦于 Go、云原生、AI Infra);本节课最终…...
华为hcia——Datacom实验指南——以太网帧和IPV4数据包格式(一)
实验开始 第一步配置环境 第二步配置客户端 如图所示,我们把客户端的ip配置成192.168.1.10,网关设为192.168.1.1 第三步配置交换机1 system-view sysname LSW1 vlan batch 10 interface ethernet0/0/1 port link-type access port default vlan 10 qu…...
ubuntu软件——视频、截图、图片、菜单自定义等
视频软件,大部分的编码都能适应 sudo apt install vlc图片软件 sudo apt install gwenview截图软件 sudo apt install flameshot设置快捷键 flameshot flameshot gui -p /home/cyun/Pictures/flameshot也就是把它保存到一个自定义的路径 菜单更换 sudo apt r…...
CSS中z-index使用详情
定位层级 1.定位元素的显示层级比普通元素高,无论什么定位,显示层级都是一样的; 2.如果位置发生重叠,默认情况是:后面的元素,会显示在前面元素之上; 3.可以通过CSS属性z-index调整元素的显示层级; 4.z-index的属性值是数字,没有单位,值越大显示层级越高; 5.只有定位的元素…...
qt 自带虚拟键盘的编译使用记录
一、windows 下编译 使用vs 命令窗口,分别执行: qmake CONFIG"lang-en_GB lang-zh_CN" nmake nmake install 如果事先没有 指定需要使用的输入法语言就进行过编译,则需要先 执行 nmake distclean 清理后执行 qmake 才能生效。 …...
杨辉三角形(信息学奥赛一本通-2043)
【题目描述】 例5.11 打印杨辉三角形的前n(2≤n≤20)行。杨辉三角形如下图: 当n5时 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 输出: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 【输入】 输入行数n。 【输出】 输出如题述三角形。n行&#…...
CentOS 7 系统上安装 SQLite
1. 检查系统更新 在安装新软件之前,建议先更新系统的软件包列表,以确保使用的是最新的软件源和补丁。打开终端,执行以下命令: sudo yum update -y -y 选项表示在更新过程中自动回答 “yes”,避免手动确认。 2. 安装 …...
程序化广告行业(13/89):DSP的深入解析与运营要点
程序化广告行业(13/89):DSP的深入解析与运营要点 大家好!一直以来,我都对程序化广告行业保持着浓厚的学习兴趣,在探索的过程中积累了不少心得。今天就想把这些知识分享出来,和大家一起学习进步…...
使用 Doris 和 LakeSoul
作为一种全新的开放式的数据管理架构,湖仓一体(Data Lakehouse)融合了数据仓库的高性能、实时性以及数据湖的低成本、灵活性等优势,帮助用户更加便捷地满足各种数据处理分析的需求,在企业的大数据体系中已经得到越来越…...
datax源码分析
文章目录 前言一、加载配置文件二、根据加载的配置文件进行调度三、根据配置文件执行读取写入任务总结 前言 在上一篇文章当中我们已经了解了datax的启动原理,以及datax的最基础的配置,datax底层java启动类的入口及关键参数。 接下来我将进行启动类执行…...
【HDLbits--分支预测器简单实现】
HDLbits--分支预测器简单实现 1 timer2.branche predicitors3.Branch history shift4.Branch direction predictor 以下是分支预测器的简单其实现; 1 timer 实现一个计时器,当load1’b1时,加载data进去,当load1’b0时进行倒计时&…...
优化Go错误码管理:构建清晰、优雅的HTTP和gRPC错误码规范
在系统开发过程中,如何优雅地管理错误信息一直是个棘手问题。传统的错误处理方式往往存在不统一、难以维护等缺点。而 errcode 模块通过对错误码进行规范化管理,为系统级和业务级错误提供了统一的编码标准。本文将带您深入了解 errcode 的设计原理、错误…...
批量压缩与优化 Excel 文档,减少 Excel 文档大小
当我们在 Excel 文档中插入图片资源的时候,如果我们插入的是原图,可能会导致 Excel 变得非常的大。这非常不利于我们传输或者共享。那么当我们的 Excel 文件非常大的时候,我们就需要对文档做一些压缩或者优化的处理。那有没有什么方法可以实现…...
MongoDB分页实现方式对比:PageRequest vs Skip/Limit
MongoDB分页实现方式对比:PageRequest vs Skip/Limit 一、基本概念1.1 PageRequest分页1.2 Skip/Limit分页 二、主要区别2.1 使用方式2.2 参数计算2.3 适用场景PageRequest适用场景:Skip/Limit适用场景: 三、性能考虑3.1 PageRequest的性能特…...
SAP Commerce(Hybris)营销模块(一):商城产品折扣配置
基于Hybris的Backoffice后台管理系统,创建一个基于模板的营销规则,并配置上对应的优惠活动。 架构设计 先从一张架构图说起 Hybris的促销模块,是基于Promotion引擎来实现的,可以通过Backoffice来进行配置。 通过上面的架构图又可…...
如何在 React 中实现错误边界?
在 React 中实现错误边界 错误边界是 React 提供的一种机制,用于捕获子组件树中的 JavaScript 错误,并展示回退 UI。它可以帮助开发者更好地处理错误,提升用户体验。本文将详细介绍如何在 React 中实现错误边界,包括其工作原理、…...
从头开始开发基于虹软SDK的人脸识别考勤系统(python+RTSP开源)(五)完整源码已上传!
本篇是对照之前代码剩余的部分代码做补充,分享给大家,便于对照运行测试。 完整版的全功能单文件版本已上传!https://download.csdn.net/download/xiaomage_cn/90484179 人脸识别抽象层,这个大家应该都知道,就是为了方…...
PySide(PyQT)的mouseMoveEvent()和hoverMoveEvent()的区别
在 PySide中,mouseMoveEvent 和 hoverMoveEvent 都是用于处理鼠标移动相关操作的事件,但它们之间存在明显的区别: 事件触发条件 • mouseMoveEvent: 当鼠标在对应的图形项(如 QGraphicsPixmapItem)…...
【通缩螺旋的深度解析与科技破局路径】
通缩螺旋的深度解析与科技破局路径 一、通缩螺旋的形成机制与恶性循环 通缩螺旋(Deflationary Spiral)是经济学中描述价格持续下跌与经济衰退相互强化的动态过程,其核心逻辑可拆解为以下链条: 需求端萎缩:居民消费信…...
【如何使用云服务器与API搭建专属聊天系统:宝塔面板 + Openwebui 完整教程】
文章目录 不挑电脑、不用技术,云服务器 API 轻松搭建专属聊天系统,对接 200 模型,数据全在自己服务器,安全超高一、前置准备:3 分钟快速上手指南云服务器准备相关账号注册 二、手把手部署教程(含代码块&a…...
Oracle数据库存储结构--逻辑存储结构
数据库存储结构:分为物理存储结构和逻辑存储结构。 物理存储结构:操作系统层面如何组织和管理数据 逻辑存储结构:Oracle数据库内部数据组织和管理数据,数据库管理系统层面如何组织和管理数据 Oracle逻辑存储结构 数据库的逻…...
C++ 左值(lvalue)和右值(rvalue)
在 C 中,左值(lvalue)和右值(rvalue)是指对象的不同类别,区分它们对于理解 C 中的表达式求值和资源管理非常重要,尤其在现代 C 中涉及到移动语义(Move Semantics)和完美转…...
《实战AI智能体》DeepSearcher 的架构设计
DeepSearcher 的架构设计 一个通往搜索AGI的Agentic RAG应该如何设计? 从架构上看,DeepSearcher 主要分为两大模块。 一个是数据接入模块,通过Milvus向量数据库来接入各种第三方的私有知识。这也是DeepSearcher相比OpenAI的原本DeepResearc…...
Kotlin 继承
Kotlin 继承 概述 Kotlin 是一种现代的编程语言,它具有简洁、安全、互操作性等特点。在面向对象编程中,继承是一种非常重要的特性,它允许我们创建具有共同属性和方法的类。本文将详细介绍 Kotlin 中的继承机制,包括继承的基本概…...
【6】树状数组学习笔记
前言 树状数组是我学的第一个高级数据结构,属于 log \log log 级数据结构。 其实现在一般不会单独考察数据结构,主要是其在其他算法(如贪心,DP)中起到优化作用。 长文警告:本文一共 995 995 995 行…...