【opencv】教程代码 —features2D(2)

使用SURF算法检测两幅图关键点后暴力匹配

SURF特征检测

使用SURF(Speeded Up Robust Features)算法来检测两张图像之间的关键点,并使用FLANN(Fast Library for Approximate Nearest Neighbors)基于特征描述符向量进行匹配

图像特征点检测(SURF)、(FLANN)匹配和目标定位

1.feature_description—SURF_matching_Demo.cpp(Debug模式)使用SURF算法检测两幅图关键点后暴力匹配

5d2215a509e099110a897b45e4bcd0a7.png

box.png

9f32be968bf98412e06bc71f3decfee6.png

box_in_scene.png

708d7dfeccbd55a5a67018744f85c2be.png

minHessian=400

1aa3e6c00029a382a651dfb8fde6ed23.png

minHessian=1000

6128a411d9dad7c93dc1218bdddb225f.png

minHessian=10000

911da9be70835cf10d8a2c2ca2e25c1a.png

#include <iostream> // 包含标准输入输出流库
#include "opencv2/core.hpp" // 包括OpenCV的核心功能头文件
#ifdef HAVE_OPENCV_XFEATURES2D // 如果定义了HAVE_OPENCV_XFEATURES2D
#include "opencv2/highgui.hpp" // 包括用户界面相关功能的头文件
#include "opencv2/features2d.hpp" // 包括特征检测相关功能的头文件
#include "opencv2/xfeatures2d.hpp" // 包括特殊特征检测的头文件(非free模块)using namespace cv; // 使用cv命名空间
using namespace cv::xfeatures2d; // 使用cv的xfeatures2d命名空间
using std::cout; // 使用标准库中的cout
using std::endl; // 使用标准库中的endlconst char* keys = // 定义命令行参数"{ help h |                  | Print help message. }""{ input1 | box.png          | Path to input image 1. }""{ input2 | box_in_scene.png | Path to input image 2. }";int main( int argc, char* argv[] ) // 主函数
{CommandLineParser parser( argc, argv, keys ); // 创建命令行解析器Mat img1 = imread( samples::findFile( parser.get<String>("input1") ), IMREAD_GRAYSCALE ); // 读取第一张图片为灰度图Mat img2 = imread( samples::findFile( parser.get<String>("input2") ), IMREAD_GRAYSCALE ); // 读取第二张图片为灰度图if ( img1.empty() || img2.empty() ) // 如果图片读取失败{cout << "Could not open or find the image!\n" << endl; // 打印错误信息parser.printMessage(); // 打印帮助信息return -1; // 返回错误代码}//-- Step 1: Detect the keypoints using SURF Detector, compute the descriptorsint minHessian = 400; // 设置SURF算法的Hessian阈值Ptr<SURF> detector = SURF::create( minHessian ); // 创建SURF特征检测器std::vector<KeyPoint> keypoints1, keypoints2; // 存放两张图片的关键点Mat descriptors1, descriptors2; // 存放两张图片的描述符detector->detectAndCompute( img1, noArray(), keypoints1, descriptors1 ); // 检测并计算img1的关键点和描述符detector->detectAndCompute( img2, noArray(), keypoints2, descriptors2 ); // 检测并计算img2的关键点和描述符//-- Step 2: Matching descriptor vectors with a brute force matcher// Since SURF is a floating-point descriptor NORM_L2 is usedPtr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::BRUTEFORCE); // 创建暴力匹配器std::vector< DMatch > matches; // 存放匹配结果matcher->match( descriptors1, descriptors2, matches ); // 执行匹配//-- Draw matchesMat img_matches; // 存放匹配之后的图片drawMatches( img1, keypoints1, img2, keypoints2, matches, img_matches ); // 绘制匹配结果//-- Show detected matchesimshow("Matches", img_matches ); // 在窗口中显示匹配结果waitKey(); // 等待用户按键return 0; // 程序成功结束
}
#else
int main() // 如果没定义HAVE_OPENCV_XFEATURES2D
{std::cout << "This tutorial code needs the xfeatures2d contrib module to be run." << std::endl; // 提示需要xfeatures2d模块return 0; // 程序结束
}
#endif

这段代码是使用OpenCV库进行图像特征点检测和匹配的示例。它通过SURF算法来检测两幅图片中的特征点,并使用暴力匹配器来找出这些特征点之间的匹配关系。最终将匹配的结果用图形化的方式展示出来。这对于很多计算机视觉任务,比如物体识别、图像拼接等是非常实用的。如果环境中没有安装OpenCV的xfeatures2d模块,则给出提示信息。

e942b242e11c0c6c54a5fa63620bc523.png

2.feature_detection—SURF_detection_Demo.cpp  SURF特征检测

38f480fb07cd90b6c8af1c0da83425bd.png

675595e35ce838102ea85f88c84d6b7b.png

#include <iostream> // 包含输入输出流的头文件
#include "opencv2/core.hpp" // 包含OpenCV核心功能的头文件
#ifdef HAVE_OPENCV_XFEATURES2D
#include "opencv2/highgui.hpp" // 包含OpenCV GUI功能的头文件
#include "opencv2/features2d.hpp" // 包含OpenCV特征检测相关功能的头文件
#include "opencv2/xfeatures2d.hpp" // 包含OpenCV extra features2d模块的头文件,例如SURFusing namespace cv; // 使用cv命名空间
using namespace cv::xfeatures2d; // 使用cv::xfeatures2d命名空间,因为SURF是其中的一部分
using std::cout; // 使用标准命名空间下的cout
using std::endl; // 使用标准命名空间下的endlint main( int argc, char* argv[] )
{CommandLineParser parser( argc, argv, "{@input | box.png | input image}" ); // 命令行参数解析器Mat src = imread( samples::findFile( parser.get<String>( "@input" ) ), IMREAD_GRAYSCALE ); // 读取图像文件转换为灰度图if ( src.empty() ){cout << "Could not open or find the image!\n" << endl;cout << "Usage: " << argv[0] << " <Input image>" << endl;return -1;}//-- Step 1: Detect the keypoints using SURF Detector// 步骤1:使用SURF检测器检测关键点int minHessian = 400; // Hessian算子的阈值Ptr<SURF> detector = SURF::create( minHessian ); // 创建SURF检测器std::vector<KeyPoint> keypoints; // 关键点的向量detector->detect( src, keypoints ); // 检测关键点//-- Draw keypoints// 绘制关键点Mat img_keypoints;drawKeypoints( src, keypoints, img_keypoints ); // 将检测到的关键点绘制到图上//-- Show detected (drawn) keypoints// 显示检测到(绘制的)关键点imshow("SURF Keypoints", img_keypoints ); // 创建一个窗口展示关键点waitKey(); // 等待任意键输入return 0;
}
#else
int main()
{std::cout << "This tutorial code needs the xfeatures2d contrib module to be run." << std::endl;return 0;
}
#endif

这段代码的功能是使用SURF算法来检测图像中的关键点。首先,它使用命令行参数解析器读取图像,并将其转换为灰度图。如果无法读取图像,它会打印错误消息并退出程序。如果图像读取成功,它创建一个SURF检测器,并根据指定的Hessian阈值来检测图像中的关键点。然后,它将这些关键点绘制在源图像上,并使用imshow函数显示结果。如果没有安装OpenCV的xfeatures2d类的附加模块,它会在命令行输出一条信息,说明需要xfeatures2d模块才能运行此代码。

3. SURF_FLANN_matching_Demo.cpp 使用SURF(Speeded Up Robust Features)算法来检测两张图像之间的关键点,并使用FLANN(Fast Library for Approximate Nearest Neighbors)基于特征描述符向量进行匹配

480c3931209ad1feb76836ec477641c5.png

0a0f8d0416a367929207b2d446b11162.png

#include <iostream>  // 包含标准输入输出流库
#include "opencv2/core.hpp" // 包含OpenCV核心功能库#ifdef HAVE_OPENCV_XFEATURES2D // 如果定义了HAVE_OPENCV_XFEATURES2D(检查xfeatures2d模块是否可用)
#include "opencv2/highgui.hpp" // 包含OpenCV高级GUI库
#include "opencv2/features2d.hpp" // 包含OpenCV特征点检测库
#include "opencv2/xfeatures2d.hpp" // 包含OpenCV附加特征点检测库using namespace cv;  // 使用cv命名空间
using namespace cv::xfeatures2d; // 使用cv::xfeatures2d命名空间
using std::cout;  // 使用cout(标准输出)
using std::endl;  // 使用endl(换行符)const char* keys =  // 定义命令行参数"{ help h |                  | Print help message. }"  // 帮助信息"{ input1 | box.png          | Path to input image 1. }"  // 输入图像1的路径"{ input2 | box_in_scene.png | Path to input image 2. }";  // 输入图像2的路径int main( int argc, char* argv[] )  // 主函数
{CommandLineParser parser( argc, argv, keys ); // 命令行解析器Mat img1 = imread( samples::findFile( parser.get<String>("input1") ), IMREAD_GRAYSCALE ); // 读取输入图像1为灰度图Mat img2 = imread( samples::findFile( parser.get<String>("input2") ), IMREAD_GRAYSCALE ); // 读取输入图像2为灰度图if ( img1.empty() || img2.empty() ) // 如果任一图像为空则打印错误信息{cout << "Could not open or find the image!\n" << endl;parser.printMessage(); // 打印帮助信息return -1; // 返回-1表示错误}//-- Step 1: Detect the keypoints using SURF Detector, compute the descriptorsint minHessian = 400; // 定义Hessian阈值Ptr<SURF> detector = SURF::create( minHessian ); // 创建SURF检测器std::vector<KeyPoint> keypoints1, keypoints2;  // 定义关键点向量Mat descriptors1, descriptors2;  // 定义描述符矩阵detector->detectAndCompute( img1, noArray(), keypoints1, descriptors1 ); // 检测图像1的关键点和描述符detector->detectAndCompute( img2, noArray(), keypoints2, descriptors2 ); // 检测图像2的关键点和描述符//-- Step 2: Matching descriptor vectors with a FLANN based matcher// Since SURF is a floating-point descriptor NORM_L2 is usedPtr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::FLANNBASED); // 创建基于FLANN的描述符匹配器std::vector< std::vector<DMatch> > knn_matches;  // 定义K邻近匹配向量matcher->knnMatch( descriptors1, descriptors2, knn_matches, 2 ); // 执行K邻近匹配//-- Filter matches using the Lowe's ratio testconst float ratio_thresh = 0.7f;  // 定义Lowe's比率测试阈值std::vector<DMatch> good_matches;  // 定义良好匹配向量for (size_t i = 0; i < knn_matches.size(); i++) // 遍历所有K邻近匹配{if (knn_matches[i][0].distance < ratio_thresh * knn_matches[i][1].distance) // 如果满足Lowe's比率测试则认为是良好匹配{good_matches.push_back(knn_matches[i][0]); // 添加到良好匹配向量中}}//-- Draw matchesMat 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 ); // 绘制良好匹配//-- Show detected matchesimshow("Good Matches", img_matches ); // 显示匹配结果图像waitKey();  // 等待按键事件return 0;  // 返回0表示成功
}
#else // 如果没有定义HAVE_OPENCV_XFEATURES2D
int main()  // 主函数
{std::cout << "This tutorial code needs the xfeatures2d contrib module to be run." << std::endl; // 打印错误信息return 0;  // 返回0表示成功
}
#endif

这段代码是一个使用OpenCV库进行图像处理的例子,特别是使用SURF(Speeded Up Robust Features)算法来检测两张图像之间的关键点,并使用FLANN(Fast Library for Approximate Nearest Neighbors)基于特征描述符向量进行匹配。首先,代码读取两张图像并将它们转换成灰度图。然后,SURF算法被用于检测关键点并计算描述符。接着,运用FLANN匹配器对这两组描述符进行匹配,并使用Lowe's比率测试过滤出良好的匹配点。最后,良好的匹配点被绘制并显示出来。如果没有安装OpenCV的xfeatures2d模块,代码将打印一条错误信息。

drawMatches( img1, keypoints1, img2, keypoints2, good_matches, img_matches, Scalar::all(-1),Scalar::all(-1), std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

b92e36a6a9d798c224c32e1b961df1b8.png

4.SURF_FLANN_matching_homography_Demo.cpp  图像特征点检测、匹配和目标定

c98a4988f0e8f4f163e525aeab49f4ff.png

8e6ebca54694c0c80c69eb93adc6ffb6.png

// 引用必要的库
#include <iostream>
#include "opencv2/core.hpp"
#ifdef HAVE_OPENCV_XFEATURES2D // 判断是否有xfeatures2d模块,如果有则进行下面的操作
#include "opencv2/calib3d.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/xfeatures2d.hpp"// 使用命名空间简化代码
using namespace cv;
using namespace cv::xfeatures2d;
using std::cout;
using std::endl;// 定义程序参数
const char* keys ="{ help h |                  | 打印帮助信息}""{ input1 | box.png          | 第一张输入图像路径}""{ input2 | box_in_scene.png | 第二张输入图像路径}";// 程序主函数
int main( int argc, char* argv[] )
{// 定义命令行解析器CommandLineParser parser( argc, argv, keys );// 读取图片Mat img_object = imread( samples::findFile( parser.get<String>("input1") ), IMREAD_GRAYSCALE );Mat img_scene = imread( samples::findFile( parser.get<String>("input2") ), IMREAD_GRAYSCALE );// 判断图片是否读取成功if ( img_object.empty() || img_scene.empty() ){cout << "无法打开或找到图片!\n" << endl;parser.printMessage(); //打印错误信息return -1;}//-- Step 1: 使用SURF检测器检测关键点并计算描述符int minHessian = 400; //设置SURF算法中的hessian阈值Ptr<SURF> detector = SURF::create( minHessian ); // 创建SURF检测器std::vector<KeyPoint> keypoints_object, keypoints_scene; // 定义储存关键点的向量Mat descriptors_object, descriptors_scene; //定义储存描述符的矩阵detector->detectAndCompute( img_object, noArray(), keypoints_object, descriptors_object ); // 在目标图片中检测关键点并计算描述符detector->detectAndCompute( img_scene, noArray(), keypoints_scene, descriptors_scene ); //在场景图片中检测关键点并计算描述符//-- Step 2: 通过FLANN匹配器对描述符向量进行匹配// 由于SURF是一个浮点数描述符,此处使用NORM_L2Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::FLANNBASED);std::vector< std::vector<DMatch> > knn_matches; //定义knn匹配的结果向量matcher->knnMatch( descriptors_object, descriptors_scene, knn_matches, 2 ); //knn匹配//-- Step 3: 利用Lowe's比率测试过滤匹配点const float ratio_thresh = 0.75f;std::vector<DMatch> good_matches; //定义储存优质匹配点的向量for (size_t i = 0; i < knn_matches.size(); i++){if (knn_matches[i][0].distance < ratio_thresh * knn_matches[i][1].distance) //通过比率测试进行筛选{good_matches.push_back(knn_matches[i][0]);}}//-- Step 4: 绘制优质匹配点Mat img_matches;drawMatches( img_object, keypoints_object, img_scene, keypoints_scene, good_matches, img_matches, Scalar::all(-1),Scalar::all(-1), std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );//-- Step 5: 找到场景图片中的目标位置std::vector<Point2f> obj;std::vector<Point2f> scene;for( size_t i = 0; i < good_matches.size(); i++ ){//-- 从优质匹配点中获取关键点obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );}Mat H = findHomography( obj, scene, RANSAC ); //计算单应性矩阵//-- Step 6: 获取目标图片的角点(the object to be "detected")std::vector<Point2f> obj_corners(4);obj_corners[0] = Point2f(0, 0);obj_corners[1] = Point2f( (float)img_object.cols, 0 );obj_corners[2] = Point2f( (float)img_object.cols, (float)img_object.rows );obj_corners[3] = Point2f( 0, (float)img_object.rows );std::vector<Point2f> scene_corners(4);perspectiveTransform( obj_corners, scene_corners, H); //对目标点进行透视投影变换//-- Draw lines between the corners (the mapped object in the scene - image_2 )line( img_matches, scene_corners[0] + Point2f((float)img_object.cols, 0),scene_corners[1] + Point2f((float)img_object.cols, 0), Scalar(0, 255, 0), 4 );line( img_matches, scene_corners[1] + Point2f((float)img_object.cols, 0),scene_corners[2] + Point2f((float)img_object.cols, 0), Scalar( 0, 255, 0), 4 );line( img_matches, scene_corners[2] + Point2f((float)img_object.cols, 0),scene_corners[3] + Point2f((float)img_object.cols, 0), Scalar( 0, 255, 0), 4 );line( img_matches, scene_corners[3] + Point2f((float)img_object.cols, 0),scene_corners[0] + Point2f((float)img_object.cols, 0), Scalar( 0, 255, 0), 4 );//-- Step 7: 展示检测到的匹配imshow("Good Matches & Object detection", img_matches );waitKey(); //等待用户按键return 0;
}
#else
int main()
{std::cout << "这个教程代码需要xfeatures2d contrib模块才能运行." << std::endl;return 0;
}
#endif

以上代码实现了一个物体识别程序,它能从一张场景图像中找到另一张目标图像的位置。首先,通过SURF检测器找到两张图片的关键点和描述符。接着,通过FLANN匹配器找到匹配的点,并通过Lowe's比率测试进行筛选,得到优质的匹配点。最后,根据这些匹配点找到目标图片在场景图片中的位置,并在匹配图上绘制出目标的角点

411cb829841d7dbe767d4a38741aa9d9.png

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows中忘记MySQL ROOT密码的解决方法

在需要ROOT身份登录MySQL但又忘记密码时&#xff0c;可以先已管理员身份运行cmd命令窗口,输入以下命令停止MySQL服务 net stop mysql 随后cd到MySQL安装目录下的bin目录下 D: //我的安装在D盘 cd D:\MySQL\bin 使用跳过权限验证的方式起启动MySQL mysqld --console --skip-g…

跨境电商IP防关联是什么?有什么作用?

做跨境电商的朋友应该都知道IP防关联这个词,那么为何IP需要防关联呢&#xff1f;今天为大家来解答这个问题。 跨境电商IP防关联是指在跨境电商运营中&#xff0c;通过采取一系列技术手段&#xff0c;确保每个跨境电商账号使用独立的IP地址&#xff0c;以避免账号之间因为IP地址…

搜索与图论——Kruskal算法求最小生成树

kruskal算法相比prim算法思路简单&#xff0c;不用处理边界问题&#xff0c;不用堆优化&#xff0c;所以一般稀疏图都用Kruskal。 Kruskal算法时间复杂度O(mlogm) 每条边存结构体里&#xff0c;排序需要在结构体里重载小于号 判断a&#xff0c;b点是否连通以及将点假如集合中…

Linux重点思考(下)--shell脚本使用以及内核开发

Linux重点思考(下&#xff09;--shell脚本使用和组合拳 shell脚本的基础算法shell脚本写123...n的值&#xff0c;说思路Shell 脚本用于执行服务器性能测试的死循环Shell 脚本备份和定时清理垃圾文件 shell脚本的内核开发正向映射反向映射 shell脚本的基础算法 shell脚本写123……

link 样式表是否会阻塞页面内容的展示?取决于浏览器,edge 和 chrome 会,但 firefox 不会。

经过实测&#xff1a; 在 head 中 link 一个 1M 大小的样式表。设置网络下载时间大概为 10 秒。 edge 和 chrome 只有在下载完样式表后&#xff0c;页面上才会出现内容。而 firefox 可以直接先显示内容&#xff0c;然后等待样式表下载完成后再应用样式。 DOMContentLoaded 事…

vue系统——v-html

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>v-html指令</title> </head> <body&…

OSPF基本原理和概念

文章目录 背景知识OSPF协议概述&#xff1a;OSPF区域的表示OSPF 骨干区域 –区域0OSPF 非骨干区域 -非0区域OSPF的五种区域类型OSPF工作原理OSPF 的报文类型OSPF邻居表中的七个状态 总结 背景知识 一台路由设备如何获取其他网段的路由&#xff0c;并加入到路由表中 直连路由 …

虚拟机 centos 安装后与主机 ip保持一致

1、安装时 网络模式 悬着自动检测 &#xff08;桥接&#xff09; 2、打开网络 这里如果没有打开 就去 编辑 该文件。把ONBOOTno 改为yes 后 vim /etc/sysconfig/network-scripts/ifcfg-ens160 刷新配置 systemctl restart network 再查看addr 与本机 192.168.31.xx 在同…

Java23种常见设计模式汇总

七大原则网站地址&#xff1a;设计模式7大原则&#xff0b;类图关系-CSDN博客 创建型设计模式&#xff1a;创建型设计模式合集-CSDN博客 七大结构型设计模式&#xff1a;7大结构型设计模式-CSDN博客 11种行为型设计模式&#xff1a; 11种行为型模式&#xff08;上&#xff0…

设计模式之装饰模式精讲

概念&#xff1a;动态地给一个对象添加一些额外的职责。 装饰器模式侧重于在不改变接口的前提下动态地给对象添加新功能&#xff0c;保持对象结构的透明性&#xff0c;客户端无感知。 以一个咖啡制作和装饰的例子来帮助大家理解&#xff1a; public interface Coffee {double…

基于单片机GPS轨迹定位和里程统计系统

**单片机设计介绍&#xff0c;基于单片机GPS轨迹定位和里程统计系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机GPS轨迹定位和里程统计系统是一个集成了GPS定位技术、单片机控制以及里程统计功能的综合性系统。该系…

五、postman基础使用案例

postman基础使用 相关案例【传递查询参数】【提交表单数据】【提交JSON数据】 注&#xff1a;postman⼀款⽀持调试和测试的⼯具&#xff0c;开发、测试⼯程师都可以使⽤。方法一般统一为&#xff1a;方法→请求头→请求体→断言 相关案例 【传递查询参数】 访问TPshop搜索商品的…

EXCEL 通过FILES函数获取指定路径中的所有文件名

FILES函数 用途 获取指定文件路径中的所有文件名。 语法 FILES(“路径\*.*”)指定从哪个路径下返回一个文件名。 *.*是通配符&#xff0c;代表所有类型的文件&#xff0c;第一个*是文件名的通配符&#xff0c;第二个* 是文件的后缀名&#xff0c;表示文件类型&#xff0c;如…

【详解】运算放大器工作原理及其在信号处理中的核心作用

什么是运算放大器 运算放大器&#xff08;简称“运放”&#xff09;是一种放大倍数非常高的电路单元。在实际电路中&#xff0c;它常常与反馈网络一起组成一定的功能模块。它是一种带有特殊耦合电路和反馈的放大器。输出信号可以是输入信号的加法、减法、微分和积分等数学运算…

【C#】知识点速通

前言&#xff1a; 笔者是跟着哔站课程&#xff08;Trigger&#xff09;学习unity才去学习的C#&#xff0c;并且C语言功底尚存&#xff0c;所以只是简单地跟着课程将unity所用的C#语言的关键部分进行了了解&#xff0c;然后在后期unity学习过程中加以深度学习。如需完善的C#知识…

什么是nginx正向代理和反向代理?

什么是代理&#xff1f; 代理(Proxy), 简单理解就是自己做不了的事情或实现不了的功能&#xff0c;委托别人去做。 什么是正向代理&#xff1f; 在nginx中&#xff0c;正向代理指委托者是客户端&#xff0c;即被代理的对象是客户端 在这幅图中&#xff0c;由于左边内网中…

深入浅出Java中高效的ConcurrentLinkedQueue队列底层实现与源码分析

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

.NET CORE使用Redis分布式锁续命(续期)问题

结合上一期 .NET CORE 分布式事务(三) DTM实现Saga及高并发下的解决方案(.NET CORE 分布式事务(三) DTM实现Saga及高并发下的解决方案-CSDN博客)。有的小伙伴私信说如果锁内锁定的程序或者资源未在上锁时间内执行完&#xff0c;造成的使用资源冲突&#xff0c;需要如何解决。本…

【STM32 HAL库SPI/QSPI协议学习,基于外部Flash读取。】

1、SPI协议 简介 SPI 协议是由摩托罗拉公司提出的通讯协议 (Serial Peripheral Interface)&#xff0c;即串行外围设备接口&#xff0c;是 一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间&#xff0c;要求通讯速率 较高的场合。 SPI 物理层 SPI 通讯…

优化选址问题 | 基于帝国企鹅算法求解工厂-中心-需求点三级选址问题含Matlab源码

目录 问题代码问题 "帝国企鹅算法"并不是一个广为人知的优化算法,可能是一个特定领域或者特定情境下提出的方法。不过,对于工厂-中心-需求点三级选址问题,它可能是一种启发式优化方法,用于在多个候选位置中选择最优的工厂、中心和需求点位置。 这类问题通常涉及…