DynaSLAM-7 DynaSLAM中双目运行流程(Ⅰ):加载Mask R-CNN网络部分MaskNet.cc

news2025/1/11 4:14:29

目录

1.执行流程

2. SegmentDynObject::SegmentDynObject

3. SegmentDynObject::GetSegmentation 


1.执行流程

        我们输入到命令行五个参数:

stereo_kitti path_to_vocabulary path_to_settings path_to_sequence (path_to_masks)

        分别是DynaSLAM双目例程中的可执行文件stereo_kittt、ORB字典文件、配置文件、序列文件、以及可选的存储mask的文件。

        输入完成后,我们便执行起了双目例程,首先进入的是LoadImages函数:

ORB-SLAM2 ---- LoadImages函数解析https://blog.csdn.net/qq_41694024/article/details/126285573        LoadImages函数的主要作用是将双目图像分割:将左目图像存储进vstrImageLeft容器中、右目图像存储进vstrImageRight容器中、对应的时间戳存储进vTimestamps中。

        随后我们就开始加载MaskRCNN网络了:

    // Initialize Mask R-CNN
    cout << "Loading Mask R-CNN. This could take a while..." << endl;
    DynaSLAM::SegmentDynObject *MaskNet;
    if (argc==5){
         MaskNet = new DynaSLAM::SegmentDynObject();
    }
    cout << "Mask net loaded!" << endl;

2. SegmentDynObject::SegmentDynObject

        这个类方法首先做的就是通过ImportSettings加载Mask R-CNN网络配置:

void SegmentDynObject::ImportSettings(){
    std::string strSettingsFile = "./Examples/RGB-D/MaskSettings.yaml";
    cv::FileStorage fs(strSettingsFile.c_str(), cv::FileStorage::READ);
    fs["py_path"] >> this->py_path;
    fs["module_name"] >> this->module_name;
    fs["class_name"] >> this->class_name;
    fs["get_dyn_seg"] >> this->get_dyn_seg;
%YAML:1.0
py_path: "./src/python/"
module_name: "MaskRCNN"
class_name: "Mask"
get_dyn_seg: "GetDynSeg"

        主要是加载了几个参数:

        @py_path : src/python目录

        @module_name : MaskRCNN文件

        @class_name:Mask类

        @get_dyn_seg:GetDynSeg MaskRCNN中的方法获取mask信息

def GetDynSeg(image,image2=None):
	h = image.shape[0]
	w = image.shape[1]
	if len(image.shape) == 2:
		im = np.zeros((h,w,3))
		im[:,:,0]=image
		im[:,:,1]=image
		im[:,:,2]=image
		image = im
	#if image2 is not None:
	#	args+=[image2]
	# Run detection
	results = model.detect([image], verbose=0)
	# Visualize results
	r = results[0]
	i = 0
	mask = np.zeros((h,w))
	for roi in r['rois']:
		if class_names[r['class_ids'][i]] == 'person':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'bicycle':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'car':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'motorcycle':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'airplane':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'bus':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'train':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'truck':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'boat':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'bird':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'cat':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'dog':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'horse':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'sheep':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'cow':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'elephant':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'bear':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'zebra':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.
		if class_names[r['class_ids'][i]] == 'giraffe':
			image_m = r['masks'][:,:,i]
			mask[image_m == 1] = 1.		
		i+=1
	#print('GetSeg mask shape:',mask.shape)

	return mask

        setenv起到改变或增加环境变量的作用,用法如下:

        int setenv(const char *name,const char * value,int overwrite);

        @name为环境变量名称字符串。
        @value则为变量内容。

        @overwrite用来决定是否要改变已存在的环境变量。

        如果overwrite不为0,则改变环境变量原有内容,原有内容会被改为参数value所指的变量内容。如果overwrite为0,且该环境变量已有内容,则参数value会被忽略。
        @reuturn 执行成功则返回0,有错误发生时返回-1。

#include<stdlib.h>
main()
{
  char * p;
  if((p=getenv(“USER”)))
      printf(“USER =%s\n”,p);
  setenv(“USER”,”test”,1);
  printf(“USER=%s\n”,getenv(“USEr”));
  unsetenv(“USER”);
  printf(“USER=%s\n”,getenv(“USER”));
}

        执行结果:USER = root        USER = test          USER = (null)

setenv("PYTHONPATH", this->py_path.c_str(), 1);

        这里就是将./src/python文件夹设置为this->py_path。初始化Python虚拟环境。

namespace DynaSLAM
{

class SegmentDynObject{
private:
	NDArrayConverter *cvt; 	/*!< Converter to NumPy Array from cv::Mat */
	PyObject *py_module; 	/*!< Module of python where the Mask algorithm is implemented */
	PyObject *py_class; 	/*!< Class to be instanced */
	PyObject *net; 			/*!< Instance of the class */
	std::string py_path; 	/*!< Path to be included to the environment variable PYTHONPATH */
	std::string module_name; /*!< Detailed description after the member */
	std::string class_name; /*!< Detailed description after the member */
        std::string get_dyn_seg; 	/*!< Detailed description after the member */

	void ImportSettings();
public:

	SegmentDynObject();
        ~SegmentDynObject();
        cv::Mat GetSegmentation(cv::Mat &image, std::string dir="no_save", std::string rgb_name="no_file");
};

        初始化Numpy向cv::Mat的转化器cvt、导入py文库文件的过程:

        知识点请见博客:

如何在C++中使用一个Python类-[PyImport_ImportModule、PyModule_GetDict、PyDict_GetItemString、PyObject_CallFuncti]https://blog.csdn.net/Windgs_YF/article/details/91416252

SegmentDynObject::SegmentDynObject(){
    std::cout << "Importing Mask R-CNN Settings..." << std::endl;
    //fs["py_path"] >> this->py_path;
    //fs["module_name"] >> this->module_name;
    //fs["class_name"] >> this->class_name;
    //fs["get_dyn_seg"] >> this->get_dyn_seg;
    ImportSettings();
    std::string x;
    setenv("PYTHONPATH", this->py_path.c_str(), 1);
    x = getenv("PYTHONPATH");
    Py_Initialize();
    this->cvt = new NDArrayConverter();
    this->py_module = PyImport_ImportModule(this->module_name.c_str());
    assert(this->py_module != NULL);
    this->py_class = PyObject_GetAttrString(this->py_module, this->class_name.c_str());
    assert(this->py_class != NULL);
    this->net = PyInstance_New(this->py_class, NULL, NULL);
    assert(this->net != NULL);
    std::cout << "Creating net instance..." << std::endl;
    cv::Mat image  = cv::Mat::zeros(480,640,CV_8UC3); //Be careful with size!!
    std::cout << "Loading net parameters..." << std::endl;
    GetSegmentation(image);
}

        py_module 的类型是PyObject *类型,通过PyImport_ImportModule方法读入src/python目录下的MaskRCNN.py文件,如果读入文件为空报错。

        py_class 的类型是PyObject *类型,通过PyObject_GetAttrString方法导入已导入模块(MaskRCNN.py)中的方法或类(MaskRCNN.py中的Mask类)。

        net  的类型是PyObject *类型,通过PyInstance_New方法使用类构造对象。

        这样我们顺利地构造了MaskRCNN.py中的Mask类。

        下面我们创建网络实例:Creating net instance....,首先创建一个480*640的空白图像。

        调用GetSegmentation函数对该张图片进行处理。

3. SegmentDynObject::GetSegmentation 

cv::Mat SegmentDynObject::GetSegmentation(cv::Mat &image,std::string dir, std::string name){
    cv::Mat seg = cv::imread(dir+"/"+name,CV_LOAD_IMAGE_UNCHANGED);
    if(seg.empty()){
        PyObject* py_image = cvt->toNDArray(image.clone());
        assert(py_image != NULL);
        PyObject* py_mask_image = PyObject_CallMethod(this->net, const_cast<char*>(this->get_dyn_seg.c_str()),"(O)",py_image);
        seg = cvt->toMat(py_mask_image).clone();
        seg.cv::Mat::convertTo(seg,CV_8U);//0 background y 1 foreground
        if(dir.compare("no_save")!=0){
            DIR* _dir = opendir(dir.c_str());
            if (_dir) {closedir(_dir);}
            else if (ENOENT == errno)
            {
                const int check = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
                if (check == -1) {
                    std::string str = dir;
                    str.replace(str.end() - 6, str.end(), "");
                    mkdir(str.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
                }
            }
            cv::imwrite(dir+"/"+name,seg);
        }
    }
    return seg;
}

        本方法将传入的image进行语义分割,得到mask图。

        首先将image图片转换成tensor格式存储在py_image在,判断是否读取成功。

        通过PyObject_CallMethod方法调用(this -> net 是MaskRCNN.py中Mask类实例化的一个对象,this->get_dyn_seg 是该类中的一个方法求得图像的mask信息,再将其转化成图片格式保存起来。返回图像。

        现在Mask R-CNN网络初始化完毕,屏幕输出Mask net loaded!。

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

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

相关文章

血氧仪/额温枪/电子体温计等 LED数显/数码管显示驱动控制电路(IC/芯片)-VK1S68C资料 SSO24小体积封装,FAE技术支持

产品品牌&#xff1a;永嘉微电/VINKA 产品型号&#xff1a;VK1S68C 封装形式&#xff1a;SSOP24 概述&#xff1a; VK1S68C是一种带键盘扫描接口的数码管或点阵LED驱动控制专用芯片&#xff0c;内部集成有3线串行接口、数据锁存器、LED 驱动、键盘扫描等电路。SEG脚接LED阳极…

Go 项目(一)

目录基础环境包管理编码规范命名规范注释import 规范错误处理RPC内置 RPC改协议改调用基础 基础部分参考这个系列接下来的这部分是对上面的更新和重构&#xff0c;更加深入理解框架部分 环境 基础环境&#xff0c;主要在Linux上搞&#xff1b;最主要是 docker&#xff0c;do…

Mac 可以玩游戏吗,有哪些游戏可以玩?

Mac 可以玩游戏吗&#xff0c;有哪些游戏可以玩&#xff1f; 新款的 MacBook Pro 入手有一段时间了&#xff0c;期间一直在熟悉 MacOS 系统及日常工作使用&#xff0c;一直都听说 MacBook 是工作本&#xff0c;不得不说工作使用确实很强&#xff0c;但用的久了就还是特别想折腾…

flex 布局:实现一行固定个数,超出强制换行(流式布局)

一、flex 布局基础知识 flex 布局的知识想必不用多说&#xff0c;一些常用的属性如下&#xff1a; 设置在父容器上的属性&#xff1a;display&#xff1a;flex&#xff0c; align-items, justify-content, flex-wrap。 设置在子容器上的属性&#xff0c;通过 flex: 1&#x…

最终一致分布式事务方案解析

业来主流的分布式事务的解决方案主要归位两大类&#xff1a;强一致性分布式事务和最终一致性分布式事务&#xff0c;本文不对强一致性分布式事务做过多描述&#xff0c;主要针对最终一致性方案解析。 根据笔者的工作经验来看&#xff0c;最终一致性方案适用用大部分互联网场景…

SpringBoot 2.7.8 自定义 Starter 自动配置

文章目录SpringBoot 2.7.8 自定义 Starter前言本次练习的代码仓库代码简要说明custom-springboot-starter-demo 的pom文件customer-starter 的pom文件test 的pom文件配置类配置信息SpringBoot 2.7.8 自定义 Starter 前言 前段时间&#xff0c;SpringBoot 出 3.x 版本了。听说…

如何与他人交流 (如何跟老板提涨工资) 第16章

最重要的事情 ---强有力的论证上期我们说根据场景来优化策略,是在隔靴搔痒,然而一个容易给出理由的人很容易成为演讲的高手.说服别人的理性与感性举个例子&#xff0c;我们如果说服别人买一件商品。采用打广告的形式&#xff0c;往往有两种途径。比如说我们要买一辆车。展示它的…

Power BI瀑布图

瀑布图&#xff08;Waterfall Plot&#xff09;也被称为阶梯图&#xff0c;它出现的历史并不长&#xff0c;最初为麦肯锡所创&#xff0c;因自上而下形似瀑布而得名&#xff0c;面世之后以其展示效果清晰而流畅被广为接受&#xff0c;经常在经营和财务分析中使用。 瀑布图是根…

4d view软件 .vol .4dv转 dcom文件

一、 .vol转 dcom文件 1、4d view软件打开vol文件 2、settings--dicom configuration-add&#xff0c;设置如下&#xff08;前面的alias、ae title等设的可以随便一些&#xff0c;我都设了1&#xff09;&#xff0c;然后save&exit&#xff08;第6步设置也可以&#xff09…

Vue13-计算属性computed

首先使用methods方法实现属性计算 步入正题&#xff1a; 计算属性&#xff1a;拿已有的属性计算得出新的属性 1.vue中属性和计算属性是分开的&#xff0c;属性在data中&#xff0c;计算属性在computed中 computed中计算属性以对象的形式存贮 这里是将fullName以及get的返回值…

计算机网络基础学习指南(一)

前言 计算机网络基础是研发/运维工程师都需掌握的知识&#xff0c;但往往会被忽略。 今天&#xff0c;我将献上一份详细 & 清晰的计算机网络基础学习指南&#xff0c;涵盖 TCP / UDP协议、Http协议、Socket等&#xff0c;希望你们会喜欢。 1. 计算机网络体系结构 1.1 简…

深入理解ThreadLocal看这篇就够了-应用场景、内部原理、内存泄漏以及父子线程如何共享数据

为了帮助大家在项目中更好使用ThreadLocal&#xff0c;本文向大家介绍ThreadLocal原理和常见问题&#xff0c;具体内容如下&#xff1a;ThreadLocal是什么ThreadLocal的应用场景ThreadLocal的内部原理ThreadLocal内存泄露问题父子线程如何共享数据ThreadLocal是什么java.lang.T…

CCS10新建TMS320F28335工程

CCS10新建TMS320F28335工程 1. 新建工程 点击Project → New CCS Project。选择芯片类型(TMS320F28335)、仿真器类型(XDS200V3)、新建工程名称、选择新建一个空工程。 2. 配置工程选项 右键项目工程名&#xff0c;进入配置选项Proprrties。或者AltEnter打开配置选项。在工程…

gd32f103vbt6 串口OTA升级-问题记录-2-平衡OTA弊端

走在路上的时候&#xff0c;我想起了这个OTA的弊端&#xff0c;那我想有没有办法解决呢&#xff1f;其实是有的。 那就是我还是把app程序放在flash的最开始的位置&#xff0c;而把OTA的程序放到后面&#xff08;flash的最后12k&#xff09;去。 这样也带来新的弊端&#xff1…

PMP考试技巧PMP考试大纲

一&#xff0c;PMP解题策略 PMP考试默认条件 精准审题 E(Eye):找到题眼&#xff1b; K(Key):找到考点&#xff1b; C(Choice):确定 选项&#xff1b; 情景结合 基本知识从PMI的角度出发&#xff0c;按PMI的思维方式&#xff0c;项目经理应该做出什么决定&#xff1b; 选…

SpringBoot自定义全局异常处理

自定义全局异常处理一. 创建所需类1. 自定义异常接口2. 自定义枚举类3. 自定义异常类4. 自定义异常处理类5. 自定义全局响应类5.1 BaseResponse类5.2 RespGenerator类二. 效果演示我们在 SpringBoot 项目中&#xff0c;往往会写许多 Controler 接口类&#xff0c;由于 Controll…

SNV的使用

一&#xff1a;什么是SVN&#xff1f; SVN是一个版本控制系统&#xff0c;SVN全称Subversion&#xff0c;用于记录一个或多个文件内容变化&#xff0c;方便我们查阅特定版本的修改情况。以前在没有版本控制的时候&#xff0c;我们通常在项目根目录下这样命名项目&#xff1a;p…

Python 环境搭建配置

Python可应用于多平台包括 Linux 和 Mac OS X。你可以通过终端窗口输入 "python" 命令来查看本地是否已经安装Python以及Python的安装版本。Unix (Solaris, Linux, FreeBSD, AIX, HP/UX, SunOS, IRIX, 等等。)Win 9x/NT/2000Macintosh (Intel, PPC, 68K)OS/2DOS (多个…

微信小程序 Springboot校园达达互助平台快递代取系统 java

本 录 摘 要 III Abstract 1 1 系统概述 1 1.1 概述 2 1.2课题意义 3 1.3 主要内容 4 2 系统开发环境 5 2.1微信开发者工具 6 2.2小程序框架以及目录结构介绍 6 2.3 JAVA简介 7 2.4 MySQL数据库 7 3 需求分析 8 3.1 系统设计目标 8 3…

STM32开发(1)----stm32f103c6t6开发板介绍和环境搭建

stm32f103c6t6开发板介绍一、stm32f103c6t6芯片资源介绍STM32 的命名规则二、最小系统开发板介绍三、开发板基本使用方法软件安装MDK5 安装安装STM32芯片包安装licenseUSB转串口驱动安装四、本文小结一、stm32f103c6t6芯片资源介绍 stm32f103c6t6 是一款基于 ARM Cortex M3 内…