ORBBEC(奥比中光)AstraPro相机在ROS2下的标定与D2C(标定与配准)

news2024/10/6 14:27:06

文章目录

  • 1.rgb、depth相机标定矫正
    • 1.1.标定rgb相机
    • 1.2.标定depth相机
    • 1.3.rgb、depth相机一起标定(效果重复了,但是推荐使用)
    • 1.4.取得标定结果
      • 1.4.1.得到的标定结果的意义
    • 1.5.IR、RGB相机分别应用标定结果
      • 1.5.1.openCV应用标定结果
      • 1.5.2.ros2工程应用标定结果
  • 2.rgb、depth相机配准
    • 2.1.求外参(R、T矩阵)
    • 2.2.求两个相机之间的R、T矩阵
    • 2.3.进行D2C操作
  • 3.题外话

相机自带的D2C效果不好,颜色和点云没有很好地匹配上,自己按照下面的介绍手动匹配一下。

1.rgb、depth相机标定矫正

在下载来的sdk,里面没有标定的文件:ost.yaml.
需要自己进行标定、生成。

我所使用的相机型号是Astra_pro,它是一个单目结构光相机,有一个RGB摄像头+一个IR摄像头。实际上算是一个双目相机(rgb+ir)。【奥比中光Astra深度传感器工作原理】

在ros2(humble)中,需要先安装相机标定套件:

    sudo apt install ros-humble-camera-*
    sudo apt install ros-humble-launch-testing-ament-cmake

在我的系统中,可以分别对这两个进行相机进行标定
在这里插入图片描述
在标定时,具体的参数(相机、话题、格子数等等)要根据你实际的情况进行填写。

1.1.标定rgb相机

执行以下命令

ros2 run camera_calibration cameracalibrator --size 6x7 --square 0.015 --no-service-check image:=/camera/color/image_raw camera:=/camera/color

在这里插入图片描述

1.2.标定depth相机

深度摄像头看起来和RGB摄像头差别很大,实际上有很多相似之处。就Kinect而言,其通过一个红外散斑发射器发射红外光束,光束碰到障碍物后反射回深度摄像头,然后通过返回散斑之间的几何关系计算距离。其实,Kinect的深度摄像头就是一个装了滤波片的普通摄像头,只对红外光成像的摄像头(可以这么认为)。因此要对其标定,只需用红外光源照射物体即可,LED红外光源在淘宝上就20元一个。还有一点必须注意,在拍摄红外照片时,要用黑胶带(或其他东西)将Kinect的红外发射器完全挡住,否则其发出的散斑会在红外照片中产生很多亮点,不利于棋盘角点的检测。
————————————————
原文链接:https://blog.csdn.net/aichipmunk/article/details/9264703

我这里就偷懒了,直接用自带的红外散斑发射器来标定。追求准确的同学,最好还是按照上面说的遮住红外发射器+买一个红外光源。

ros2 run camera_calibration cameracalibrator --size 6x7 --square 0.015 --no-service-check image:=/camera/ir/image_raw camera:=/camera/ir

在这里插入图片描述

1.3.rgb、depth相机一起标定(效果重复了,但是推荐使用)

假如已经进行了上面rgb、depth相机的分别标定,这一步其实没必要进行,效果是一样的。
但是这个一起标定的话,有个好处:在后面计算外参时,可以直接拿到同一时刻两个相机分别拍到的图像。
【ROS下采用camera_calibration进行双目相机标定】

ros2 run camera_calibration cameracalibrator --size 6x7 --square 0.015 --approximate 0.1 --no-service-check left:=/camera/ir/image_raw left_camera:=/camera/ir right:=/camera/color/image_raw right_camera:=/camera/color

在这里插入图片描述

1.4.取得标定结果

参考上面提到的文章进行操作后,分别可以在/tmp目录下得到标定后的数据。
在这里插入图片描述无论是用camera_calibration进行单目标定和双目标定,貌似没有本质的区别,都是分别得到两个相机的内参。
得到的相机内参入下图所示:
在这里插入图片描述
以上图为例,可以知道相机的内参fx=628.54905,fy=631.37457;这是说相机镜头的焦距为628.54905mm吗?
不是,这个是以像素为单位的,镜头的焦距为628.54905像素。那1像素代表多少mm呢(像元尺寸)?
这个要看相机感光芯片的尺寸及芯片的分辨率。假设感光芯片尺寸为WH(单位mm),分辨率为UV,那么像元尺寸为[W/U, H/V).
在这里插入图片描述以上面的海康威视相机为例,假如我标定时使用的是这个相机(像元尺寸6.9um),然后得到的内参为fx=628.54905,fy=631.37457,那么,通过标定得知的镜头焦距:f=628.54905 * 6.9 um=4336.988445um=4.3mm。也就是说这个镜头大概是4.3mm的镜头。
关于靶面、像元的介绍,可以看看这里:【相机和镜头选型需要注意哪些问题】、【相机靶面尺寸详解+工业相机选型】

1.4.1.得到的标定结果的意义

各标定参数的意义:

image_width、image_height代表图片的长宽
camera_name为摄像头名
camera_matrix规定了摄像头的内部参数矩阵
distortion_model指定了畸变模型
distortion_coefficients指定畸变模型的系数
rectification_matrix为矫正矩阵,一般为单位阵
projection_matrix为外部世界坐标到像平面的投影矩阵

也可以看看这个
【相机内参标定究竟标了什么?相机内参外参保姆级教程】

1.5.IR、RGB相机分别应用标定结果

得到标定结果后,有两种方法应用标定结果。

1.5.1.openCV应用标定结果

假如需要自己进行相机的画面矫正,可以使用opencv来进行。opencv只用到上面的camera_matrix、distortion_coefficients这两组数据
【opencv畸变校正的两种方法】

1.5.2.ros2工程应用标定结果

我这里可以直接修改卖家提供的源码里面的launch.xml文件的内容,让其加载标定结果。
设置好文件路径之后,出现 “Invalid camera calibration URL”的解决办法
要加上file://前缀,格式如下:
在这里插入图片描述假如出现 does not match narrow_stereo in时
在这里插入图片描述将ost.yaml里面相机的名字改成和报错的一致:
在这里插入图片描述 由于AstraPro的rgb、ir镜头的畸变不明显,标定校准后,畸变的校准效果也不明显,这里就不贴对比图上来了。

2.rgb、depth相机配准

两个相机都标定完之后,就需要进行配准,也就是要得到从ir图到rgb图的映射(旋转矩阵R、平移矩阵T),从而得到对应深度点的颜色值。
【视觉SLAM十四讲(第二版)第5讲习题解答】
在这里插入图片描述
根据【Kinect深度图与RGB摄像头的标定与配准】里面分析到的,要求RT,就需要先求出外参。

2.1.求外参(R、T矩阵)

从【Opencv——相机标定】的介绍可以看到,opencv的函数calibrateCamera在根据若干组棋盘格点坐标,计算得到相机内参时,也可以得到每张图片的外参。但是我们目前是用ros的camera_calibration得到的相机内参(虽然内部也是opencv,但是camera_calibration没有给我们保存外参),所以不能够直接得到可用的外参。
但是,我们可以从前面双目标定得到的结果中选取同一时刻拍摄的两张图片(一张是rgb相机的,一张是ir相机的)
在这里插入图片描述然后按照【OPENCV已知内参求外参】、【OPENCV标定外参】,利用上面的两张图片+各自相机的内参,分别算出每个相机的外参,主要代码如下:

#include <opencv2/opencv.hpp>
#include <opencv2/calib3d.hpp>

using namespace std;
using namespace cv;

// 根据已知的信息计算外参
int calcExtrinsics(string fileName, Mat cameraMatrix, Mat distCoeffs, Size board_size, double rectWidth,
                   Mat &R, Mat &T)
{
    vector<Point2f> image_points;  /* 图像上检测到的角点 */

    Mat imageInput = imread(fileName, IMREAD_COLOR);

    cout << "image size:" << imageInput.cols << "," << imageInput.rows << endl;

    cout << "cameraMatrix:" << cameraMatrix << endl;
    cout << "distCoeffs:"   << distCoeffs   << endl;

    // 显示一下纠正后的图像,直观地检查一下传递进来的cameraMatrix、disCoeffs有没有问题
    Mat undistortMat;
    undistort(imageInput, undistortMat, cameraMatrix, distCoeffs);
    imshow("undistort mat", undistortMat);
    cout << "undistortMat size:" << undistortMat.cols << "," << undistortMat.rows << endl;

    /* 提取角点 */
    if (0 == findChessboardCorners(imageInput, board_size, image_points))
    {
        cout << "can not find chessboard corners!\n"; //找不到角点
        return -1;
    }
    else
    {
        Mat view_gray;

        cvtColor(imageInput, view_gray, COLOR_RGB2GRAY);

        /* 亚像素精确化 */
        find4QuadCornerSubpix(view_gray, image_points, Size(11,11)); //对粗提取的角点进行精确化

        //        // 看看点的排列顺序
        //        image_points_buf[0] += Point2f(-50, -100);
        //        image_points_buf[8] += Point2f(-60, -100);

        /* 在图像上显示角点位置 */
        Mat displayImg = imageInput.clone();
        drawChessboardCorners(displayImg, board_size, image_points, true); //用于在图片中标记角点

        imshow("Camera Calibration", displayImg);//显示图片
    }

    // 上面已经得到了标定板的二维坐标,现在来填充三维坐标
    vector<Point3f> object_points;
    for(int i = 0; i < board_size.height; i++)
    {
        for(int j = 0; j < board_size.width; j++)
        {
            object_points.push_back(Point3f(rectWidth * j, rectWidth * i, 0));
        }
    }

    //    cout << "object points:" << object_points << endl;

    cout << image_points.size() << " "<< object_points.size() << endl;

    //创建旋转矩阵和平移矩阵
    //    Mat rvecs = Mat::zeros(3, 1, CV_64FC1);
    //    Mat tvecs = Mat::zeros(3, 1, CV_64FC1);
    Mat rvec;
    Mat tvec;

    //求解pnp
    bool pnpResult = false;
    //    pnpResult = solvePnP(object_points, image_points, cameraMatrix, distCoeffs, rvec, tvec);
    pnpResult = solvePnPRansac(object_points, image_points, cameraMatrix, distCoeffs, rvec, tvec);

    cout << "pnp result:" << pnpResult << endl;
    if(pnpResult == false)
    {
        return -2;
    }

    Mat rotM;
    Rodrigues(rvec, rotM);  //将旋转向量变换成旋转矩阵

    R = rotM;
    T = tvec;

    // 直观地检验一下计算到的R、T有没有问题
    {
        vector<Point2f> image_points2; /* 保存重新计算得到的投影点 */
        projectPoints(object_points, rvec, tvec, cameraMatrix, distCoeffs, image_points2);

        /* 在图像上显示角点位置 */
        Mat displayImg = imageInput.clone();
        drawChessboardCorners(displayImg, board_size, image_points2, true); //用于在图片中标记角点

        imshow("projectPoints image", displayImg);//显示图片
    }

    return 0;
}

// 分别对两个相机进行外参计算
void calcExtrinsicsDemo()
{
//#define calc_rgb // 通过注释这个来切换

    // 图像路径
    std::string fileName;

    Size board_size = Size(7, 6);   // 标定板上每行、列的角点数
    double rectWidth = 0.015;       // 标定版棋盘格的大小,单位m

    //相机内参矩阵
    Mat cameraMatrix;
    //相机畸变系数
    Mat distCoeffs;


#ifdef calc_rgb
    fileName = "/home/yong/Desktop/orbbec/calibration/dual/calibrationdata/right-0000.png";     // rgb 图像路径
#else
    fileName = "/home/yong/Desktop/orbbec/calibration/dual/calibrationdata/left-0000.png";     // ir 图像路径
#endif


#ifdef calc_rgb
    // rgb相机参数
    double camData[] = {
                        628.549051,  0.000000,   324.691230,
                        0.000000,    631.374570, 283.546017,
                        0.000000,    0.000000,   1.000000};
    cameraMatrix = Mat(3, 3, CV_64F, camData);


    double distData[] = {0.195904,
                         -0.299118,
                         0.018483,
                         0.005324,
                         0.000000};
    distCoeffs = Mat(5, 1, CV_64F, distData);
#else
    // ir相机参数
    double camData[] = {
                        588.560930, 0.000000  ,  306.212790,
                        0.000000  , 590.708852,  250.991143,
                        0.000000  , 0.000000  ,  1.000000};
    cameraMatrix = Mat(3, 3, CV_64F, camData);

    double distData[] = {-0.044573,
                         0.212463,
                         0.006501,
                         -0.006851,
                         0.000000};
    distCoeffs = Mat(5, 1, CV_64F, distData);
#endif

    Mat R,T;
    calcExtrinsics(fileName, cameraMatrix, distCoeffs, board_size, rectWidth, R, T);

    cout << "R:" << R << endl;
    cout << "T:" << T << endl;

}

2.2.求两个相机之间的R、T矩阵

通过上面的代码,计算得到了rgb、ir(depth)相机的外参:

    // rgb
//R:[0.9932208622695912, -0.104179968756072, -0.05156406561195055;
//     0.09876316392901367, 0.9902419675733234, -0.09831929163314773;
//     0.06130380251811834, 0.09256014134873089, 0.9938181242210883]
//        T:[-0.1985727556503669;
//                -0.1321870936778361;
//                0.5274038381890026]

    // ir
//R:[0.9949185009774844, -0.1001176653598934, 0.01065971367344506;
//     0.1005768682173857, 0.9931508653869539, -0.05946135014214975;
//     -0.004633572304179904, 0.06023131796689411, 0.9981736914704138]
//        T:[-0.1633382501071563;
//                -0.1003269691775472;
//                0.5162717136103199]

然后我们根据【Kinect深度图与RGB摄像头的标定与配准】里面的公式:
在这里插入图片描述计算一下R、T:

Mat R_rgb, T_rgb, R_ir, T_ir;
    {
        double data[] =  {0.9932208622695912, -0.104179968756072, -0.05156406561195055,
                         0.09876316392901367, 0.9902419675733234, -0.09831929163314773,
                         0.06130380251811834, 0.09256014134873089, 0.9938181242210883};
        R_rgb = Mat(3, 3, CV_64F, data).clone();
    }
    {
        double data[] =  {-0.1985727556503669, -0.1321870936778361, 0.5274038381890026};
        T_rgb = Mat(3, 1, CV_64F, data).clone();
    }
    {
        double data[] =  {0.9949185009774844, -0.1001176653598934, 0.01065971367344506,
                         0.1005768682173857, 0.9931508653869539, -0.05946135014214975,
                         -0.004633572304179904, 0.06023131796689411, 0.9981736914704138};
        R_ir = Mat(3, 3, CV_64F, data).clone();
    }
    {
        double data[] =  {-0.1633382501071563,
                         -0.1003269691775472,
                         0.5162717136103199};
        T_ir = Mat(3, 1, CV_64F, data).clone();
    }

    //    cout << R_rgb << endl << T_rgb;


    Mat R, T;
    R = R_rgb * R_ir.inv();
    T = T_rgb - R*T_ir;

    cout << "R:" << R << endl;
    cout << "T:" << T << endl;
    
    /*
R:[0.9980544085026888, -0.0005053133907268852, -0.06234695122237745;
 -0.00192747042416588, 0.9992391545866735, -0.03895377772019822;
 0.06231919869600642, 0.03899816148599567, 0.9972940694071134]
T:[-0.003415024268825395;
 -0.01214055388563491;
 0.02662079621125524]
 */

2.3.进行D2C操作

有了R和T,我们就可以用rgb来对点云着色),注意,此时我们不是用ir图了,而是用depth图了,depth图是16uc1类型的,其数值表示深度(单位mm)。

#include <Eigen/Core>
#include <Eigen/LU>

void depthToColor(Mat depthMat, Mat bgrMat)
{
    Eigen::Matrix3f R_ir2rgb;
    R_ir2rgb <<
        0.9980544085026888, -0.0005053133907268852, -0.06234695122237745,
        -0.00192747042416588, 0.9992391545866735, -0.03895377772019822,
        0.06231919869600642, 0.03899816148599567, 0.9972940694071134;

    Eigen::Vector3f T_ir2rgb;
    T_ir2rgb <<
        -0.003415024268825395,
        -0.01214055388563491,
        0.02662079621125524;


    Eigen::Matrix3f K_ir;           // ir内参矩阵
    K_ir <<
        588.560930, 0.000000  ,  306.212790,
        0.000000  , 590.708852,  250.991143,
        0.000000  , 0.000000  ,  1.000000;

    Eigen::Matrix3f K_rgb;          // rgb内参矩阵
    K_rgb <<
        628.549051,  0.000000,   324.691230,
        0.000000,    631.374570, 283.546017,
        0.000000,    0.000000,   1.000000;

//    Eigen::Matrix3f R;
//    Eigen::Vector3f T;
//    R = K_rgb*parm->R_ir2rgb*K_ir.inverse();
//    T = K_rgb*parm->T_ir2rgb;

    cout << "K_rgb:\n" << K_rgb << endl;
    cout << "K_ir:\n" << K_ir << endl;
//    cout << "R:\n" << R << endl;
//    cout << "T:\n" << T << endl;

    // 4.2 计算投影
    Mat result(480, 640, CV_8UC3);
    int i = 0;
    for (int row = 0; row < 480; row++)
    {
        for (int col = 0; col < 640; col++)
        {
            unsigned short* p = (unsigned short*)depthMat.data;
            unsigned short depthValue = p[row * 640 + col];
            //cout << "depthValue       " << depthValue << endl;
            if (depthValue != std::numeric_limits<unsigned short>::infinity() &&
                depthValue != -std::numeric_limits<unsigned short>::infinity() &&
                depthValue != 0 &&
                depthValue != 65535)
            {
                // 投影到彩色图上的坐标

                // 1)构造一个三维向量p_ir = (x, y, z),其中x,y是该点的像素坐标,z是该像素的深度值;
                Eigen::Vector3f p_ir(col, row, 1.0f);

               // 2)用Kinect内参矩阵H_ir的逆,乘以p_ir得到对应的空间点坐标P_ir,具体公式见上文第四部分(配准);
                Eigen::Vector3f P_ir = K_ir.inverse() *  (p_ir *  (depthValue / 1000.f)); // (除以1000,是为了从毫米变米)
                // 现在这个P_ir,可以放到点云去显示
                
                // 3)由于P_ir是该点在Kinect坐标系下的坐标,我们需要将其转换到RGB摄像头的坐标系下,具体的,就是乘以一个旋转矩阵R,再加上一个平移向量T,得到P_rgb;
                Eigen::Vector3f P_rgb = R_ir2rgb * P_ir + T_ir2rgb;

                // 4)用RGB摄像头的内参矩阵H_rgb乘以P_rgb,得到p_rgb,
                // p_rgb也是一个三维向量,其x和y坐标即为该点在RGB图像中的像素坐标,取出该像素的颜色,作为深度图像中对应像素的颜色;
                Eigen::Vector3f p_rgb = K_rgb * P_rgb;

                int X = static_cast<int>(p_rgb [0] / p_rgb [2]);                // !!!Z_rgb*p_rgb -> p_rgb
                int Y = static_cast<int>(p_rgb [1] / p_rgb [2]);                // !!!Z_rgb*p_rgb -> p_rgb
                //cout << "X:       " << X << "     Y:      " << Y << endl;
                if ((X >= 0 && X < 640) && (Y >= 0 && Y < 480))
                {
                    //cout << "X:       " << X << "     Y:      " << Y << endl;
                    result.data[i * 3]     = bgrMat.data[3 * (Y * 640 + X)];
                    result.data[i * 3 + 1] = bgrMat.data[3 * (Y * 640 + X) + 1];
                    result.data[i * 3 + 2] = bgrMat.data[3 * (Y * 640 + X) + 2];
                }
                else
                {
                    result.data[i * 3] = 0;
                    result.data[i * 3 + 1] = 0;
                    result.data[i * 3 + 2] = 0;
                }
            }
            else
            {
                result.data[i * 3] = 0;
                result.data[i * 3 + 1] = 0;
                result.data[i * 3 + 2] = 0;
            }
            i++;
        }
    }

    imshow("result", result);
}

根据原文的介绍:
在这里插入图片描述

在应用R、T矩阵时,可以根据实际情况微调一下T矩阵的x、y
在这里插入图片描述

但是经过尝试,假如调好了近处的物体,远处的物体和颜色又对不齐;反之亦然。可能是硬件的问题。
另外,我用这种方式得到点云与官方的点云在X、Y方向有较大的偏差,可能是我通过标定得到的内参和官方的内参存在较大差异导致的。
在这里插入图片描述

3.题外话

由于我们用的点云来源自ir相机,所以手眼标定时,要用ir相机去参与标定,而不是rgb相机。


参考:
【1.Astra相机标定】
【【Nav2中文网】ROS2单目相机标定教程】
【深度图与彩色图的配准与对齐】
【Kinect深度图与RGB摄像头的标定与配准】
【RGBD相机实用问题】
【相机内参标定究竟标了什么?相机内参外参保姆级教程】

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

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

相关文章

mac m1安装V2rayU

我原先window上使用的是V2rayN。mac系统使用的是V2rayU。 1.首先下载V2rayU 下载地址&#xff1a;https://github.com/yanue/V2rayU/releases 2.将下载的文件拉到application 安装后&#xff0c;点击运行&#xff0c;此时会弹出安全警告&#xff0c;需要在「系统偏好设置-安…

第4章-动态规划

第4章-动态规划 总分&#xff1a;100分 得分&#xff1a;100.0分 10.0 分 1 . 多选题 中等 10分 有关0-1背包问题,用c[i][j]描述子问题:1...i共i个物品,背包容量为j的最优值(装入背包的最大价值),则其子问题为:1...i-1共i-1个物品,背包容量为j-w ix i,以下说法正确的是( AB…

TypeScript教程(N)

弱类型和强类型 编程语言&#xff0c;按照数据类型是否固定可分为 强类型语言 和 弱类型语言。 弱类型语言 弱类型语言&#xff1a;变量、函数参数和函数的返回值&#xff0c;是没有类型的&#xff0c;一个变量可以接收任何类型的数据&#xff0c;一个函数也可以返回任何类型…

大学生所面临的网络安全问题有哪些?

网络安全从本质上来讲就是网络上的信息安全&#xff0c;就是指网络系统中流动和保存的数据&#xff0c;不受到偶然的或者恶意的破坏、泄露、更改&#xff0c;系统连续正常的工作&#xff0c;网络服务不中断。从广义上来说&#xff0c;凡是涉及网络信息的保密性、完整性、可用性…

登顶Nature 正刊!百度生物计算用AI首次实现mRNA领域重大进展

1985年11月21日的《自然》封面&#xff0c;是一张来自中国的“地图”。这张地图是清代总兵陈伦炯所编撰《海国闻见录》中的插图&#xff0c;是中国人开始认知与探索世界的见证&#xff0c;而选用这张封面&#xff0c;是为了配合当期的特别文章《科技在中国》。 那时候&#xff…

4 ROS2节点参数基础

4 ROS2节点参数基础 4.1 ROS2节点参数介绍4.2 使用C/C实现对节点参数的增删改查4.2.1 创建C/C节点参数的服务端4.2.2 创建C/C节点参数客户端 4.3 使用Python实现对节点参数的增删改查4.3.1 创建Python节点参数的服务端4.3.2 创建Python节点参数客户端 4.4 ROS2节点参数小结 其他…

2008-2020年上市公司能源消耗数据

2008-2020年上市公司能耗数据/上市公司能源消耗数据 1、时间&#xff1a;2008-2020年 2、指标包括&#xff1a;上市公司ID、证券代码、证券简称、资源名称、消耗量、单位 EndDate [统计截止日期] - YYYY-12-31 InstitutionID [上市公司ID] - null Symbol [证券代码] - 交易所…

[架构之路-187]-《软考-系统分析师》-5-数据库系统 - 操作型数据库OLTP与分析型数据库OLAP比较

OLAP与OLTP的区别&#xff1f; OLTP(Online transaction processing) 在线/联机事务处理。典型的OLTP类操作都比较简单&#xff0c;主要是对数据库中的数据进行增删改查&#xff0c;操作主体一般是产品的用户。 OLAP(Online analytical processing): 指联机分析处理。通过分…

Linux网络编程:三次握手 四次挥手

1. 三次握手 建立TCP可靠连接&#xff0c;只能是客户端先发起。 &#xff08;1&#xff09;SYN标志位为1&#xff0c;表示请求建立连接&#xff1b;ACK标志位为1&#xff0c;表示确认收到对方报文。 &#xff08;2&#xff09;seq为数据包序列号&#xff0c;ack为确认序列号。…

计算机视觉的应用4-目标检测任务:利用Faster R-cnn+Resnet50+FPN模型对目标进行预测

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用4-目标检测任务&#xff0c;利用Faster RcnnResnet50FPN模型对目标进行预测&#xff0c;目标检测是计算机视觉三大任务中应用较为广泛的&#xff0c;Faster R-CNN 是一个著名的目标检测网络&#x…

or-tools 应用案例分析:复杂作业车间调度问题

作业调度问题是常见的线性规划(整数规划)问题&#xff0c;其中多个作业在多台机器上处理。每个作业由一系列任务组成&#xff0c;这些任务必须按给定的顺序执行&#xff0c;并且每个任务都必须在特定的机器上处理。如何有效的利用所有的机器在最短的时间内完成所有的作业任务&a…

神经形态处理和自搜索存储如何降低联邦机构的网络风险

组织在边缘处理的信息量呈爆炸式增长。对于联邦机构和军队来说尤其如此&#xff0c;它们从设备、建筑物、船舶、飞机等中的移动设备和传感器生成大量数据。 寻找有效的方法来管理、使用和保护这些数据具有挑战性。但是有一个有效且具有成本效益的解决方案。神经形态处理和自搜…

c#笔记-数组

数组 声明数组 数组是一种可以声明多个同类型变量的数据结构&#xff0c;能替你声明多个变量。 并且其中的值可以通过索引动态访问&#xff0c;可以搭配循环批量处理这些值。 数组类型的写法是&#xff0c;在目标类型后加上一对中括号。 数组值没有字面量&#xff0c;需要构…

海天注塑机KEBA系统数据采集

本文章只针对海天注塑机的KEBA系统&#xff0c;因为其他注塑机厂家也用KEBA系统&#xff0c;他们的采集方式可能不太一样&#xff0c;所以后续有时间我将写其他文章来解释&#xff08;默认你已经向海天采购了OPC组件&#xff09;。 一、采集原理 采集软件&#xff08;OPC cli…

electron+vue3全家桶+vite项目搭建【18】electron新建窗口时传递参数【url版】

文章目录 引入实现效果展示实现思路实现步骤1.调整主进程新建窗口的handle2.调整新建窗口函数3.封装url获取请求参数的工具 测试代码 引入 electronvue的项目中&#xff0c;我们通过传入页面路由来展开新的页面&#xff0c;就像vue-router的路由传参一样&#xff0c;我们可以利…

排序算法 — 桶排序

文章目录 桶排序介绍桶排序实现桶排序复杂度和稳定性桶排序复杂度桶排序稳定性 代码实现核心&总结 桶排序介绍 假设待排序的数组a中共有N个整数&#xff0c;并且已知数组a中数据的范围[0, MAX)。在桶排序时&#xff0c;创建容量为MAX的桶数组r&#xff0c;并将桶数组元素都…

【AUTOSAR】【通信安全】E2E

目录 一、概述 二、约束和假设 三、依赖模块 四、功能描述 4.1 开发错误 4.1.1 运行时错误 五、API接口 5.1 E2E Profile 接口 5.2 E2E其他接口 一、概述 该文档制定了PRS E2E协议的平台特定实现要求。这包括所使用的接口和数据类型。 E2E保护的概念假设在运行时应对…

探讨Redis缓存问题及解决方案:缓存穿透、缓存击穿、缓存雪崩与缓存预热(如何解决Redis缓存中的常见问题并提高应用性能)

Redis是一种非常流行的开源缓存系统&#xff0c;用于缓存数据以提高应用程序性能。但是&#xff0c;如果我们不注意一些缓存问题&#xff0c;Redis也可能会导致一些性能问题。在本文中&#xff0c;我们将探讨Redis中的一些常见缓存问题&#xff0c;并提供解决方案。 一、缓存穿…

云计算中的边缘计算技术及其应用

章节一&#xff1a;云计算和边缘计算的简介 随着互联网的发展&#xff0c;数据中心的规模不断扩大&#xff0c;云计算也成为了越来越受欢迎的计算模式。但是&#xff0c;云计算存在着一些问题&#xff0c;比如延迟较高&#xff0c;网络瓶颈&#xff0c;数据隐私和安全性等等。…

Canny边缘检测算法

文章目录 前言1、Canny边缘检测算法2、代码1函数 3、代码24、基于tensor数据的代码 前言 最近在向卷积神经网络里的数据预处理和数据增强部分加这个函数&#xff0c;记录一下。 1、Canny边缘检测算法 Canny边缘检测算法是一种经典的边缘检测算法&#xff0c;其基本原理如下&a…