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

news2024/11/17 5:43:12

若该文为原创文章,转载请注明原文出处
本文章博客地址: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摄像头默认为0
    if(!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;
#endif
    int 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 TestCorrectingChessboardUseCamera
    cv::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 TestCorrectingChessboardUseCamera
    cv::waitKey(1);
    }
//    cv::imshow(_windowTitle.toStdString(), dstMat);
#else
    cv::waitKey(0);
#endif
}

对应工程模板v1.68.0

  在这里插入图片描述


入坑

入坑一:无法识别图像

问题

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

原理

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

解决

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

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

问题

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

原理

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

解决

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


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


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

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

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

相关文章

Orange3数据预处理(预处理器组件)

1.组件介绍 Orange3 提供了一系列的数据预处理工具&#xff0c;这些工具可以帮助用户在数据分析之前准备好数据。以下是您请求的预处理组件的详细解释&#xff1a; Discretize Continuous Variables&#xff08;离散化连续变量&#xff09;&#xff1a; 这个组件将连续变量转…

利用Nginx正向代理实现局域网电脑访问外网

引言 在网络环境中&#xff0c;有时候我们需要让局域网内的电脑访问外网&#xff0c;但是由于网络策略或其他原因&#xff0c;直接访问外网是不可行的。这时候&#xff0c;可以借助 Nginx 来搭建一个正向代理服务器&#xff0c;实现局域网内电脑通过 Nginx 转发访问外网的需求…

算法(结合算法图解)

算法简介简单查找二分查找法 选择排序内存的工作原理数组和链表数组选择排序小结 递归小梗 要想学会递归&#xff0c;首先要学会递归。 递归的基线条件和递归条件递归和栈小结 快速排序分而治之快速排序合并排序时间复杂度的平均情况和最糟情况小结 算法简介 算法是一组完成任…

Python3虚拟环境之virtualenv

virtualenv 在开发Python应用程序的时候&#xff0c;系统安装的Python3只有一个版本&#xff1a;3.7。所有第三方的包都会被pip安装到Python3的site-packages目录下。 如果要同时开发多个应用程序&#xff0c;这些应用程序都会共用一个Python&#xff0c;就是安装在系统的Pyt…

【算法】一维前缀和以及二维前缀和

目录 一维前缀和适用场景示例 二维前缀和适用场景一种情况另一种情况示例 一维前缀和 适用场景 求一段区间的和。 比如有一个数列 &#xff1a; 如果我们要求 [l,r]即某个区间内的数组和的时候&#xff0c;思路就是每遍历一个元素就进行求和&#xff0c;记录下加到al时的和…

HYBBS 表白墙网站PHP程序源码,支持封装成APP

PHP表白墙网站源码&#xff0c;适用于校园内或校区间使用&#xff0c;同时支持封装成APP。告别使用QQ空间的表白墙。 简单安装&#xff0c;只需PHP版本5.6以上即可。 通过上传程序进行安装&#xff0c;并设置账号密码&#xff0c;登录后台后切换模板&#xff0c;适配手机和PC…

Java双非大二找实习记录

先说结论&#xff1a;2.22→3.6线上线下面了七家&#xff0c;最后oc两家小公司&#xff0c;接了其中一个。 本人bg&#xff1a; 真名不经传双非一本&#xff0c;无绩点无竞赛无奖项无实习&#xff0c;23年12月开始学java。若非要说一点相关的经历&#xff0c;就是有java基础&…

python-0003-pycharm开发虚拟环境中的项目

前言 在虚拟环境中创建好了python项目&#xff0c;使用pycharm进行开发 打开项目 使用pycharm打开项目 设置虚拟环境的解释器 File–>Settings–>Project(项目名)–>Python Interpreter–>添加解释器–>添加已经存在的解释器–>选择虚拟环境的解释器 …

程序人生——Java开发中通用的方法和准则,Java进阶知识汇总

目录 引出Java开发中通用的方法和准则建议1:不要在常量和变量中出现易混淆的字母建议2:莫让常量蜕变成变量建议3:三元操作符的类型务必一致建议4:避免带有变长参数的方法重载建议5:别让null值和空值威胁到变长方法建议6:覆写变长方法也循规蹈矩建议7:警惕自增的陷阱建议…

linux查看文件内容cat,less,vi,vim

学习记录 目录 catlessvi vim cat 输出 FILE 文件的全部内容 $ cat [OPTION] FILE示例 输出 file.txt 的全部内容 $ cat file.txt查看 file1.txt 与 file2.txt 连接后的内容 $ cat file1.txt file2.txt为什么名字叫 cat&#xff1f; 当然和猫咪没有关系。 cat 这里是 co…

Python 导入Excel三维坐标数据 生成三维曲面地形图(面) 4-2、线条平滑曲面(原始颜色)但不去除无效点

环境和包: 环境 python:python-3.12.0-amd64包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 scipy 1.12.0 代码: import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from scipy.interpolate import griddata fr…

未来城市:数字孪生技术助力智慧城市构建

目录 一、数字孪生技术的兴起与定义 二、数字孪生技术在智慧城市构建中的应用 1、城市规划与管理 2、智慧交通 3、智慧能源 4、智慧环保 三、数字孪生技术助力智慧城市构建的挑战与对策 四、结语 随着科技的飞速发展&#xff0c;未来城市正在经历一场前所未有的变革。数…

Redis 的 key 的过期策略是怎么实现的【经典面试题】

前言 在 Redis 中可以通过命令 expire 对指定的 key 值设置过期时间&#xff0c;在时间到了以后该键值对就会自动删除。 一个 Redis 中可能会存在很多的 key &#xff0c;而这些 key 中有很大的一部分都会有过期时间&#xff0c;那么 Redis 怎么知道哪些 key 已经到了过期时间需…

【C语言】InfiniBand驱动mlx4_register_interface函数

一、讲解 mlx4_register_interface函数是Mellanox InfiniBand驱动程序的一部分&#xff0c;这个函数的作用是注册一个新的接口(intf)到InfiniBand设备。这允许不同的子系统&#xff0c;如以太网或存储&#xff0c;能够在同一个硬件设备上注册它们各自需要的接口&#xff0c;在…

Vue3全家桶 - VueRouter - 【6】导航守卫

导航守卫 查看以下情形&#xff1a; 点击主页链接时&#xff0c;默认情况下可直接进入指定页面&#xff0c;如下图&#xff0c;但是问题是该跳转的界面是需要用户登录后方可访问的&#xff1b; 可设置导航守卫来检测用户是否登录&#xff0c;如果已登录&#xff0c;则进入后台…

解决 Webpack 中 ERROR in main Module not found: Error: Can‘t resolve ‘./src‘ 问题

出自 BV1MN411y7pw&#xff0c; P98 黑马AJAX-Node.js-Webpack教学视频中webpack部分&#xff0c;打包的时候出错 ERROR in main Module not found: Error: Cant resolve ./src in V:\Web\mycode\webpack\01_webpack_use resolve ./src in V:\Web\mycode\webpack\01_webpack_us…

Leetcode30-串联所有单词的子串[三种方法]

文章目录 30. 串联所有单词的子串&#xff08;hard&#xff09;方法一&#xff1a;暴力方法二&#xff1a;滑窗再次优化 小记-map的使用 30. 串联所有单词的子串&#xff08;hard&#xff09; 方法一&#xff1a;暴力 思路&#xff1a; map存每个单词出现的个数。枚举s串的每一…

haproxy-高性能负载均衡反向代理服务

目录 一、HAProxy&#xff08;High Availability Proxy&#xff09;概述 1、HAProxy的概念 2、HAProxy的主要特性 3、HAProxy的优缺点 4、Haproxy负载均衡策略 5、LVS、nginx、HAProxy的区别 二、安装HAProxy 1、yum安装 2、第三方rpm包安装 3、编译安装 3.1 解决 l…

深度学习模型部署(六)TensorRT工作流and入门demo

TensorRT工作流程 官方给出的步骤&#xff1a; 总结下来可以分为两大部分&#xff1a; 模型生成&#xff1a;将onnx经过一系列优化&#xff0c;生成tensorrt的engine模型 选择batchsize&#xff0c;选择精度precision&#xff0c;模型转换 模型推理&#xff1a;使用python或…

软考 系统架构设计师之回归及知识点回顾(6)

接前一篇文章&#xff1a;软考 系统架构设计师之回归及知识点回顾&#xff08;5&#xff09; 10. 边缘计算 边云协同 边缘计算与云计算各有所长&#xff0c;云计算擅长全局性、非实时、长周期的大数据处理与分析&#xff0c;能够在长周期维护、业务决策支撑等领域发挥优势&…