使用VideoPipe视频分析框架做车辆检索

车辆检索是ReID技术的一种具体实现,跟以图搜图类似,需要使用CNN网络预提取海量车辆样本特征并进行存储(附带一些结构化属性),在检索阶段,再使用向量比对技术从海量样本中查询Top N的相似结果并返回。那么前期预提取海量车辆样本特征(以及结构化属性)该如何实现呢?VideoPipe视频分析框架能够胜任99%的视频结构化需求,覆盖了人脸识别、目标行为分析、车辆检索等等应用场景。VideoPipe完全开源(仅供学习),github地址(github.com/sherlockchou86/video_pipe_c)

下面介绍使用VideoPipe实现车辆检索的过程。

车辆检索应用主要环节

  1. 提取特征&结构化属性
  2. 海量特征存储&结构化数据存储
  3. 海量特征比对&关系型数据库检索

其中第2、3步骤暂不涉及,重点讲述第一步。一般提取得到的车辆图像特征都是高维数据,比如256维float型数组、甚至1204维float数组。这些高维数据一般无法被人类直观理解。在提取特征的同时,我们还可以为车辆图像提取结构化属性,比如是白车还是黑车、是小卡车还是大卡车、有天窗还是没天窗等等。我们将提取到的高维特征数据和结构化属性同时存档(存入不同类型数据库),当作待检索数据集。下面列举车辆检索第一步骤提取到的数据可能有哪些:

  1. 颜色:白色、黑色、蓝色、灰色、黄色、红色
  2. 车型:轿车、SUV、皮卡、大卡、小卡、厢式货车、大巴、依维柯
  3. 天窗:有、无
  4. 车牌:未知、具体车牌值
  5. 图像特征:[0.231230, -0.092778, 0.289908 …]

提取特征&结构化属性的实现

VideoPipe视频分析框架可以快速集成目标检测、图像分类、特征提取等神经网路图像算法,支持多种视频(图片)接入方式,下面代码读取指定目录下的图片,先后进行车辆检测、车型分类、特征提取等操作,最后基于车辆检测和分类的结果、以及提取得到的特征值做显示和聚合。

#include "VP.h"

#include "../nodes/vp_image_src_node.h"
#include "../nodes/vp_file_src_node.h"
#include "../nodes/infers/vp_trt_vehicle_detector.h"
#include "../nodes/infers/vp_trt_vehicle_color_classifier.h"
#include "../nodes/infers/vp_trt_vehicle_type_classifier.h"
#include "../nodes/infers/vp_trt_vehicle_feature_encoder.h"
#include "../nodes/track/vp_sort_track_node.h"
#include "../nodes/osd/vp_osd_node.h"
#include "../nodes/osd/vp_cluster_node.h"
#include "../nodes/vp_screen_des_node.h"
#include "../nodes/vp_fake_des_node.h"

#include "../utils/analysis_board/vp_analysis_board.h"

/*
* ## vehicle_cluster_based_on_classify_encoding_sample ##
* vehicle cluster based on classify(categories) and encoding(features), pipeline would display 3 windows (cluster by t-SNE, cluster by categories, detect osd result)
*/

#if vehicle_cluster_based_on_classify_encoding_sample

int main() {
    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
    VP_LOGGER_INIT();

    // create nodes
    auto image_src_0 = std::make_shared<vp_nodes::vp_image_src_node>("image_src_0", 0, "./images/vehicle/%d.jpg");
    //auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, "./test_video/22.mp4");
    auto trt_vehicle_detector = std::make_shared<vp_nodes::vp_trt_vehicle_detector>("trt_detector", "./models/trt/vehicle/vehicle_v8.5.trt");
    auto trt_vehicle_color_classifier = std::make_shared<vp_nodes::vp_trt_vehicle_color_classifier>("trt_color_cls", "./models/trt/vehicle/vehicle_color_v8.5.trt", std::vector<int>{0, 1, 2});
    auto trt_vehicle_type_classifier = std::make_shared<vp_nodes::vp_trt_vehicle_type_classifier>("trt_type_cls", "./models/trt/vehicle/vehicle_type_v8.5.trt", std::vector<int>{0, 1, 2});
    auto trt_vehicle_feature_encoder = std::make_shared<vp_nodes::vp_trt_vehicle_feature_encoder>("trt_encoder", "./models/trt/vehicle/vehicle_embedding_v8.5.trt", std::vector<int>{0, 1, 2});
    auto osd_0 = std::make_shared<vp_nodes::vp_osd_node>("osd_0");
    auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);
    auto cluster_0 = std::make_shared<vp_nodes::vp_cluster_node>("cluster_0", true, std::vector<std::string>{"red", "white", "black", "blue", "yellow", "bus", "small_truck", "van", "tanker"}, 1000);
    auto fake_des_0 = std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_0", 0);
    
    // construct pipeline
    trt_vehicle_detector->attach_to({image_src_0});
    //trt_vehicle_detector->attach_to({file_src_0});
    trt_vehicle_color_classifier->attach_to({trt_vehicle_detector});
    trt_vehicle_type_classifier->attach_to({trt_vehicle_color_classifier});
    trt_vehicle_feature_encoder->attach_to({trt_vehicle_type_classifier});
    
    // split into 2 branches automatically
    /* branch of osd -> screen des*/
    osd_0->attach_to({trt_vehicle_feature_encoder});
    screen_des_0->attach_to({osd_0});
    /* branch of cluster -> fake des*/
    cluster_0->attach_to({trt_vehicle_feature_encoder});
    fake_des_0->attach_to({cluster_0});  // to keep pipeline complete

    // start pipeline
    image_src_0->start();
    //file_src_0->start();

    // visualize pipeline for debug
    //vp_utils::vp_analysis_board board({file_src_0});
    vp_utils::vp_analysis_board board({image_src_0});
    board.display();
}

#endif

上面代码运行后,可以显示4个窗口,分别是:

  1. Pipeline管道运行状态
  2. 车辆检测结果
  3. 车辆按分类标签(车型、颜色)显示
  4. 车辆按特征自动聚合(相似车辆聚合到一起)

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值