彩色图和深度图转点云

彩色图和深度图转点云环境:windows10、VS2013、opencv2.49、openNi、PCL1.8opencv环境搭建参考https://www.cnblogs.com/cuteshongshong/p/4057193.htmlhttps://blog.csdn.net/u013105549/article/details/50493069PCL1.8+openNi搭建参考https://blog.cs…

大家好,又见面了,我是你们的朋友全栈君。

环境:windows10、VS2013、opencv 2.49、openNi、PCL1.8

opencv 环境搭建参考
PCL1.8+openNi搭建参考
将上面的opencv和pcl的配置保存到属性表中,以便下一次快速引用。

彩色图和深度图转点云
新建项目,选择解决方案配置选择Debug x64,属性管理器的Debug|x64中添加上面两个属性表

彩色图和深度图转点云
RGBDtoPC.cpp


#include "stdafx.h"

#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <opencv2/opencv.hpp>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <pcl/visualization/cloud_viewer.h>
using namespace std;
// 定义点云类型
typedef pcl::PointXYZRGBA PointT;
typedef pcl::PointCloud<PointT> PointCloud;

// 相机内参
const double camera_factor = 1000;
const double camera_cx = 325.5;
const double camera_cy = 253.5;
const double camera_fx = 518.0;
const double camera_fy = 519.0;
// 主函数 

int main(int argc, char** argv)
{
	// 读取./data/rgb.png和./data/depth.png,并转化为点云

	// 图像矩阵
	cv::Mat rgb, depth;
	// 使用cv::imread()来读取图像
	// API: http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imread#cv2.imread
	rgb = cv::imread("color.png");
	cout << "read rgb"<<endl;
	// rgb 图像是8UC3的彩色图像
	// depth 是16UC1的单通道图像,注意flags设置-1,表示读取原始数据不做任何修改
	depth = cv::imread("depth.png");
	cout << "read depth" << endl;
	// 点云变量
	// 使用智能指针,创建一个空点云。这种指针用完会自动释放。
	PointCloud::Ptr cloud(new PointCloud);
	// 遍历深度图
	for (int m = 0; m < depth.rows; m++)
		for (int n = 0; n < depth.cols; n++)
		{
		// 获取深度图中(m,n)处的值
		ushort d = depth.ptr<ushort>(m)[n];
		// d 可能没有值,若如此,跳过此点
		if (d == 0)
			continue;
		// d 存在值,则向点云增加一个点
		PointT p;

		// 计算这个点的空间坐标
		p.z = double(d) / camera_factor;
		p.x = (n - camera_cx) * p.z / camera_fx;
		p.y = (m - camera_cy) * p.z / camera_fy;

		// 从rgb图像中获取它的颜色
		// rgb是三通道的BGR格式图,所以按下面的顺序获取颜色
		p.b = rgb.ptr<uchar>(m)[n * 3];
		p.g = rgb.ptr<uchar>(m)[n * 3 + 1];
		p.r = rgb.ptr<uchar>(m)[n * 3 + 2];

		// 把p加入到点云中
		cloud->points.push_back(p);
		//cout << cloud->points.size() << endl;
		}
	// 设置并保存点云
	cloud->height = 1;
	cloud->width = cloud->points.size();
	cout << "point cloud size = " << cloud->points.size() << endl;
	cloud->is_dense = false;
	try{
		//保存点云图
		pcl::io::savePCDFile("E:\\Visual Studio2013\\project\\RGBDtoPC\\data\\pcd.pcd", *cloud);
		

	}
	catch (pcl::IOException &e){
		cout << e.what()<< endl;
	}
	//显示点云图
	pcl::visualization::CloudViewer viewer("Simple Cloud Viewer");//直接创造一个显示窗口
	viewer.showCloud(cloud);//再这个窗口显示点云
	while (!viewer.wasStopped())
	{
	}

	//pcl::io::savePCDFileASCII("E:\\Visual Studio2013\\projectpointcloud.pcd", *cloud);
	// 清除数据并退出
	cloud->points.clear();
	cout << "Point cloud saved." << endl;
	return 0;
}

运行后可能直接返回,提示pcl::io Exception
单步运行发现cv::imread()并没有读取到图片。原因如下

opencv有cvLoadImage()和cv::imread()读图片的方法

而后者的链接库版本不正确:(debug下对应的库为xxxd.lib,release的为xxx.lib)
链接器中的附加依赖项中同时添加带d和不带d的依赖项会出问题,如果用Debug调试则只添加后面带d的即可,将不带d的删除。

彩色图和深度图转点云

我添加了这些
opencv_calib3d249d.lib

opencv_contrib249d.lib

opencv_core249d.lib

opencv_features2d249d.lib

opencv_flann249d.lib

opencv_gpu249d.lib

opencv_highgui249d.lib

opencv_imgproc249d.lib

opencv_legacy249d.lib

opencv_ml249d.lib

opencv_nonfree249d.lib

opencv_objdetect249d.lib

opencv_photo249d.lib

opencv_stitching249d.lib

opencv_ts249d.lib

opencv_video249d.lib

opencv_videostab249d.lib

显示点云图参考:
//显示点云图
	pcl::visualization::CloudViewer viewer("Simple Cloud Viewer");//直接创造一个显示窗口
	viewer.showCloud(cloud);//再这个窗口显示点云

color.png
彩色图和深度图转点云
depth.png

彩色图和深度图转点云
运行结果
彩色图和深度图转点云
深度图和彩色图没有对准,可能的原因是在代码的相机内参设置不匹配。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/129915.html原文链接:https://javaforall.net

(0)
上一篇 2022年4月25日 下午2:00
下一篇 2022年4月25日 下午2:00


相关推荐

  • SQL学习(一):months_between日期函数

    SQL学习(一):months_between日期函数日期函数months_between的用法:MONTHS_BETWEEN(date1,date2)用于计算date1和date2之间有几个月。如果date1在日历中比date2晚,那么MONTHS_BETWEEN()就返回一个正数。如果date1在日历中比date2早,那么MONTHS_BETWEEN()就返回一个负数。如果date1和date2日期一样,那么MONTHS_BETWEEN()就返回一个0。案例SQL>selectmonths_between(to_date(

    2022年8月20日
    10
  • IDEA 汉化插件

    IDEA 汉化插件最近更新了最新版本的IDEA,听同事说有官方汉化插件了,这里跟大家分享下:直接去设置中插件搜索chinese就可以看到,下载安装,然后重启就会生效ps:如果没有查找到或者不生效,升级下自己的IDEA版本…

    2022年6月7日
    51
  • 20款优秀的基于浏览器的在线代码编辑器「建议收藏」

    20款优秀的基于浏览器的在线代码编辑器「建议收藏」20款优秀的基于浏览器的在线代码编辑器1.CompilrCompilr是一个在线编译器和在线IDE。可以用它来开发PHP,C,C++,Ruby。在浏览器中编译Java,C#和VB.net等。马上使用2.Dabblet跨浏览器兼容,对前端攻城师们来说是一个不得不处理的问题。为了在浏览器间呈现统一的显示效果,攻城师们不仅要为每个游览器添加CSS前缀,甚至还需要用到一…

    2022年6月26日
    103
  • bigdecimal除法不四舍五入_BigDecimal除法问题

    bigdecimal除法不四舍五入_BigDecimal除法问题BigDecimal 类的主要功能是进行小数的大数计算 而且最重要的是可以精确到指定的四舍五入位数 如果要进行四舍五入的操作 则必须依靠以下的方法 publicBigDec BigDecimaldi intscale introundingM scale 表示四舍五入的位数在上面的例子中 我们使用了 BigDecimal 类 并且采用 setScale 方法设置

    2026年3月18日
    2
  • springboot 解决跨域问题_java解决跨域问题

    springboot 解决跨域问题_java解决跨域问题SpringBoot版本的不同,CrossOrigin失效了,正确配置如下: @CrossOrigin(originPatterns=”*”,allowCredentials=”true”,maxAge=3600)

    2026年4月14日
    4
  • Android Layout 布局属性全解

    Android Layout 布局属性全解写的挺全 mark 一下 Android nbsp Layout 布局属性全解 Android 有基本 Layout FrameLayout LinearLayout TableLayout RelativeLayo AbsoluteLayo android 开发者谷歌文档 http android xsoftlab net reference android view ViewGrou

    2026年3月26日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号