Advertisement

结合彩色图和深度图创建点云(OpenCV+OpenNI+PCL)

阅读量:

花了相当长的时间进行各种尝试后终于取得了令人满意的结果!通过OpenNI实现了对彩色图像和深度数据流的捕获,并将其转换为OpenCV支持的Mat图像格式。

对相机进行标定,获取相机的内部参数:

Optimization outcomes post-calibration (considering measurement uncertainties) are presented below, along with their corresponding confidence intervals.

Focal Length: fc = [511, 514] ± [2, 2] //焦距
Principal Point: cc = [324, 236] ± [4, 3] //主点
Skewness: αc = [±...] → Pixel Axis Angle = (9±...)° //偏斜
Distortion Coefficients: kc = [..., ..., ..., ...] //畸变
Pixel Error Vector: er = [...] //像素误差向量

设(u, v)是像素坐标系的坐标,(Xw, Yw,Zw)是世界坐标系的坐标。

则标定后可以通过(u, v)求出(Xw, Yw),公式如下:

Xw = (u - u0) * Zw / fx;

Yw = (v - v0) *Zw / fy;

其中(u0,v0)是光轴与像素平面的交点坐标。

效果图如下:

代码如下:

复制代码
 <span style="font-size:18px;">#include <pcl/visualization/cloud_viewer.h>

    
 #include <iostream>
    
 #include <pcl/io/io.h>
    
 #include <pcl/io/pcd_io.h>
    
 #include <opencv2/opencv.hpp>
    
  
    
 int user_data;
    
 const double u0 = 319.52883;
    
 const double v0 = 271.61749;
    
 const double fx = 528.57523;
    
 const double fy = 527.57387;
    
  
    
 void viewerOneOff (pcl::visualization::PCLVisualizer& viewer)
    
 {
    
     viewer.setBackgroundColor (0.0, 0.0, 0.0);
    
 }
    
     
    
 int main ()
    
 {
    
 	pcl::PointCloud<pcl::PointXYZRGB> cloud_a;
    
 	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB>);
    
  
    
  
    
 	cv::Mat color = cv::imread("Image1.jpg");
    
 	cv::Mat depth = cv::imread("cc.jpg");
    
  
    
 	int rowNumber = color.rows;
    
 	int colNumber = color.cols;
    
  
    
 	cloud_a.height  = rowNumber;
    
 	cloud_a.width = colNumber;
    
 	cloud_a.points.resize(cloud_a.width * cloud_a.height);
    
  
    
 	for (unsigned int u = 0; u < rowNumber; ++u)
    
 	{
    
 		for (unsigned int v = 0; v < colNumber; ++v)
    
 		{
    
 			unsigned int num = u*colNumber + v;
    
 			double Xw = 0, Yw = 0, Zw = 0;
    
  
    
 			Zw = ((double)depth.at<uchar>(u,v)) / 255.0 * 10001.0;
    
 			Xw = (u-u0) * Zw / fx;
    
 			Yw = (v-v0) * Zw / fy;
    
  
    
 			cloud_a.points[num].b = color.at<cv::Vec3b>(u,v)[0];
    
 			cloud_a.points[num].g = color.at<cv::Vec3b>(u,v)[1];
    
 			cloud_a.points[num].r = color.at<cv::Vec3b>(u,v)[2];
    
  
    
 			cloud_a.points[num].x = Xw;
    
 			cloud_a.points[num].y = Yw;
    
 			cloud_a.points[num].z = Zw;
    
 		}
    
 	}
    
  
    
 	*cloud = cloud_a;
    
  
    
     pcl::visualization::CloudViewer viewer("Cloud Viewer");    
    
  
    
     viewer.showCloud(cloud);
    
  
    
     viewer.runOnVisualizationThreadOnce (viewerOneOff);
    
  
    
     while (!viewer.wasStopped ())
    
     {
    
 		user_data = 9;
    
     }
    
  
    
     return 0;
    
 }</span>

全部评论 (0)

还没有任何评论哟~