特征提取

功能介绍

通过构造Sift类实例可实现对输入的图像进行特征提取。给定输入图片张量以及用于限制特征提取区域的掩模矩形框,调用特征提取接口执行相应的模型推理,输出提取的特征点列表及描述子列表。

使用Sift类进行特征点提取时,需要提前生成构建尺度空间的om模型,可按照如下步骤进行。

  1. 设置CANN开发套件包的环境变量,本次步骤中${CANN_INSTALL_PATH}以普通用户默认路径(“$HOME”)为例。
    1
    . ${CANN_INSTALL_PATH}/ascend-toolkit/set_env.sh
    
  2. 设置Vision SDK开发套件包的环境变量,其中${MX_SDK_HOME}Vision SDK安装目录。
    1
    . ${MX_SDK_HOME}/set_env.sh
    
  3. 进入Vision SDK安装目录。
    1
    cd ${MX_SDK_HOME}
    
  4. 创建并进入存放模型权重文件的目录“data”
    1
    2
    mkdir data
    cd data
    
  5. 执行“${MX_SDK_HOME}/bin”目录下的“generate_sift_weights.py”创建模型所需的权重文件。
    1
    python3 ../bin/generate_sift_weights.py
    
  6. 进入Vision SDK安装目录下的“bin”文件。
    1
    cd ${MX_SDK_HOME}/bin
    
  7. 执行可执行文件“sift”创建om模型,支持传入芯片版本参数“soc_version”
  8. Atlas 200I A2 加速模块(20 TOPS,12GB)对应芯片版本名称为“Ascend310B*”,其中“*”可能根据芯片性能提升等级、芯片核数使用等级等因素会返回不同的值,具体类型可通过npu-smi info查询获取。
    ./sift soc_version

接口调用流程

图1 特征提取接口调用流程
  1. 调用MxInit()接口进行全局初始化。
  2. 调用特征提取接口前,需初始化ImageProcessor,调用ImageProcessor的图片解码接口得到输入图像Image,具体请参见图片解码
  3. 调用Image类的ConvertToTensor接口将输入图像转化为张量。
  4. 由于Sift的特征提取仅支持单通道图像,因此,需要调用Tensor类的CvtColor接口,将张量转化为单通道灰度图张量,数据排布格式为HWC,具体操作流程请参见色域转换
  5. 定义输入的掩码矩形框,用于限制需要计算特征的区域,针对该区域内的图像进行特征提取。矩形框对应的左上角坐标及右下角坐标需在图片有效范围内。
  6. 定义特征点列表及描述子列表,支持用户自己对特征点列表赋值,接口将使用用户定义的特征点直接生成描述子
  7. 构造特征提取类,并初始化模型提取资源。

    如需在构造特征提取类时调整参数值,请注意对异常情况进行处理,建议使用try/catch捕获异常。

  8. 调用特征提取接口进行计算。
  9. 调用MxDeInit()接口对初始化的全局资源进行去初始化。

示例代码

以下为特征提取接口的功能特性关键步骤的代码示例,不可以直接拷贝编译运行,仅供参考。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// 初始化
MxBase::MxInit();

{
    // 构造图像处理类
    MxBase::ImageProcessor imageProcessor(deviceId);

    // 图像解码操作生成Image
    // 解码后的图像类
    MxBase::Image image;

    //根据图像路径进行解码
    APP_ERROR ret = imageProcessor.Decode(imagePath, image);
    if (ret != APP_ERR_OK) {
        return 0;
    }

    // 将图像转换为张量,且张量排布格式为HWC
    MxBase::Tensor tensor = image.ConvertToTensor(true, false);

    // 通过张量方法对图像进行色域转换
    // 定义色域转换类型
    auto mode = MxBase::CvtColorMode::COLOR_YUVSP4202GRAY;

    // 定义输出张量
    MxBase::Tensor imgTensor;

    // 执行色域转换
    MxBase::CvtColor(tensor, imgTensor, mode, true);
 
    // 定义掩码矩形框
    MxBase::Rect mask = MxBase::Rect(x0, x1, y0, y1);
 
    // 定义特征点列表
    vector<cv::KeyPoint> keyPoints;
 
    // 定义描述子列表
    cv::Mat descriptors;

    try {
        // 构造特征提取类
        Sift sift(nFeatures, nOctaveLayers, contrastThreshold, edgeThreshold, sigma, descriptorType);
 
        // 初始化模型特征提取资源
        sift.Init(deviceId);
 
        // 执行特征提取
        sift.DetectAndCompute(imgTensor, mask, keyPoints, descriptors, false);
    } 
    catch (runtime_error error) {
        return 0;
    }
}

// 去初始化
MxBase::MxDeInit();