双目视觉——点云与RGB图像融合

一、固定向量类

1、cv::Vec

   在OpenCV中针对三通道矩阵,定义的Vec类型有:cv::Vec3bcv::Vec3scv::Vec3wcv::Vec3dcv::Vec3fcv::Vec3i6种类型。其中的数字表示通道个数,最后一位是数据类型的缩写。

  • cv::Vec3b:b是uchar类型的缩写。
  • cv::Vec3s:s是short类型的缩写。
  • cv::Vec3w:w是ushort类型的缩写。
  • cv::Vec3d:d是double类型的缩写。
  • cv::Vec3f:f是float类型的缩写。
  • cv::Vec3i:i是int类型的缩写。
       对于二通道和四通道也定义了对应的变量类型,也有同样的命名规则。例如:cv::Vec2b表示二通道uchar类型。

2、读取像素

   由于在OpenCV中,使用imread读取到的Mat图像数据,都是用uchar类型的数据存储,对于RGB三通道的图像,每个点的数据都是一个Vec3b类型的数据。

使用at定位方法如下:

Mat mat = imread("test.jpg");

//(row, col)即所需要定位点的坐标
mat.at<Vec3b>(row, col)[0] = 255;  //修改点 (row, col) 的 B 通道数据
mat.at<Vec3b>(row, col)[1] = 255;  //修改点 (row, col) 的 G 通道数据
mat.at<Vec3b>(row, col)[2] = 255;  //修改点 (row, col) 的 R 通道数据

二、点云着色

   将双目相机的图像色彩添加到点云上生成彩色点云(PointXYZRGB点云)

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <opencv2/opencv.hpp>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;

int	main(int argc, char** argv)
{
    
    
	// --------------------------------加载点云---------------------------------
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
	if (pcl::io::loadPCDFile<pcl::PointXYZ>("test.pcd", *cloud) == -1)
	{
    
    
		PCL_ERROR("读取点云失败 \n");
		return (-1);
	}
	// -------------------------------加载图像----------------------------------
	cv::Mat img = cv::imread("test.jpeg");  //读入图片
	if (img.empty())
	{
    
    
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	cv::imshow("image", img);  //显示图片
	// ----------------------------点云与图像融合-------------------------------
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr pointcloud(new pcl::PointCloud<pcl::PointXYZRGB>); 

	for (int r = 0; r < img.rows; r++) 
	{
    
    
		for (int c = 0; c < img.cols; c++)
		{
    
    
			pcl::PointXYZRGB point;
			// opencv中的颜色为Scalar(B,G,R),PCL中的颜色为RGB,需要做到一一对应
			point.x = cloud->points[r * img.cols + c].x;
			point.y = cloud->points[r * img.cols + c].y;
			point.z = cloud->points[r * img.cols + c].z;
			point.r = img.at<cv::Vec3b>(r, c)[2];
			point.g = img.at<cv::Vec3b>(r, c)[1];
			point.b = img.at<cv::Vec3b>(r, c)[0];
			pointcloud->push_back(point);
		}
	}
	// -----------------------保存生成的点云到本地文件夹--------------------------------
	pcl::io::savePCDFileASCII("RGB真彩点云.pcd", *pointcloud);
	// -----------------------------使用PCL可视化点云-----------------------------------
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(pointcloud);// 显示RGB
	viewer->addPointCloud<pcl::PointXYZRGB>(pointcloud, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud"); // 设置点云大小
	// 启动可视化
	viewer->addCoordinateSystem(1000);  // 显示XYZ指示轴
	viewer->initCameraParameters();    // 初始化摄像头参数
	while (!viewer->wasStopped())
	{
    
    
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}

	return 0;
}

四、结果展示

1、图像

在这里插入图片描述

2、点云

在这里插入图片描述

3、彩色点云

在这里插入图片描述

五、参考链接

【OpenCV】关于Vec3b类型的含义与使用
点云与RGB融合

猜你喜欢

转载自blog.csdn.net/qq_36686437/article/details/121449760
今日推荐