ORB-SLAM2第二节---双目地图初始化

2023-10-26

比起单目初始化,而双目实现地图的初始化非常简单,只需要一帧(左右目图像)即可完成初始化。

  1. 行特征点统计。考虑用图像金字塔尺度作为偏移量,在当前点上下正负偏移量(r)内的纵坐标值都认为是匹配点可能存在的行数。之所以这样做,是因为极线矫正后仍然存在一定的误差,通过这种方式可以避免漏匹配。对于左图中极线上的投影像素点,在右图中搜索的纵坐标范围是minr~maxr。
  2. 粗匹配。在左图中的特征点与右图中的候选匹配点进行逐个比较,得到描述子距离最小的点作为最佳的粗匹配点。根据三维点的距离范围可以将横坐标搜索范围限制在minU~maxU。maxU对应的是三维点位于无穷远处,视差为0时的横坐标,而minU对应的是三维点位于最近距离时的横坐标。
  3. 在粗匹配的基础上,在图像块滑动窗口内用差的绝对和(Sum of Absolute Differences,SAD)实现精确匹配。此时得到的匹配像素坐标仍然是整数坐标。如图10-4,图像块本身的窗口大小是2w+1,滑动窗口范围是-L~L。
  4. 在精确匹配的基础上,用亚像素插值得到最佳的亚像素匹配坐标。
  5. 根据最佳的亚像素匹配坐标计算视差,从而得到深度值。
  6. 判断并删除外点。

亚像素坐标是指:坐标误差小于一个像素的形式。(浮点数) 

/*
 * 双目匹配函数
 *
 * 为左图的每一个特征点在右图中找到匹配点 \n
 * 根据基线(有冗余范围)上描述子距离找到匹配, 再进行SAD精确定位 \n ‘
 * 这里所说的SAD是一种双目立体视觉匹配算法,可参考[https://blog.csdn.net/u012507022/article/details/51446891]
 * 最后对所有SAD的值进行排序, 剔除SAD值较大的匹配对,然后利用抛物线拟合得到亚像素精度的匹配 \n 
 * 这里所谓的亚像素精度,就是使用这个拟合得到一个小于一个单位像素的修正量,这样可以取得更好的估计结果,计算出来的点的深度也就越准确
 * 匹配成功后会更新 mvuRight(ur) 和 mvDepth(Z)
 */
void Frame::ComputeStereoMatches()
{
    /*两帧图像稀疏立体匹配(即:ORB特征点匹配,非逐像素的密集匹配,但依然满足行对齐)
     * 输入:两帧立体矫正后的图像img_left 和 img_right 对应的orb特征点集
     * 过程:
          1. 行特征点统计. 统计img_right每一行上的ORB特征点集,便于使用立体匹配思路(行搜索/极线搜索)进行同名点搜索, 避免逐像素的判断.
          2. 粗匹配. 根据步骤1的结果,对img_left第i行的orb特征点pi,在img_right的第i行上的orb特征点集中搜索相似orb特征点, 得到qi
          3. 精确匹配. 以点qi为中心,半径为r的范围内,进行块匹配(归一化SAD),进一步优化匹配结果
          4. 亚像素精度优化. 步骤3得到的视差为uchar/int类型精度,并不一定是真实视差,通过亚像素差值(抛物线插值)获取float精度的真实视差
          5. 最优视差值/深度选择. 通过胜者为王算法(WTA)获取最佳匹配点。
          6. 删除离群点(outliers). 块匹配相似度阈值判断,归一化sad最小,并不代表就一定是正确匹配,比如光照变化、弱纹理等会造成误匹配
     * 输出:稀疏特征点视差图/深度图(亚像素精度)mvDepth 匹配结果 mvuRight
     */

    // 为匹配结果预先分配内存,数据类型为float型
    // mvuRight存储右图匹配点索引
    // mvDepth存储特征点的深度信息
	mvuRight = vector<float>(N,-1.0f);
    mvDepth = vector<float>(N,-1.0f);

	// orb特征相似度阈值  -> mean ~= (max  + min) / 2
    const int thOrbDist = (ORBmatcher::TH_HIGH+ORBmatcher::TH_LOW)/2;

    // 金字塔底层(0层)图像高 nRows
    const int nRows = mpORBextractorLeft->mvImagePyramid[0].rows;

	// 二维vector存储每一行的orb特征点的列坐标的索引,为什么是vector,因为每一行的特征点有可能不一样,例如
    // vRowIndices[0] = [1,2,5,8, 11]   第1行有5个特征点,他们的列号(即x坐标)分别是1,2,5,8,11
    // vRowIndices[1] = [2,6,7,9, 13, 17, 20]  第2行有7个特征点.etc
    vector<vector<size_t> > vRowIndices(nRows, vector<size_t>());
    for(int i=0; i<nRows; i++) vRowIndices[i].reserve(200);

	// 右图特征点数量,N表示数量 r表示右图,且不能被修改
    const int Nr = mvKeysRight.size();

	// Step 1. 行特征点统计。 考虑用图像金字塔尺度作为偏移,左图中对应右图的一个特征点可能存在于多行,而非唯一的一行
    for(int iR = 0; iR < Nr; iR++) {

        // 获取特征点ir的y坐标,即行号
        const cv::KeyPoint &kp = mvKeysRight[iR];
        const float &kpY = kp.pt.y;
        
        // 计算特征点ir在行方向上,可能的偏移范围r,即可能的行号为[kpY + r, kpY -r]
        // 2 表示在全尺寸(scale = 1)的情况下,假设有2个像素的偏移,随着尺度变化,r也跟着变化
        const float r = 2.0f * mvScaleFactors[mvKeysRight[iR].octave];
        const int maxr = ceil(kpY + r);
        const int minr = floor(kpY - r);

        // 将特征点ir保证在可能的行号中
        for(int yi=minr;yi<=maxr;yi++)
            vRowIndices[yi].push_back(iR);
    }

    // 下面是 粗匹配 + 精匹配的过程
    // 对于立体矫正后的两张图,在列方向(x)存在最大视差maxd和最小视差mind
    // 也即是左图中任何一点p,在右图上的匹配点的范围为应该是[p - maxd, p - mind], 而不需要遍历每一行所有的像素
    // maxd = baseline * length_focal / minZ
    // mind = baseline * length_focal / maxZ

    const float minZ = mb;
    const float minD = 0;			// 最小视差为0,对应无穷远 
    const float maxD = mbf/minZ;    // 最大视差对应的距离是相机的基线

    // 保存sad块匹配相似度和左图特征点索引
    vector<pair<int, int> > vDistIdx;
    vDistIdx.reserve(N);

    // 为左图每一个特征点il,在右图搜索最相似的特征点ir
    for(int iL=0; iL<N; iL++) {

		const cv::KeyPoint &kpL = mvKeys[iL];
        const int &levelL = kpL.octave;
        const float &vL = kpL.pt.y;
        const float &uL = kpL.pt.x;

        // 获取左图特征点il所在行,以及在右图对应行中可能的匹配点
        const vector<size_t> &vCandidates = vRowIndices[vL];
        if(vCandidates.empty()) continue;

        // 计算理论上的最佳搜索范围
        const float minU = uL-maxD;
        const float maxU = uL-minD;
        
        // 最大搜索范围小于0,说明无匹配点
        if(maxU<0) continue;

		// 初始化最佳相似度,用最大相似度,以及最佳匹配点索引
        int bestDist = ORBmatcher::TH_HIGH;
        size_t bestIdxR = 0;
        const cv::Mat &dL = mDescriptors.row(iL);
        
        // Step 2. 粗配准。左图特征点il与右图中的可能的匹配点进行逐个比较,得到最相似匹配点的描述子距离和索引
        for(size_t iC=0; iC<vCandidates.size(); iC++) {

            const size_t iR = vCandidates[iC];
            const cv::KeyPoint &kpR = mvKeysRight[iR];

            // 左图特征点il与待匹配点ic的空间尺度差超过2,放弃
            if(kpR.octave<levelL-1 || kpR.octave>levelL+1)
                continue;

            // 使用列坐标(x)进行匹配,和stereomatch一样
            const float &uR = kpR.pt.x;

            // 超出理论搜索范围[minU, maxU],可能是误匹配,放弃
            if(uR >= minU && uR <= maxU) {

                // 计算匹配点il和待匹配点ic的相似度dist
                const cv::Mat &dR = mDescriptorsRight.row(iR);
                const int dist = ORBmatcher::DescriptorDistance(dL,dR);

				//统计最小相似度及其对应的列坐标(x)
                if( dist<bestDist ) {
                    bestDist = dist;
                    bestIdxR = iR;
                }
            }
        }
    
        // Step 3. 图像块滑动窗口用SAD(Sum of absolute differences,差的绝对和)实现精确匹配. 
        if(bestDist<thOrbDist) {
            // 如果刚才匹配过程中的最佳描述子距离小于给定的阈值
            // 计算右图特征点x坐标和对应的金字塔尺度
            const float uR0 = mvKeysRight[bestIdxR].pt.x;
            const float scaleFactor = mvInvScaleFactors[kpL.octave];
            
            // 尺度缩放后的左右图特征点坐标
            const float scaleduL = round(kpL.pt.x*scaleFactor);			
            const float scaledvL = round(kpL.pt.y*scaleFactor);
            const float scaleduR0 = round(uR0*scaleFactor);

            // 滑动窗口搜索, 类似模版卷积或滤波
            // w表示sad相似度的窗口半径
            const int w = 5;

            // 提取左图中,以特征点(scaleduL,scaledvL)为中心, 半径为w的图像块patch
            cv::Mat IL = mpORBextractorLeft->mvImagePyramid[kpL.octave].rowRange(scaledvL-w,scaledvL+w+1).colRange(scaleduL-w,scaleduL+w+1);
            IL.convertTo(IL,CV_32F);
            
            // 图像块均值归一化,降低亮度变化对相似度计算的影响
			IL = IL - IL.at<float>(w,w) * cv::Mat::ones(IL.rows,IL.cols,CV_32F);

			//初始化最佳相似度
            int bestDist = INT_MAX;

			// 通过滑动窗口搜索优化,得到的列坐标偏移量
            int bestincR = 0;

			//滑动窗口的滑动范围为(-L, L)
            const int L = 5;

			// 初始化存储图像块相似度
            vector<float> vDists;
            vDists.resize(2*L+1); 

            // 计算滑动窗口滑动范围的边界,因为是块匹配,还要算上图像块的尺寸
            // 列方向起点 iniu = r0 - 最大窗口滑动范围 - 图像块尺寸
            // 列方向终点 eniu = r0 + 最大窗口滑动范围 + 图像块尺寸 + 1
            // 此次 + 1 和下面的提取图像块是列坐标+1是一样的,保证提取的图像块的宽是2 * w + 1
            // ! 源码: const float iniu = scaleduR0+L-w; 错误
            // scaleduR0:右图特征点x坐标
            const float iniu = scaleduR0-L-w;
            const float endu = scaleduR0+L+w+1;

			// 判断搜索是否越界
            if(iniu<0 || endu >= mpORBextractorRight->mvImagePyramid[kpL.octave].cols)
                continue;

			// 在搜索范围内从左到右滑动,并计算图像块相似度
            for(int incR=-L; incR<=+L; incR++) {

                // 提取右图中,以特征点(scaleduL,scaledvL)为中心, 半径为w的图像快patch
                cv::Mat IR = mpORBextractorRight->mvImagePyramid[kpL.octave].rowRange(scaledvL-w,scaledvL+w+1).colRange(scaleduR0+incR-w,scaleduR0+incR+w+1);
                IR.convertTo(IR,CV_32F);
                
                // 图像块均值归一化,降低亮度变化对相似度计算的影响
                IR = IR - IR.at<float>(w,w) * cv::Mat::ones(IR.rows,IR.cols,CV_32F);
                
                // sad 计算,值越小越相似
                float dist = cv::norm(IL,IR,cv::NORM_L1);

                // 统计最小sad和偏移量
                if(dist<bestDist) {
                    bestDist = dist;
                    bestincR = incR;
                }

                //L+incR 为refine后的匹配点列坐标(x)
                vDists[L+incR] = dist; 	
            }

            // 搜索窗口越界判断
            if(bestincR==-L || bestincR==L)
                continue;

			// Step 4. 亚像素插值, 使用最佳匹配点及其左右相邻点构成抛物线来得到最小sad的亚像素坐标
            // 使用3点拟合抛物线的方式,用极小值代替之前计算的最优是差值
            //    \                 / <- 由视差为14,15,16的相似度拟合的抛物线
            //      .             .(16)
            //         .14     .(15) <- int/uchar最佳视差值
            //              . 
            //           (14.5)<- 真实的视差值
            //   deltaR = 15.5 - 16 = -0.5
            // 公式参考opencv sgbm源码中的亚像素插值公式
            // 或论文<<On Building an Accurate Stereo Matching System on Graphics Hardware>> 公式7

            const float dist1 = vDists[L+bestincR-1];	
            const float dist2 = vDists[L+bestincR];
            const float dist3 = vDists[L+bestincR+1];
            const float deltaR = (dist1-dist3)/(2.0f*(dist1+dist3-2.0f*dist2));

            // 亚像素精度的修正量应该是在[-1,1]之间,否则就是误匹配
            if(deltaR<-1 || deltaR>1)
                continue;
            
            // 根据亚像素精度偏移量delta调整最佳匹配索引
            float bestuR = mvScaleFactors[kpL.octave]*((float)scaleduR0+(float)bestincR+deltaR);
            float disparity = (uL-bestuR);
            if(disparity>=minD && disparity<maxD) {
                // 如果存在负视差,则约束为0.01
                if( disparity <=0 ) {
                    disparity=0.01;
                    bestuR = uL-0.01;
                }
                
                // 根据视差值计算深度信息
                // 保存最相似点的列坐标(x)信息
                // 保存归一化sad最小相似度
                // Step 5. 最优视差值/深度选择.
                mvDepth[iL]=mbf/disparity;
                mvuRight[iL] = bestuR;
                vDistIdx.push_back(pair<int,int>(bestDist,iL));
        }   
    }
    }
    // Step 6. 删除离群点(outliers)
    // 块匹配相似度阈值判断,归一化sad最小,并不代表就一定是匹配的,比如光照变化、弱纹理、无纹理等同样会造成误匹配
    // 误匹配判断条件  norm_sad > 1.5 * 1.4 * median
    sort(vDistIdx.begin(),vDistIdx.end());
    const float median = vDistIdx[vDistIdx.size()/2].first;
    const float thDist = 1.5f*1.4f*median;

    for(int i=vDistIdx.size()-1;i>=0;i--) {
        if(vDistIdx[i].first<thDist)
            break;
        else {
			// 误匹配点置为-1,和初始化时保持一直,作为error code
            mvuRight[vDistIdx[i].second]=-1;
            mvDepth[vDistIdx[i].second]=-1;
        }
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ORB-SLAM2第二节---双目地图初始化 的相关文章

  • 是否需要销毁运算符删除的形式才能真正销毁对象?

    C 20 添加了破坏形式operator delete区别于std destroying delete t范围 它导致delete表达式在调用之前不再销毁对象operator delete 目的是在显式调用对象的析构函数和释放内存之前 允许
  • 使用 ADAL v3 使用 ClientID 对 Dynamics 365 进行身份验证

    我正在尝试对我们的在线 Dynamics CRM 进行身份验证以使用可用的 API 我能找到的唯一关于执行此操作的官方文档是 https learn microsoft com en us dynamics365 customer enga
  • C#.Net 邮件将进入垃圾邮件文件夹

    我正在从 ASP net Web 应用程序发送电子邮件 邮件发送成功 没有失败 但大多数都进入了垃圾邮件文件夹 请帮助我克服垃圾邮件过滤器 我的发送邮件代码 public void SendMail string FromAddress s
  • 如何使用 openSSL 函数验证 PEM 证书的密钥长度

    如何验证以这种方式生成的 PEM 证书的密钥长度 openssl genrsa des3 out server key 1024 openssl req new key server key out server csr cp server
  • 关于逻辑/算法的想法以及如何防止线程写入 Sql Server 中的竞争

    我有以下逻辑 public void InQueueTable DataTable Table int incomingRows Table Rows Count if incomingRows gt RowsThreshold async
  • C# 中的 Stack<> 实现

    我最近一直在实现递归目录搜索实现 并且使用堆栈来跟踪路径元素 当我使用 string Join 连接路径元素时 我发现它们被颠倒了 当我调试该方法时 我查看了堆栈 发现堆栈内部数组中的元素本身是相反的 即最近 Push 的元素位于内部数组的
  • 无法继承形状

    为什么我不能使用继承 a 的类Shapes class http msdn microsoft com en us library ms604615 28v vs 90 29 我需要延长Rectangle具有一些方法的类 但我想以与使用相同
  • strlen() 编译时优化

    前几天我发现你可以找到编译时strlen使用这样的东西 template
  • Selenium - C# - Webdriver - 无法找到元素

    在 C 中使用 selenium 我试图打开浏览器 导航到 Google 并找到文本搜索字段 我尝试下面的 IWebDriver driver new InternetExplorerDriver C driver Navigate GoT
  • 2个对象,完全相同(除了命名空间)c#

    我正在使用第三方的一组网络服务 但遇到了一个小障碍 在我手动创建将每个属性从源复制到目标的方法之前 我想我应该在这里寻求更好的解决方案 我有 2 个对象 一个是 Customer CustomerParty 类型 另一个是 Appointm
  • 如何向 Mono.ZeroConf 注册服务?

    我正在尝试测试 ZeroConf 示例http www mono project com Mono Zeroconf http www mono project com Mono Zeroconf 我正在运行 OpenSuse 11 和 M
  • C# 根据当前日期传递日期时间值

    我正在尝试根据 sql server 中的两个日期获取记录 Select from table where CreatedDate between StartDate and EndDate我通过了5 12 2010 and 5 12 20
  • 当Model和ViewModel一模一样的时候怎么办?

    我想知道什么是最佳实践 我被告知要始终创建 ViewModel 并且永远不要使用核心模型类将数据传递到视图 这就说得通了 让我把事情分开 但什么是Model 和ViewModel一模一样 我应该重新创建另一个类还是只是使用它 我觉得我应该重
  • 使用 gcc 时在头文件中查找定义的好方法是什么?

    在使用 gcc 时 有人有推荐的方法在头文件中查找定义吗 使用 MSVC 时 我只需右键单击并选择 转到定义 这非常好 我使用过 netbeans gcc 它确实有代码帮助 包括到定义的超链接 所以这是一种选择 但是 我想知道是否有任何其他
  • C++ 指针引用混淆

    struct leaf int data leaf l leaf r struct leaf p void tree findparent int n int found leaf parent 这是 BST 的一段代码 我想问一下 为什么
  • C:设置变量范围内所有位的最有效方法

    让我们来int举个例子 int SetBitWithinRange const unsigned from const unsigned to To be implemented SetBitWithinRange应该返回一个int其中所有
  • winform c# 中的弹出窗口

    我正在开发一个需要弹出窗口的项目 但问题是我还希望能够通过表单设计器在此弹出窗口中添加文本框等 所以基本上我有一个按钮 当您单击它时 它将打开我在表单设计器中设计的另一个窗口 我一直在谷歌搜索 但还没有找到我需要的东西 所以我希望你们能帮助
  • .Net Reactive Extensions Framework (Rx) 是否考虑拓扑顺序?

    Net 反应式扩展框架是否按拓扑顺序传播通知以最大限度地减少更新量 就像 Scala Rx 所做的那样 Net 反应式扩展 Rx 是否可以 https github com lihaoyi scala rx wiki How it Work
  • 从后面的代码添加外部 css 文件

    我有一个 CSS 文件 例如 SomeStyle css 我是否可以将此样式表文档从其代码隐藏应用到 aspx 页面 您可以将文字控件添加到标头控件中 Page Header Controls Add new System Web UI L
  • 如果找不到指定的图像文件,显示默认图像的最佳方式?

    我有一个普通的电子商务应用程序 我将 ITEM IMAGE NAME 存储在数据库中 有时经理会拼错图像名称 为了避免 丢失图像 IE 中的红色 X 每次显示产品列表时 我都会检查服务器中是否有与该产品相关的图像 如果该文件不存在 我会将其

随机推荐

  • 【WSL】[04]从C盘解放出来WSL的linux镜像

    前言 C盘的硬盘资源有限 虚拟机的需求无限 所以 要把无限的硬盘需求搞到其他盘去才行啊 方案1 利用工具 move wsl 1 管理员运行PowerShell 创建WSL的工作目录 移动前 C盘的空间大小 base PS C WINDOWS
  • String、StringBuffer、StringBuilder三者的区别

    在前面的文章中 我们已经分别介绍了String StringBuffer StringBuilder三者的基本使用 还不懂String StringBuffer StringBuilder这三个类是如何使用的 可以先去看看之前的文章 Jav
  • unity图集的使用(万能方法)

    图集的意义 使用图集可以说是多加了一个步骤 但是这个步骤不是没有意义的 他可以有效的减少drawcall的数量 多张图片需要多个drawcall 而如果我们合成一个大图 只需要一个drawcall 并且可以减少内存的开销 图集的使用 然后就
  • 最全的jquery datatables api 使用详解

    分别导入css和js文件 加载
  • 【语义分割】4、DFANet: Deep Feature Aggregation for Real-Time Semantic Segmentation

    文章目录 摘要 1 引言 2 相关工作 3 深层特征聚合网络 3 1 Observations 3 2 深层特征聚合 3 3 网络结构 4 实验 4 1 DFA 结构的分析 4 1 1 轻量级 backbone 网络 4 1 2 特征聚合
  • M5311模组对接OneNet平台—AT指令基本操作流程(LwM2M协议)

    目录 概述 一 开机驻网流程 二 注册onenet平台 概述 下面将介绍M5311模组对接OneNet平台 AT指令基本操作流程 LwM2M协议 已在项目中使用 一 开机驻网流程 1 AT SM LOCK 2 AT 3 AT CMEE 1
  • 经典树结构——B+树的原理及实现

    文章目录 B 树的概念 B 树实现 B 树节点参数 B 树的查询 实现 B 树插入 实现 B 树删除 实现 B 树的概念 规则 B 跟B树不同B 树的非叶子节点不保存关键字记录的指针 只进行数据索引 这样使得B 树每个非叶子节点所能保存的关
  • Linux系统基础操作命令

    目录 一 基本使用 1 编辑Linux命令行的辅助操作 2 常用的基础命令 1 切换用户 su 2 pwd 查看当前工作目录 3 cd 切换工作目录 4 cp 复制 5 mkdir 创建目录 6 touch 创建文件 7 创建链接文件ln
  • 《网络安全工程师笔记》 第十一章:WEB服务器和FTP服务器

    注 本笔记来自温晓飞老师的网络安全课程 第十一章 WEB服务器和FTP服务器 第一章 虚拟化架构与系统部署 第二章 IP地址详解 第三章 进制转换 第四章 DOS基本命令与批处理 第五章 用户与组管理 第六章 服务器远程管理 第七章 NTF
  • java基础6

    packagecom edu 01 public class Student 私有化成员变量 private String name private int age set get方法 public voidsetName String n
  • [基础数据结构] 判断是否为完全二叉搜索树

    对二叉搜索树的定义是 一棵深度为k的有n个结点的二叉树 对树中的结点按从上至下 从左到右的顺序进行编号 如果编号为i 1 i n 1 i n 1 i n 的结点与满二叉树中编号为i的结点在二叉树中的位置相同 则这棵二叉树称为
  • UI设计都有哪些设计原则,分享三个给你

    是什么使一个好UI设计容易阅读 是什么让用户轻松浏览 设计师如何创造一个闪亮的UI 任何软件产品的关键部分都是用户界面 好的UI设计 用户甚至会忽略它 如果做得不好 就会成为用户使用产品的绊脚石 为了更有效地设计能够满足用户使用的设计UI
  • 【原理篇】再次带你进入多线程的世界

    1 Java内存模型基础知识 1 1并发编程模型的两个关键问题 线程间如何通信 即 线程之间以何种机制来交换信息 线程间如何同步 即 线程以何种机制来控制不同线程间操作发 的相对顺序 有两种并发模型可以解决这两个问题 消息传递并发模型 共享
  • scala的基础语法之变量

    1 类介绍 我们在new scala类的时候 这里分为Class和Object两大类 idea2019 1版本 其他新版本应该是四种 case Class和case Object 不过没关系 这里想要使用case的直接在前面写case即可
  • 任正非谈成功秘诀:28年只对准一个城墙口冲锋

    文 记者 赵东辉 李斌 刘诗平 蔡国兆 彭勇 何雨欣 任正非和华为公司 堪称当代商业史上的传奇 1987年 年满43岁的任正非和5个同伴集资2 1万元成立华为公司 利用两台万用表加一台示波器 在深圳的一个 烂棚棚 里起家创业 28年后 华为
  • 穿越火线排位赛显示该服务器,CF新段位S7枪王排位调整 排位分数和地图

    CF新段位S7枪王排位调整 排位分数和地图 本次体验服客户端正式更新同时S7枪王排位赛页开启了 本期枪王排位针对地图 段位分数和奖励上进行调整 不同段位分数和地图加成都不同 枪王排位第五赛季开始及优化丢掉大脑再丢烦恼 冲啥大冲啥小 冲啥都有
  • 【无标题】PAT作业1001 害死人不偿命的(3n+1)猜想

    题目要求简要概述 输入一个小于1000的正整数 如果该正整数为奇数 进行2 n的运算 如果为偶数 进行 3n 1 2的运算 反复进行计算 直至n 1后 输出运算的次数 解题方法 1 定义两个整形变量 分别用于输入n 记录运算次数 int n
  • 将压缩包里的图片显示到页面上示例

    在做项目的时候有个这样的需求 需要把压缩包里的图片预览显示出来 梳理一下就以下三步 下载压缩包 解压出文件 组成可用的图片URL 显示到图片标签上 实现这个功能过程还是走了些弯路的 也遇到一些坑 这里就不多废话了 直接上代码 希望能帮助各位
  • SVPWM所需要掌握的一些定理

    1 正弦定理 2 伏秒平衡 不懂 伏秒平衡 又称伏秒平衡 是指开关电源稳定工作状态下 加在电感两端的电压乘以导通时间等于关断时刻电感两端电压乘以关断时间 或指在稳态工作的开关电源中电感两端的正伏秒值等于负伏秒值 在SVPWM中 磁链等于电压
  • ORB-SLAM2第二节---双目地图初始化

    比起单目初始化 而双目实现地图的初始化非常简单 只需要一帧 左右目图像 即可完成初始化 行特征点统计 考虑用图像金字塔尺度作为偏移量 在当前点上下正负偏移量 r 内的纵坐标值都认为是匹配点可能存在的行数 之所以这样做 是因为极线矫正后仍然存