OpenCV开发笔记(七十七):相机标定(二):通过棋盘标定计算相机内参矩阵矫正畸变摄像头图像

若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/136616551
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)

OpenCV开发专栏(点击传送门)

上一篇:《OpenCV开发笔记(七十六):相机标定(一):识别棋盘并绘制角点》
下一篇:持续补充中…


前言

  通过相机图片可以识别出棋盘角点了,这时候我们需要通过角点去计算相机内参矩阵,通过上篇得知畸变的原理,所以我们尽可能要全方位都能获取标定图片,全方位意思是提供的多张图综合起来基本覆盖了相机所有的像素,同时还要注意远近和斜着
  本篇通过一张图片来识别计算得到相机内参矩阵,并矫正相机畸形。


补充

  做项目一定要多张且基本覆盖相机所有区域,要保证每一张截取的图片也要被识别,可以做成个软件,识别出棋盘都在一个预先指定的区域内则截图,然后下一个区域,实现半自动半人工化标定。


Demo

  在这里插入图片描述

  这里只用了一张图校准,所以可能内参矩阵经度不那么高:
   在这里插入图片描述


一张图校准的实例

   注意:这里demo只使用了可识别的一张图作为计算,可能没覆盖的区域则出现不可预期的图像问题。

步骤一:世界坐标系初始化

   这里是直接填充行列的坐标,第三个是z坐标直接设置为0,为视口处:

// 步骤八:角点对应的三维坐标(一张图一组)
std::vector<std::vector<cv::Point3f>> vectorObjectPoint;
std::vector<cv::Point3f> objectPoints;  // 三维世界坐标系
for(int i = 0; i < chessboardRowCornerCount; i++)
{for(int j = 0; j < chessboardColCornerCount; j++){objectPoints.push_back(cv::Point3f(j, i, 0));}
}
vectorObjectPoint.push_back(objectPoints);

步骤二:识别的角点放入列表

   多张图放入多次,这里只有一张图:

// 步骤九:图像识别出来的角点(一张图一组)
std::vector<std::vector<cv::Point2f>> vectorImagePoint;
vectorImagePoint.push_back(vectorPoint2fCorners);

步骤三:计算内参和畸变系数

   输出的参数有点多,输入的参数却不多:

// 步骤十:计算内参和畸变系数
cv::Mat cameraMatrix;                   // 相机矩阵(接收输出)
cv::Mat distCoeffs;                     // 畸变系数(接收输出)
cv::Mat Rotate;                         // 旋转量(接收输出)
cv::Mat Translate;                      // 偏移量(接收输出)
cv::calibrateCamera(vectorObjectPoint,vectorImagePoint,grayMat.size(),cameraMatrix,distCoeffs,Rotate,Translate);
std::cout << "cameraMatrix:" << std::endl;
std::cout << cameraMatrix << std::endl;std::cout << "distCoeffs:" << std::endl;
std::cout << distCoeffs << std::endl;std::cout << "Rotate:" << std::endl;
std::cout << Rotate << std::endl;std::cout << "Translate:" << std::endl;
std::cout << Translate << std::endl;

步骤四:畸变函数校准

   这里校准相对容易,所以难点在于标定校准,做项目肯定要自己写一个标定软件了,每次这么手动查看校准肯定不行的。

// 步骤十一:畸变图像校准
cv::Mat dstMat;
cv::undistort(srcMat, dstMat, cameraMatrix, distCoeffs);
cv::imshow("6", dstMat);

函数原型

calibrateCamera:相机标定求解函数

   OpenCV中的一个函数,用于相机标定。相机标定是估计相机内参(如焦距、主点坐标等)和畸变系数的过程,这些参数对于后续的图像处理任务(如三维重建、目标跟踪等)至关重要。

double calibrateCamera(InputArrayOfArrays objectPoints,  InputArrayOfArrays imagePoints,  Size imageSize,  OutputArray cameraMatrix,  OutputArray distCoeffs,  OutputArray rvecs,  OutputArray tvecs,  int flags=0,  TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 1e-6));

   参数说明:

  • objectPoints:世界坐标系中的三维点。通常,这些点是通过在标定板上定义的一系列点来获取的,这些点的坐标是已知的。对于每个图像,它应该是一个 Nx3 的数组(或数组列表),其中 N 是点的数量,而 3 表示每个点的 (X, Y, Z) 坐标。
  • imagePoints:图像坐标系中的二维点,即对应于 objectPoints 中的三维点在图像中的投影。对于每个图像,它应该是一个 Nx2 的数组(或数组列表),其中 N 是点的数量,而 2 表示每个点的 (x, y) 坐标。
  • imageSize:图像的大小,表示为 Size 类型的对象,包含图像的宽度和高度。
  • cameraMatrix:输出参数,存储 3x3 的相机内参矩阵。
  • distCoeffs:输出参数,存储畸变系数。通常有 5 个系数(k1, k2, p1, p2, k3)对于径向和切向畸变,或 8 个系数(k1, k2, k3, k4, k5, k6, p1, p2)对于鱼眼相机模型。
  • rvecs:输出参数,对于每个图像,存储旋转向量的数组。
  • tvecs:输出参数,对于每个图像,存储平移向量的数组。
  • flags:不同标志的组合,用于指定标定过程中使用的算法。
    CV_CALIB_USE_INTRINSIC_GUESS:使用该参数时,将包含有效的fx,fy,cx,cy的估计值的内参矩阵cameraMatrix,作为初始值输入,然后函数对其做进一步优化。如果不使用这个参数,用图像的中心点初始化光轴点坐标(cx, cy),使用最小二乘估算出fx,fy(这种求法好像和张正友的论文不一样,不知道为何要这样处理)。注意,如果已知内部参数(内参矩阵和畸变系数),就不需要使用这个函数来估计外参,可以使用solvepnp()函数计算外参数矩阵。
    CV_CALIB_FIX_PRINCIPAL_POINT:在进行优化时会固定光轴点,光轴点将保持为图像的中心点。当CV_CALIB_USE_INTRINSIC_GUESS参数被设置,保持为输入的值。
    CV_CALIB_FIX_ASPECT_RATIO:固定fx/fy的比值,只将fy作为可变量,进行优化计算。当 CV_CALIB_USE_INTRINSIC_GUESS没有被设置,fx和fy的实际输入值将会被忽略,只有fx/fy的比值被计算和使用。
    CV_CALIB_ZERO_TANGENT_DIST:切向畸变系数(P1,P2)被设置为零并保持为零。
    CV_CALIB_FIX_K1,…,CV_CALIB_FIX_K6:对应的径向畸变系数在优化中保持不变。如果设置了CV_CALIB_USE_INTRINSIC_GUESS参数,就从提供的畸变系数矩阵中得到。否则,设置为0。
    CV_CALIB_RATIONAL_MODEL(理想模型):启用畸变k4,k5,k6三个畸变参数。使标定函数使用有理模型,返回8个系数。如果没有设置,则只计算其它5个畸变参数。
    CALIB_THIN_PRISM_MODEL (薄棱镜畸变模型):启用畸变系数S1、S2、S3和S4。使标定函数使用薄棱柱模型并返回12个系数。如果不设置标志,则函数计算并返回只有5个失真系数。
    CALIB_FIX_S1_S2_S3_S4 :优化过程中不改变薄棱镜畸变系数S1、S2、S3、S4。如果cv_calib_use_intrinsic_guess设置,使用提供的畸变系数矩阵中的值。否则,设置为0。
    CALIB_TILTED_MODEL (倾斜模型):启用畸变系数tauX and tauY。标定函数使用倾斜传感器模型并返回14个系数。如果不设置标志,则函数计算并返回只有5个失真系数。
    CALIB_FIX_TAUX_TAUY :在优化过程中,倾斜传感器模型的系数不被改变。如果cv_calib_use_intrinsic_guess设置,从提供的畸变系数矩阵中得到。否则,设置为0。
  • criteria:迭代优化的终止条件。通常包含最大迭代次数和收敛的精度。

   这个函数返回一个双精度浮点数,表示重投影误差的估计值,即实际图像点与通过相机参数和畸变系数计算出的图像点之间的平均误差。
   为了获得准确的相机标定结果,通常需要多个视图(即多张不同角度和姿态拍摄的标定板图像),**并确保标定板在不同图像中占据足够的视场。**此外,图像应该清晰,且标定板上的特征点(如棋盘格的角点)应准确检测。

initUndistortRectifyMap:计算畸变参数

   OpenCV中用于初始化用于图像去畸变和校正的映射表的函数。这个函数的目的是生成两个映射,一个用于x坐标,另一个用于y坐标,它们可以被用于 remap函数来校正图像的畸变。

void initUndistortRectifyMap(InputArray cameraMatrix, InputArray distCoeffs, InputArray R, InputArray newCameraMatrix, Size size, int m1type, OutputArray map1, OutputArray map2)

   参数说明

  • cameraMatrix:相机的内参矩阵,一个3x3的浮点数矩阵。
  • distCoeffs:畸变系数,一个1x5或1x8的向量,包含径向和切向畸变系数。
  • R:可选的旋转矩阵,一个3x3的浮点数矩阵,表示从原相机坐标系到新的相机坐标系的旋转。如果这个参数是空的,那么newCameraMatrix必须是cameraMatrix。
  • newCameraMatrix:新的相机内参矩阵,一个3x3的浮点数矩阵。这个矩阵可以是原始相机矩阵,或者经过getOptimalNewCameraMatrix调整后的矩阵,以考虑图像的有效视场。
  • size:输出映射的尺寸,表示为Size类型的对象,包含图像的宽度和高度。
  • m1type:输出映射的类型,可以是CV_32FC1或CV_16SC2。
  • map1:输出的第一个映射,用于x坐标,可以被传递给remap函数。
  • map2:输出的第二个映射,用于y坐标,可以被传递给remap函数。

   这两个映射map1和map2可以被传递给remap函数,以对图像进行去畸变和校正。
   如果有一个畸变的图像distortedImage和想要得到校正后的图像undistortedImage,可以这样使用这两个函数:

Mat map1,map2;
initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, size, CV_32FC1, map1, map2);  
remap(distortedImage, undistortedImage, map1, map2, INTER_LINEAR);

   在这个例子中,INTER_LINEAR是插值方法的类型,用于remap函数。其他的插值方法,如INTER_NEAREST、INTER_CUBIC等也可以被使用,具体取决于应用需求。


Demo源码

void OpenCVManager::testCorrectingChessboard()
{
#define TestCorrectingChessboardUseCamera 0
#if !TestCorrectingChessboardUseCamera// 使用图片
//    std::string srcFilePath = "D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/chessboard.png";
//    std::string srcFilePath = "D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/24.jpg";
//    std::string srcFilePath = "D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/27.png";
//    std::string srcFilePath = "D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/28.png";std::string srcFilePath = "D:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/28.jpg";cv::Mat srcMat = cv::imread(srcFilePath);
#else// 使用摄像头cv::VideoCapture capture;// 插入USB摄像头默认为0if(!capture.open(0)){qDebug() << __FILE__ << __LINE__  << "Failed to open camera: 0";}else{qDebug() << __FILE__ << __LINE__  << "Succeed to open camera: 0";}while(true){cv::Mat srcMat;capture >> srcMat;
#endifint chessboardColCornerCount = 6;int chessboardRowCornerCount = 9;
//    int chessboardColCornerCount = 7;
//    int chessboardRowCornerCount = 7;// 步骤一:读取文件
//    cv::imshow("1", srcMat);
//    cv::waitKey(0);
//     步骤二:缩放,太大了缩放下(可省略)cv::resize(srcMat, srcMat, cv::Size(srcMat.cols / 2, srcMat.rows / 2));cv::Mat srcMat2 = srcMat.clone();cv::Mat srcMat3 = srcMat.clone();cv::imshow("2", srcMat);
//    cv::waitKey(0);// 步骤三:灰度化cv::Mat grayMat;cv::cvtColor(srcMat, grayMat, cv::COLOR_BGR2GRAY);cv::imshow("3", grayMat);
//    cv::waitKey(0);// 步骤四:检测角点std::vector<cv::Point2f> vectorPoint2fCorners;bool patternWasFound = false;patternWasFound = cv::findChessboardCorners(grayMat,cv::Size(chessboardColCornerCount, chessboardRowCornerCount),vectorPoint2fCorners,cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_FAST_CHECK | cv::CALIB_CB_NORMALIZE_IMAGE);/*enum { CALIB_CB_ADAPTIVE_THRESH = 1,    // 使用自适应阈值将图像转化成二值图像CALIB_CB_NORMALIZE_IMAGE = 2,    // 归一化图像灰度系数(用直方图均衡化或者自适应阈值)CALIB_CB_FILTER_QUADS    = 4,    // 在轮廓提取阶段,使用附加条件排除错误的假设CALIB_CB_FAST_CHECK      = 8     // 快速检测};*/cvui::printf(srcMat, 0, 0, 1.0, 0xFF0000, "found = %s", patternWasFound ? "true" : "false");cvui::printf(srcMat, 0, 24, 1.0, 0xFF0000, "count = %d", vectorPoint2fCorners.size());qDebug() << __FILE__ << __LINE__ << vectorPoint2fCorners.size();// 步骤五:绘制棋盘点cv::drawChessboardCorners(srcMat2,cv::Size(chessboardColCornerCount, chessboardRowCornerCount),vectorPoint2fCorners,patternWasFound);
#if TestCorrectingChessboardUseCameracv::imshow("0", srcMat);cv::imshow("4", srcMat2);if(!patternWasFound){cv::imshow("5", srcMat3);cv::waitKey(1);continue;}
#endif// 步骤六:进一步提取亚像素角点cv::TermCriteria criteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER,   // 类型30,                                   // 参数二: 最大次数0.001);                               // 参数三:迭代终止阈值/*#define CV_TERMCRIT_ITER    1                   // 终止条件为: 达到最大迭代次数终止#define CV_TERMCRIT_NUMBER  CV_TERMCRIT_ITER    //#define CV_TERMCRIT_EPS     2                   // 终止条件为: 迭代到阈值终止*/qDebug() << __FILE__ << __LINE__ << vectorPoint2fCorners.size();cv::cornerSubPix(grayMat,vectorPoint2fCorners,cv::Size(5, 5),cv::Size(-1, -1),criteria);// 步骤七:绘制棋盘点cv::drawChessboardCorners(srcMat3,cv::Size(chessboardColCornerCount, chessboardRowCornerCount),vectorPoint2fCorners,patternWasFound);cv::imshow("5", srcMat3);
//    cv::waitKey(0);// 步骤八:角点对应的三维坐标(一张图一组)std::vector<std::vector<cv::Point3f>> vectorObjectPoint;std::vector<cv::Point3f> objectPoints;  // 三维世界坐标系for(int i = 0; i < chessboardRowCornerCount; i++){for(int j = 0; j < chessboardColCornerCount; j++){objectPoints.push_back(cv::Point3f(j, i, 0));}}vectorObjectPoint.push_back(objectPoints);// 步骤九:图像识别出来的角点(一张图一组)std::vector<std::vector<cv::Point2f>> vectorImagePoint;vectorImagePoint.push_back(vectorPoint2fCorners);// 步骤十:计算内参和畸变系数cv::Mat cameraMatrix;                   // 相机矩阵(接收输出)cv::Mat distCoeffs;                     // 畸变系数(接收输出)cv::Mat Rotate;                         // 旋转量(接收输出)cv::Mat Translate;                      // 偏移量(接收输出)cv::calibrateCamera(vectorObjectPoint,vectorImagePoint,grayMat.size(),cameraMatrix,distCoeffs,Rotate,Translate);std::cout << "cameraMatrix:" << std::endl;std::cout << cameraMatrix << std::endl;std::cout << "distCoeffs:" << std::endl;std::cout << distCoeffs << std::endl;std::cout << "Rotate:" << std::endl;std::cout << Rotate << std::endl;std::cout << "Translate:" << std::endl;std::cout << Translate << std::endl;// 步骤十一:畸变图像校准cv::Mat dstMat;cv::undistort(srcMat, dstMat, cameraMatrix, distCoeffs);cv::imshow("6", dstMat);#if TestCorrectingChessboardUseCameracv::waitKey(1);}
//    cv::imshow(_windowTitle.toStdString(), dstMat);
#elsecv::waitKey(0);
#endif
}

对应工程模板v1.68.0

  在这里插入图片描述


入坑

入坑一:无法识别图像

问题

  无法识别。
  在这里插入图片描述

原理

  要全部棋盘视野内,且可以识别,这个确实识别不了。

解决

  换图重新来过(这是笔者随便找的图)。

入坑二:校准之后四角不准

问题

  四角明显不对。
  在这里插入图片描述

原理

  这里需要多张图在能识别的情况下覆盖所有区域。

解决

  先这样,下次实际标定的时候再多张图看是否还存在该问题。


上一篇:《OpenCV开发笔记(七十六):相机标定(一):识别棋盘并绘制角点》
下一篇:持续补充中…


若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/136616551

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

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

相关文章

Visual Studio 2022 配置“Debug|x64”的 Designtime 生成失败。IntelliSense 可能不可用。

今天写代码&#xff0c;无缘无故就给我整个这个错误出来&#xff0c;我一头雾水。 经过我几个小时的奋战&#xff0c;终于解决问题 原因就是这个Q_INTERFACES(&#xff09;宏&#xff0c;我本想使用Q_DECLARE_INTERFACE Q_INTERFACES这两个Qt宏实现不继承QObject也能使用qobjec…

VSCode提交代码

VSCode提交代码方式&#xff1a; 先在电脑本地文件夹中打开git的bash窗口使用git clone https://github.com/xxxx/克隆仓库地址到本地&#xff0c;并生成一个项目的文件夹打开VSCode&#xff0c;点击文件按钮&#xff0c;打开加载项目的文件夹对于VSCode设置Git路径&#xff…

Three 材质纹理 (总结三)

THREE.MeshLambertMaterial&#xff08;网格 Lambert 材质&#xff09; 该材质使用基于非物理的Lambertian模型来计算反射率。可以用来创建暗淡的并不光亮的表面&#xff0c;该材质非常易用&#xff0c;而且会与场景中的光源产生反应。 MeshLambertMaterial属性 # .color : …

蓝桥杯刷题|02入门真题

[蓝桥杯 2022 省 B] 刷题统计 题目描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 a 道题目&#xff0c;周六和周日每天做 b 道题目。请你帮小明计算&#xff0c;按照计划他将在第几天实现做题数大于等于 n 题? 输入格式 输入一行包含三个整数…

Linux之线程互斥

目录 一、问题引入 二、线程互斥 1、相关概念 2、加锁保护 1、静态分配 2、动态分配 3、锁的原理 4、死锁 三、可重入与线程安全 1、概念 2、常见的线程不安全的情况 3、常见的线程安全的情况 4、常见不可重入的情况 5、常见可重入的情况 6、可重入与线程安全联系…

Linux 部署 Samba 服务

一、Ubuntu 部署 Samba 1、安装 Samba # 更新本地软件包列表 sudo apt update# 安装Samba sudo apt install samba# 查看版本 smbd --version2、创建共享文件夹&#xff0c;并配置 Samba 创建需要共享的文件夹&#xff0c;并赋予权限&#xff1a; sudo mkdir /home/test sud…

Kubernetes operator系列:webhook 知识学习【更新中】

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 Kubernetes operator学习 系列文章&#xff0c;本节会对 kubernetes webhook 知识进行学习 本文的所有代码&#xff0c;都存储于github代码库&#xff1a;https://github.com/graham924/share-code-operator-st…

C语言例3-12:自增和自减运算的例子

i 先引用后加1--i 先减1后引用 代码如下&#xff1a; #include<stdio.h> int main(void) {int i2, j2;char c1d, c2D; //d(100) D(68)printf("i %d\n",i); //3, i3printf("j-- %d\n",j--); …

生成式人工智能如何赋能SOC分析师?

以下是已经在全球SOC崭露头角的六大生成式人工智能应用。 在当今网络安全威胁日益严峻的形势下&#xff0c;安全运营中心(SOC)肩负着重大责任。然而&#xff0c;SOC分析师往往人手不足&#xff0c;工作繁重。生成式人工智能(GenAI)的出现为缓解这一困境带来了希望&#xff0c;使…

工具篇--从零开始学Git

一、git概述 1.1版本控制方式 集中式版本控制工具 集中式版本控制工具&#xff0c;版本库是集中存放在中央服务器的&#xff0c; team 里每个人 work 时从中央服务器下载代码&#xff0c;是必须联网才能工作&#xff0c; 局域网或互联网&#xff0c;个人修改之…

IAB视频广告标准《数字视频和有线电视广告格式指南》之 简介、目录及视频配套广告 - 我为什么要翻译介绍美国人工智能科技公司IAB系列(2)

写在前面 谈及到中国企业走入国际市场&#xff0c;拓展海外营销渠道的时候&#xff0c;如果单纯依靠一个小公司去国外做广告&#xff0c;拉渠道&#xff0c;找代理公司&#xff0c;从售前到售后&#xff0c;都是非常不现实的。我们可以回想一下40年前&#xff0c;30年前&#x…

【学习记录】调试千寻服务+DTU+导远RTK过程的记录

最近调试车载定位的时候&#xff0c;遇到了一些问题&#xff0c;千寻服务已经正确配置到RTK里面了&#xff0c;但是导远的定位设备一直显示RTK浮动解&#xff0c;通过千寻服务后台查看状态&#xff0c;长时间显示不合法的GGA值。 首先&#xff0c;通过四处查资料&#xff0c;千…

嵌入式面经-ARM体系架构-计算机基础

嵌入式系统分层 操作系统的作用&#xff1a;向下管理硬件&#xff0c;向上提供接口&#xff08;API&#xff09; 应用开发&#xff1a;使用操作系统提供的接口&#xff08;API&#xff09;&#xff0c;做上层的应用程序开发&#xff0c;基本不用去关内核操作硬件是怎么实现的 …

网络架构层_服务器上下行宽带

网络架构层_服务器上下行宽带 解释一 云服务器ECS网络带宽的概念、计费、安全及使用限制_云服务器 ECS(ECS)-阿里云帮助中心 网络带宽是指在单位时间&#xff08;一般指的是1秒钟&#xff09;内能传输的数据量&#xff0c;带宽数值越大表示传输能力越强&#xff0c;即在单位…

蓝桥杯第十一届电子类单片机组程序设计

目录 前言 单片机资源数据包_2023&#xff08;点击下载&#xff09; 一、第十一届比赛原题 1.比赛题目 2.赛题解读 1&#xff09;计数功能 2&#xff09;连续按下无效按键 二、部分功能实现 1.计数功能的实现 2.连续按下无效按键的处理 3.其他处理 1&#xff09;对于…

SQLiteC/C++接口详细介绍之sqlite3类(八)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;七&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍之sqlite3类&#xff08;八&#xff09;&#xff08;暂未发表&#xff09; 24.sqlite3_cr…

OSCP靶场--BlackGate

OSCP靶场–BlackGate 考点(1.redis rce 2. CVE-2021-4034提权) 1.nmap扫描 ┌──(root㉿kali)-[~/Desktop] └─# nmap -sV -sC -p- 192.168.163.176 --min-rate 2500 Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-14 03:32 EDT Nmap scan report for 192.168.163.…

牛-迈面试题----答案/类似题/知识点

来源在这里 来源在这里 1.Redis的优势 (1) 速度快&#xff0c;因为数据存在内存中&#xff0c;类似于HashMap&#xff0c;HashMap的优势就是查找和操作的时间复杂度都很低 (2)支持丰富数据类型&#xff0c;支持string&#xff0c;list&#xff0c;set&#xff0c;sorted set&…

前端基础篇-深入了解用 HTML 与 CSS 实现标题排版

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 HTML 与 CSS 概述 2.0 HTML - 标题排版 2.1 图片标签 2.2 标题标签 2.3 水平标签 2.4 实现标题排版 3.0 HTML - 标题样式(style 样式) 3.1 CSS 的引入方式 3.2…

《系统架构设计师教程(第2版)》第6章-数据库设计基础知识-04-应用程序与数据库的交互

文章目录 1. 库函数级别访问接口2. 嵌入SQL访问接口2.1 概述2.2 数据库厂商 3. 通用数据接口标准3.1 开放数据库连接 (ODBC)3.2 一些数据库接口1&#xff09;数据库访问对象 (DAO)2&#xff09;远程数据库对象 (RDO)3&#xff09;ActiveX数据对象 (ADO)4&#xff09;Java数据库…