图漾深度摄像头基本使用方法

2023-05-16

搞到一款图漾的3d相机(型号为FM810-C)有好久了,一直也只是编译了sample代码跑起来看看样子,并没有着手看SDK以及开发的事。近几日对照SDK以及其中的SimpleView_FetchFrame例子,捋了捋头绪。
先看一下官方文档给出的开发流程:

  1. 初始化 API。
  2. 操作设备。
    (a) 获取设备列表。
    初次获取设备信息时可以通过 TYGetDeviceList() 查询已连接的设备。在已知设备 ID 的情况下,
    可以不调用该函数查询。
    (b) 打开设备。
    对于 USB 设备可以通过 TYOpenDevice() 打开设备;对于网络设备可以通过 TYOpenDevice-
    WithIP() 打开设备。
  3. 操作组件。
    (a) 查询组件状态。
    使用 TYGetComponentIDs() 可查询所有组件状态;使用 TYGetEnabledComponents() 查询使能
    状态的组件。
    (b) 配置组件。
    每个设备打开后都必须配置组件,
    默认情况下只有虚拟组件 TY_COMPONENT_DEVICE
    是使能状态。多个设备可以通过位或方式同时使能。代码示例如下:

    cd source
    int32_t componentIDs = TY_COMPONENT_DEPTH_CAM | TY_COMPONENT_RGB_CAM ;
    TYEnableComponents ( hDevice , componentIDs ) ;
  4. 操作参数。
    (a) 查询指定参数的信息。通过填充结构体 TY_FEATURE_INFO 来获取指定组件的指定参数的信息。
    如果该组件不包含所指定的参数,则 TY_FEATURE_INFO 中 isValid 值为 false。
    (b) 配置参数。
    配置参数的 API 按照参数的数据类型分类,如 TYGetIntRange,和 TYSetFloat 等。
  5. 给驱动程序分配 framebuffer。
    (a) 查询当前配置下每个 framebuffer 的大小。
    (b) 分配 framebuffer 并压入驱动内的缓冲队列。
    驱动内部维护一个缓冲队列(buffer queue),每帧数据传出时会将填充好的 buffer 作 dequeue
    操作,并完全传出给用户使用。用户需要保证新的一帧数据到来时驱动的缓冲队列 buffer queue
    不为空,否则该帧数据将被丢弃。
  6. 注册回调函数(主动获取模式下不调用)。
  7. 启动采集。
  8. 主动获取帧数据(主动获取模式下不调用)。
  9. 停止采集。
  10. 关闭设备。
  11. 释放 API。

看起来流程还算清晰,但是只有这个感觉还是一头雾水。于是对应sample中的SimpleView_FetchFrame源码,慢慢的理了理头绪。先贴一个最最最简单核心的骨架流程:
1、初始化设备 TYInitLib();
2、打开设备 TYOpenDevice();
3、使能组件 TYEnableComponents();
4、将帧缓存压入队列 TYEnqueueBuffer();
5、开始拍摄 TYStartCapture();
6、获取帧数据 TYFetchFrame();
7、解析帧数据 parseFrame();
8、显示图像 cv::imshow();
9、停止拍摄 TYStopCapture();
10、关闭设备 TYCloseDevice();
11、注销API TYDeinitLib();

流程看起来跟SDK上说的没有什么差别啊,是的,并没有太多的差别,但是后面贴的代码是核心流程中最最最简化的核心流程,用于抽出框架,其他的功能在此框架上添加(比如SimpleView_FetchFrame例子中的一些信息状态输出,运行状态检测,等等)。

贴上对应的代码:


#include "../common/Utils.hpp"

int main(int argc, char* argv[])
{
    //初始化
    TYInitLib();

    // 打开设备
    // 用设备ID打开设备,同时构建此设备的设备管理器。
    TY_DEV_HANDLE hDevice;
    TYOpenDevice("207000000866", &hDevice);

    // 使能组件
    // 按位或上组件结构体中的值,即可打开设备。
    TYEnableComponents(hDevice, TY_COMPONENT_RGB_CAM | TY_COMPONENT_DEPTH_CAM | TY_COMPONENT_IR_CAM_LEFT | TY_COMPONENT_IR_CAM_RIGHT);

    // 取得帧缓存大小。
    // 说一下这一步的目的,由于打开不同组件(打开哪些组件),以及不同组件参数设定(分辨率)的原因,每一帧数据的大小是不固定的,
    // 所以要用此函数计算一下当前设备以及当前设定下,一帧数据出来,需要多大的缓存buffer。
    // 因为后面需要压入buffer队列进行数据读取,所以要保证buffer的大小能否装下一帧数据。
    int32_t frameSize;
    TYGetFrameBufferSize(hDevice, &frameSize);

    // 驱动内部维护一个queue,用户往队列中enqueue空的buffer,
    // 设备用每一帧的framedata去填充这个空的buffer,填充后,将此buffer弹出队列(dequeue),返回给用户使用。
    // 这几个buffer是循环使用的,弹出被用户取出数据后,又会回到队列尾部。理论上将,只需要两个buffer即可循环使用。
    int frameBuffer_number = 3;
    char* frameBuffer[frameBuffer_number];
    for (int i = 0; i < frameBuffer_number; ++i)
    {
        frameBuffer[i] = new char[frameSize];
        TYEnqueueBuffer(hDevice, frameBuffer[i], frameSize);
    }

    //开始拍摄
    TYStartCapture(hDevice);

    //取景后不断有帧输出,需要循环取得帧数据,并进行解析输出。
    TY_FRAME_DATA frame;
    cv::Mat depth, irl, irr, color;
    while(1)
    {
        // 取得帧
        TYFetchFrame(hDevice, &frame, -1);

        // 这句为整个程序的核心,解析得到的帧,解析为cv::Mat类型的图像,跟OpenCV对接后即可进行后续的处理。 defined in Utils.hpp line36
        parseFrame(frame, &depth, &irl, &irr, &color, 0);

        //图像显示
        cv::imshow("Depth", depth);
        cv::imshow("LeftIR", irl);
        cv::imshow("RightIR", irr);
        cv::imshow("Color", color);

        //检测
        if (cv::waitKey(1) == 'q') { break; }

        // 这里就是申请的buffer循环使用的根本,每次buffer被dequeue用户取得帧后,在这个帧处理函数中,最后又把当前的buffer压入队列中,循环使用,
        // 由于队列特性,队首出列,队尾入列,所以会有循环使用的样子。
        TYEnqueueBuffer(hDevice, frame.userBuffer, frame.bufferSize);
    }

    //停止拍摄。
    TYStopCapture(hDevice);
    //关闭设备。
    TYCloseDevice(hDevice);
    //反初始化,注销API。
    TYDeinitLib();
    //delete释放内存。
    for (int j = 0; j < frameBuffer_number; ++j)
    {
        delete frameBuffer[j];
    }

    return 0;
}

先一句句来说:
第一句 :#include "../common/Utils.hpp"
这是一个工具头文件:

#ifndef SAMPLE_COMMON_UTILS_HPP_
#define SAMPLE_COMMON_UTILS_HPP_

#include <opencv2/opencv.hpp>
#include "TY_API.h"

static inline const char* colorFormatName(TY_PIXEL_FORMAT fmt){...}

static inline const TY_IMAGE_DATA* TYImageInFrame(const TY_FRAME_DATA& frame, const TY_COMPONENT_ID comp){...}

static inline int parseFrame(const TY_FRAME_DATA& frame, cv::Mat* pDepth, cv::Mat* pLeftIR, cv::Mat* pRightIR, cv::Mat* pColor, cv::Mat* pPoints){...}

#endif

函数的实现略掉,仅看结构。很简单,包含了opencv头文件和TY自己的API头文件。这是最低配了,因为显示图像要用到opencv,API自然也不必说。然后就是三个静态内联函数,主要看第三个:parseFrame() 。这个函数也是第7步中用于解析帧数据的函数,是本程序的核心函数,也就是通过它,将从设备取出的frame数据解析成opencv下cv::Mat格式的各个图像,用于后续的处理。

紧接着是流程中的第一步,初始化。也就是main函数中的TYInitLib(); 没什么好说的,就一个无参函数。

这两句是流程中第二步的打开设备

TY_DEV_HANDLE hDevice;
TYOpenDevice("207000000866", &hDevice);

首先看一下TYOpenDevice("207000000866", &hDevice); 函数的原型:

/// @brief Open device by device ID.
/// @param  [in]  deviceID      Device ID string, can be get from TY_DEVICE_BASE_INFO.
/// @param  [out] deviceHandle  Handle of opened device.
/// @retval TY_STATUS_OK        Succeed.
/// @retval TY_STATUS_NOT_INITED        TYInitLib not called.
/// @retval TY_STATUS_NULL_POINTER      deviceID or deviceHandle is NULL.
/// @retval TY_STATUS_INVALID_PARAMETER Device not found.
/// @retval TY_STATUS_BUSY              Device has been opened.
/// @retval TY_STATUS_DEVICE_ERROR      Open device failed.
TY_CAPI TYOpenDevice              (const char* deviceID, TY_DEV_HANDLE* deviceHandle);

可以看出,需要输出字符串类型的deviceID,和一个设备管理器指针类型的deviceHandle。
deviceHandle好弄,上一句定义一下就好了。而且他是一个输出承接参数,将deviceID对应的这台设备绑定这里定义的deviceHandle。
那deviceID这里是为了简化,获取后将获取程序去掉,直接用ID进行设备打开(因为我只有一台设备,ID也不会变,所以获取后即可直接用,好处是代码简化,坏处是代码不具有兼容性)。
那到底是如何获取设备ID的呢?其实是利用TYGetDeviceList()函数

//定义设备基本信息指针,用于承接后续得到的多个设备的信息,因为有可能连接多个设备。
TY_DEVICE_BASE_INFO* pBaseInfo;
//取得设备列表,结果存放在pBaseInfo数组中。
TYGetDeviceList(pBaseInfo, 100, &n)//这里即为打开第1个设备。利用第一个设备对应的ID。如果有很多设备的话,往后罗列即可。
TYOpenDevice(pBaseInfo[0].id, &hDevice)

看一下TY_DEVICE_BASE_INFO 结构体的定义:

typedef struct TY_DEVICE_BASE_INFO
{
    TY_INTERFACE        devInterface;       ///< interface, see TY_INTERFACE_LIST
    char                id[32];
    char                vendorName[32];     
    char                modelName[32];
    TY_VERSION_INFO     hardwareVersion;
    TY_VERSION_INFO     firmwareVersion;
    TY_DEVICE_NET_INFO  netInfo;
    TY_STATUS           status;
    char                reserved[248];
}TY_DEVICE_BASE_INFO;

发现可以输出很多设备的基本信息,不光包括ID,还有供应商信息、型号、硬件版本、固件版本、网络信息、状态等。反正就是用它能得到关于设备的很多信息就是了。然后用.ID 得到ID,传入设备打开函数。

继续看,到第三步,使能组件:

TYEnableComponents(hDevice, TY_COMPONENT_RGB_CAM | TY_COMPONENT_DEPTH_CAM | TY_COMPONENT_IR_CAM_LEFT | TY_COMPONENT_IR_CAM_RIGHT);

先看一下函数原型:

/// @brief Enable components.
/// @param  [in]  hDevice       Device handle.
/// @param  [in]  componentIDs  Components to be enabled.
/// @retval TY_STATUS_OK        Succeed.
/// @retval TY_STATUS_INVALID_HANDLE    Invalid device handle.
/// @retval TY_STATUS_INVALID_COMPONENT Some components specified by componentIDs are invalid.
/// @retval TY_STATUS_BUSY      Device is capturing.
TY_CAPI TYEnableComponents        (TY_DEV_HANDLE hDevice, int32_t componentIDs);

它需要两个输入参数,第一个就是上方绑定好的设备管理器hDevice 。第二个是组件ID,注意看,它的类型是int32_t 也就是说是一个数字!也就是说我用这个数字,来控制到底使能哪些组件!背后应该是有将各个组件对应成数字,然后用于使能,OK,找到了这个(TY_API.h line 154):

typedef enum TY_DEVICE_COMPONENT_LIST
{
    TY_COMPONENT_DEVICE         = 0x80000000, ///< Abstract component stands for whole device, always enabled
    TY_COMPONENT_DEPTH_CAM      = 0x00010000, ///< Depth camera
    TY_COMPONENT_POINT3D_CAM    = 0x00020000, ///< Point3D camera
    TY_COMPONENT_IR_CAM_LEFT    = 0x00040000, ///< Left IR camera
    TY_COMPONENT_IR_CAM_RIGHT   = 0x00080000, ///< Right IR camera
    TY_COMPONENT_RGB_CAM_LEFT   = 0x00100000, ///< Left RGB camera
    TY_COMPONENT_RGB_CAM_RIGHT  = 0x00200000, ///< Right RGB camera
    TY_COMPONENT_LASER          = 0x00400000, ///< Laser
    TY_COMPONENT_IMU            = 0x00800000, ///< Inertial Measurement Unit
    TY_COMPONENT_BRIGHT_HISTO   = 0x01000000, ///< virtual component for brightness histogram of ir 

    TY_COMPONENT_RGB_CAM        = TY_COMPONENT_RGB_CAM_LEFT /// Some device has only one RGB camera, map it to left
}TY_DEVICE_COMPONENT_LIST;
typedef int32_t TY_COMPONENT_ID;

这里发现了,组件ID就是一个数字!不过不是随便一个数字,而是在TY_DEVICE_COMPONENT_LIST 枚举中定义的这些。总体的思路应该是每个组件被对应成了一个16进制的数字也就是枚举中体现的这些。需要使能它们或者其他操作时,本质上是直接输入数字即可,但是肯定不会直接输入数字,因为输入枚举值更能直观的对应是哪个组件。另外还有就是代码中的按位或运算| 这在嵌入式中用法应该是同时打开各个位。
看一下0x00010000 -0x00080000 在内存中的存储形式(int32_t为32位,0x代表十六进制,转换为2进制后,高位补0即可):

0000 0000 0000 0001 0000 0000 0000 0000
0000 0000 0000 0010 0000 0000 0000 0000
0000 0000 0000 0100 0000 0000 0000 0000
0000 0000 0000 1000 0000 0000 0000 0000

可以非常明晰的发现各个组件其实就是对应一个32位bit串中的一个位置,在处理的时候,设备按位去读取值,每一位对应一个组件,若为1,则使能,若为0则不使能。而按位与| 操作能够一次性的将各个位上的1合并到一个数字上去,比如上面的四个做| 操作会得到:0000 0000 0000 1111 0000 0000 0000 0000 这样,将此数字传入函数,会一次性使能4个组件。所以程序中也将4个组件| 操作,同时使能。分别是彩色摄像头,深度摄像头,左右两个红外摄像头。

到了第五步,将帧缓存压入队列

    int32_t frameSize;
    TYGetFrameBufferSize(hDevice, &frameSize);

    int frameBuffer_number = 100;
    char* frameBuffer[frameBuffer_number];
    for (int i = 0; i < frameBuffer_number; ++i)
    {
        frameBuffer[i] = new char[frameSize];
        TYEnqueueBuffer(hDevice, frameBuffer[i], frameSize);
    }

这里一开始有点糊涂,先仔细的看一下文档:

5 给驱动程序分配 framebuffer。
(a) 查询当前配置下每个 framebuffer 的大小。
(b) 分配 framebuffer 并压入驱动内的缓冲队列。
驱动内部维护一个缓冲队列(buffer queue),每帧数据传出时会将填充好的 buffer 作 dequeue
操作,并完全传出给用户使用。用户需要保证新的一帧数据到来时驱动的缓冲队列 buffer queue
不为空,否则该帧数据将被丢弃。

打个比喻说一下相机将帧传送到外部的流程:
缓冲队列:食堂打饭窗口,
buffer:餐盘,
帧:鸡腿。
打饭大妈固定时间往窗口上扔一个鸡腿(相机固定时间采集一帧数据输出),假如底下有盘子(队列里面有buffer,不为空),接住了鸡腿(buffer被帧数据填充),那么将这个盘子端走去吃(将填充好的buffer弹出列,供用户使用)。
那由于大妈是固定时间扔一个鸡腿,所以为了不损失鸡腿(不丢帧),我们需要注意三个问题:
1、大妈开始扔鸡腿前(开始拍摄前),我必须先放上至少一个盘子(先将队列压入至少一个buffer)。
2、在装了鸡腿后(填充了buffer)走了(将buffer弹出队列)时,下一刻的鸡腿没地方放了!这个鸡腿要被扔地上了(要丢帧)!所以,最开始我们准备至少2个盘子先放在台子上(取景前先压入两个缓冲buffer),这样端走一个鸡腿去吃的时候(弹出队列去处理的时候),后面的不至于扔了。
3、另外你吃完鸡腿后(用户处理完后),空的盘子还是要放回台子上循环接鸡腿(还是要继续将buffer压入队列)。

另外还有一个问题就是要先确定大妈扔的是鸡腿有多大,是火鸡腿还是小鸡腿,好准备盘子大小(获取buffer大小,以免装不下frame)。

综上,所以我们看到的结果就是,在TYStartCapture(hDevice); 之前,压入了两个buffer。且在处理完当前帧后,又将此buffer压入队列,以供循环使用。其实这里可以压入更多,以防丢帧,只要能保证处理的时间小于下一帧到来时所需的时间即可,但也不能无限多,会吃内存。

然后第五步开始拍摄:TYStartCapture(hDevice); 没什么说的,需要传入设备管理器。

第678步是一组循环操作,
获取帧:TYFetchFrame(hDevice, &frame, -1);
解析帧:parseFrame(frame, &depth, &irl, &irr, &color, 0);
显示图像:cv::imshow()
其中解析帧数据的时候,就用到了Utils.hpp中定义的函数。
每次循环操作结束后,一定记得将buffer再压入队列,不然盘子就用空了。。。。

后面的几步就没什么说的了,流程化操作。

    //停止拍摄。
    TYStopCapture(hDevice);
    //关闭设备。
    TYCloseDevice(hDevice);
    //反初始化,注销API。
    TYDeinitLib();

最后记得释放申请的内存,以防泄露:

    for (int j = 0; j < frameBuffer_number; ++j)
    {
        delete frameBuffer[j];
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

图漾深度摄像头基本使用方法 的相关文章

  • 什么是物联网?发展前景如何?

    物联网其实是互联网的一个延伸 xff0c 互联网的终端是计算机 PC 服务器 xff0c 我们运行的所有程序 xff0c 无非都是计算机和网络中的数据处理和数据传输 xff0c 除了计算机外 xff0c 没有涉及任何其他的终端 硬件 物联网
  • Linux上压缩文件的 5 种方法

    在 Linux 上有不少用于压缩文件的命令 最新最有效的一个方法是 xz xff0c 但是所有的方法都有节省磁盘空间和维护备份文件供以后使用的优点 在这篇文章中 xff0c 我们将比较这些压缩命令并指出显著的不同 tar tar 命令不是专
  • 新手如何从零开始学习unity

    自从 unity5发布免费过后 xff0c 有很多独立游戏开发者转向unity游戏开发 xff0c unity的优势就是多终端 跨平台打包 xff0c 入门也快 xff0c 很多人感觉自己的英文不好 xff0c 就觉得学不会 xff0c 其
  • stm32零基础入门,应学习那些知识

    1 首先我们先看看与STM32相关的文档 我们假定大家已经对STM32的书籍或者文档有一定的理解 如不理解 xff0c 请立即阅读STM32的文档 xff0c 以获取最基本的知识点 如果你手上拥有ST官方主推的STM32神舟系列的板子 xf
  • Java如何实现二维码扫码授权登陆

    如今的生活中 xff0c 登录网站也变得如此简单 xff0c 当你已经登录一微信时 xff0c 当你想要登录另一个网站时 xff0c 只需扫码便可 xff0c 可是大家知道用Java怎么实现扫码授权吗 本文讲述的就是关于如何用Java实现扫
  • Postman安装与简单使用

    Postman使用参考文档 xff1a 1 官方英文文档 2 chrome插件整理的 postman中文使用教程 Postman一款非常流行的API调试工具 其实 xff0c 开发人员用的更多 因为测试人员做接口测试会有更多选择 xff0c
  • c语言入门基础

    C语言的结构 1 Hello world 简单来说 xff0c 一个C程序就是由若干头文件和函数组成 include 包含头文件 主函数 int main printf Hello World return 0 include 就是一条预处
  • 单片机串行口介绍

    介绍 串行口是单片机与外界进行信息交换的工具 xff0c 8051单片机的通信方式有两种 xff1a 并行通信 数据的各位同时发送或接收 串行通信 数据一位一位次序发送或接收 串行通信的方式 异步通信 用一个起始位0表示字符的开始 xff0
  • 51单片机中断机制(定时器)

    单片机中断简介 52单片机一共有6个中断源 xff0c 它们的符号 xff0c 名称以及各产生的条件分别如下 xff1a INT0 外部中断0 xff0c 由P3 2端口线引入 xff0c 低电平或下降沿引起 INT1 外部中断1 xff0
  • 什么叫51单片机最小系统

    单片机最小系统 或者称为最小应用系统 是指用最少的元件组成的单片机可以工作的系统 对51系列单片机来说 最小系统一般应该包括 单片机 晶振电路 复位电路 下面给出一个51单片机的最小系统电路图 说明 复位电路 由电容串联电阻构成 由图并结合
  • 嵌入式系统C编程之错误处理

    一 错误概念 1 1 错误分类 从严重性而言 xff0c 程序错误可分为致命性和非致命性两类 对于致命性错误 xff0c 无法执行恢复动作 xff0c 最多只能在用户屏幕上打印出错消息或将其写入日志文件 xff0c 然后终止程序 而对于非致
  • 补光灯的单片机开发设计

    说到摄影灯 xff0c 相信每个人都一定听说过闪光灯和补光灯 那它们是怎么由来的呢 又是怎么达到了你想要的效果呢 不论是闪光灯还是补光灯 xff0c 它们都有一个共同点 xff0c 那就是由NY8A051D单片机开发而来 xff0c 单片机
  • 单片机C语言如何产生随机数

    单片机C语言如何产生随机数 随机数在单片机的应用中也是很多的 xff0c 当然产生随机数的方法有很多 xff0c 当中有一个就是利用单片机定时器 xff0c 取出未知的定时器THX和TLX的值 xff0c 再加以运算得到一个规定范围内的随机
  • 使用mac终端编译运行c程序

    使用mac终端编译运行c程序 本文介绍如何利用mac自带文本编辑软件编写c代码 xff0c 并在mac自带终端内用命令行编译运行c程序 1 在mac上安装c编译环境 打开mac自带的终端 在终端命令行里输入xcode select inst
  • HtmlParser 一个不错的网站爬虫工具

    有时候我们需要在网上获取自己需要的内容时 xff0c 而且需求量达到一定程度时 xff0c 就要通过代码来实现重复的操作 当用Java来帮我们解决这个问题时 xff0c 我们又如何通过Java来过滤掉多余的内容 xff0c 剩余自己想要的信
  • 因为jsoup,再见了我的htmlparser

    jsoup 一款Java 的HTML解析器 xff0c 可直接解析某个URL地址 HTML文本内容 它提供了一套非常省力的API xff0c 可通过DOM xff0c CSS以及类似于jQuery的操作方法来取出和操作数据 这里是jsoup
  • Python 当前时间是那一年第几周的周几

    isocalendar 函数 返回 xff08 XX年 xff0c 一年中的第几周 xff0c 这一天是周几 xff09 gt gt gt from datetime import datetime gt gt gt datetime no
  • 对Socket CAN的理解(1)——【CAN总线原理】

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 由于Socket CAN涉及到CAN总线协议 套接字 Linux网络设备驱动等 因此 xff0c 为了能够全面地了解Socket CAN的
  • 对Socket CAN的理解(2)——【Socket的原理及使用】

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 为了能够对Socket CAN的深入理解 xff0c 我们需要了解Socket的机制 Socket的中文翻译为 插座 xff0c 在计算机
  • 【智能家居篇】wifi网络结构(上)

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 WIFI是什么 xff0c 相信大家都知道 xff0c 这里就不作说明了 我们需要做的是深入了解其工作原理 xff0c 包括软硬件 网络结

随机推荐

  • 【智能家居篇】wifi网络结构(下)

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 由于WIFI网络具有移动性 xff0c 同时WIFI以无线电波作为传输媒介 xff0c 这种媒介本质上是开放的 xff0c 且容易被拦截
  • 【智能家居篇】wifi网络接入原理(上)——扫描Scanning

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 对于低头党来说 xff0c 在使用WIFI功能时 xff0c 经常性的操作是打开手机上的WIFI设备 xff0c 搜索到心目中的热点 xf
  • 【智能家居篇】wifi网络接入原理(下)——关联Association

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 认证完成后 xff0c 下一步就是关联 xff08 Association xff09 工作站与基站进行关联 xff0c 以便获得网络的完
  • 【智能家居篇】wifi驱动的理解(3)——usb接口在wifi模块中的角色

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 上一篇文章已经提到USB接口在wifi模块中的最重要两个函数是usb read port 和usb write port 那它们是怎么和w
  • 【智能家居篇】wifi驱动的理解(4)——usb接口在wifi模块中的角色

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 还有1天就到2017年了 xff0c 回顾整个2016年至此 xff0c 都没发表过一篇技术文章 做软件开发已有5 6年 xff0c 作为
  • mx51 TVOUT分析

    1397 static int init enable tve setup char options 1398 1399 g enable tve 61 true 1400 1401 return 1 1402 1403 setup 34
  • 2D图形加速引擎(GE2D)

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 英文原文 NUC970 Series Technical Reference Manual Chapter 5 28 一 概述 32位2D
  • Redis 安装

    安装 下载 解压 编译Redis wget http download redis io releases redis 6 0 6 tar gz tar xzf redis 6 0 6 tar gz cd redis 6 0 6 make
  • linux下 tcpdump实现原理

    linux下抓包实现原理 一 tcpdump 对于本机中进程的系统行为调用跟踪 xff0c strace是一个很好的工具 xff0c 而在网络问题的调试中 xff0c tcpdump应该说是一个必不可少的工具 xff0c 和大部分linux
  • eigen求特征值和特征向量

    Eigen Matrix2d matrix 22 matrix 22 lt lt 2 3 2 1 cout lt lt 34 matrix 61 n 34 lt lt matrix 22 lt lt endl Eigen SelfAdjoi
  • sophus库的一些使用

    首先是cmakelists cmake minimum required VERSION 2 8 project useSophus 为使用 sophus xff0c 您需要使用find package命令找到它 find package
  • OpenCV中ORB特征点检测和匹配简单用法

    cmakelists span class hljs keyword cmake minimum required span VERSION span class hljs number 3 7 span span class hljs k
  • LKflow

    cmakelists span class hljs keyword cmake minimum required span VERSION span class hljs number 3 7 span span class hljs k
  • 关于关于高博3d2d程序报错的改动

    想直接改动 xff0c 在 还是g2o初始化一些 那篇 xff0c 这篇比较啰嗦 xff0c 主要是记录自己思考的步骤 首先说明主题 xff1a 没文化真可怕 好了 xff0c 说干货 之前高博的代码 只要涉及g2o的部分 xff0c 一律
  • C++类内成员初始化

    所有标准为C11标准 xff0c 旧的就不看了 首先说一条指导规则 xff1a 通常情况下 xff0c 不应该在类内部初始化成员 xff01 xff01 无论是否为静态 是否为常量 是否为int等 xff01 xff01 统统不建议在类内初
  • RANSAC算法理解

    最早应该是十四讲上见过 xff0c 在第九章的project中src中的visual odometry cpp中 xff0c 最核心的求解3d 2d的变换中 xff1a span class hljs label 整个核心就是用这个cv s
  • 装双系统的一些记录

    小米电脑F2进入BIOS设置 xff0c F12选取启动项 启动U盘制作 ROS安装
  • ROS使用注意事项

    看到一篇总结 xff0c 感觉很有用 摘抄下来 转自 xff1a https www cnblogs com pk28 p 7625838 html
  • Python time模块 时间戳转换

    时间戳转换 时间戳获取 import time time time 时间戳转时间字符串 时间戳 gt 时间数组 gt 格式化时间字符串 时间字符串转时间戳 格式时间字符串 gt 时间数组 gt 时间数组 时间戳转换时间字符串 time st
  • 图漾深度摄像头基本使用方法

    搞到一款图漾的3d相机 xff08 型号为FM810 C xff09 有好久了 xff0c 一直也只是编译了sample代码跑起来看看样子 xff0c 并没有着手看SDK以及开发的事 近几日对照SDK以及其中的SimpleView Fetc