C++利用opencv中的viz模块实现点云三维地图


前言

该文章主要是记录了如何利用opencv中的viz来进行三维点云建模。由于目前遇到了需要建立三维地图和地图场景加载的需求,故在此记录。编译环境为opencv3.4.1,vtk7.1.1,语言标准为C++11。


一、环境配置

打开VS工程,右击属性进行VC++目录的包含目录、库目录以及链接器->输入->附加依赖项配置。具体配置可以参考其它博主的博客,一般配置包含目录、库目录和链接器中的附件依赖项环境基本就可以正常运行。

二、具体实现

1.头文件

头文件代码如下:

#include<iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/viz.hpp>

2.代码

在进行代码实现前,先对数据进行一部分定义,假定光学地图的tif文件为三通道,变量值为无符号char型(及值为0-255);假定高程信息为float类型。光学地图和高程信息覆盖的经纬度范围相同(分辨率不同可以后期进行双三插值)。

int main(){
	std::string filepath = "E:\\weitu\\光学地体.tif";//光学地图为三通道tif文件(RGB通道),文件数据类型为unsigned char
	std::string DEM_filepath = "E:\\weitu\\DEM.tif";//高程信息,文件数据为float类型
	cv::Mat image = cv::imread(filepath, cv::IMREAD_UNCHANGED);//像素为BGR
	cv::Mat DEM_data = cv::imread(DEM_filepath, CV_LOAD_IMAGE_ANYDEPTH);//DEM数据,两种数据imread的第二个参数有所区别
	float minValue = *std::min_element(DEM_data.begin<float>(), DEM_data.end<float>());//取高程最小值
	cv::Size newSize(image.cols, image.rows);
	cv::resize(DEM_data, DEM_data, newSize, 0, 0, cv::INTER_CUBIC);//插值和影像分辨率统一
	std::vector<cv::Vec3f> cloud;
	std::vector<cv::Vec3b> color;
	int inter_ = 2;//采样间隔
	for (long long y = 0; y < nImgSizeY; y+= inter_) {
		for (long long x = 0; x < nImgSizeX; x+= inter_) {
			cloud.emplace_back(cv::Vec3f(y / inter_, x / inter_, (DEM_data.at<float>(y, x) - minValue) * 5));//经纬高,第三个元素*5是防止高程变化平缓,人工可调的系数
			color.emplace_back(image.at<cv::Vec3b>(y,x));//BGR值
		}
	}
	cv::viz::WCloud cloud_widget(cloud, color);//点云
	cv::viz::Viz3d window("window");
	cloud_widget.setRenderingProperty(cv::viz::RenderingProperties::POINT_SIZE, 2);//设置点大小
	window.showWidget("pnt_cloud", cloud_widget);//窗口显示点云,ID为pnt_cloud

	//下面是加入长方体并设置RGB轮换变化
	cv::viz::WCube cube_widget(cv::Point3f(51.0, -15, 0.0), cv::Point3f(5.0, 0.5, 15), true, cv::viz::Color::red());
	cube_widget.setRenderingProperty(cv::viz::LINE_WIDTH, 1.0); // 设置线条粗细
	//cube_widget.setRenderingProperty(cv::viz::OPACITY, 0.1);//设置透明度
	window.showWidget("Cube", cube_widget);
	const int delay = 100; // 单位1毫秒的延迟
	int aa = 0;
	//上面部分
	//接下来开始显示
	while (!window.wasStopped()) {
		// 处理事件
		window.spinOnce(delay, true);
		if (aa % 3 == 0) {
			cube_widget.setColor(cv::viz::Color::blue());
		}
		if (aa % 3 == 1) {
			cube_widget.setColor(cv::viz::Color::red());
		}
		if (aa % 3 == 2) {
			cube_widget.setColor(cv::viz::Color::green());
		}
		++aa;				
	}
	image.release();//释放内存
	DEM_data.release();
}

总结

下面看一看效果图
在这里插入图片描述
初步尝试,有好的建议和问题都可以提出。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值