一. 课题背景
机械臂引导:3D视觉引导机械臂方案被越来越多的行业认可,如:快递分拣供包、汽车配件上下料、仓储拆码垛、仓配货品拣选。通过使用3D视觉系统,可以实时获取目标物体的三维位置和姿态信息。这使得机械臂能够准确地定位和操作目标物体,实现高精度的任务执行。相比于传统的2D视觉系统,3D视觉能够提供更全面和准确的信息,提高了机械臂的定位精度。3D视觉系统可以同时获取多个视角的数据,从而提供更全面的物体信息。通过融合多个视角的数据,可以得到更准确的物体形状和表面信息,提高机械臂对目标物体的感知能力。这对于复杂形状的物体或需要多角度操作的任务非常有用。此外3D视觉系统对光照、阴影和遮挡等环境因素具有较强的鲁棒性。相比于2D视觉系统,3D视觉可以更好地应对复杂的工作环境,提供更可靠的目标检测和定位结果。这使得机械臂在不同的工作场景下都能够保持高效和稳定的操作。
本课题以鞋底、水果、快递箱为实验对象,使用海康3D相机产品获取视野中多个无序摆放的物料,通过6轴协作机械臂对其进行分拣,本篇文章主要介绍将RGB图与深度图转换为带RGB信息的点云。
二. 环境介绍
1.Visual Studio 2019
2.PCL
3.QT
4.Open CV
5。VTK 8.2
三. 深度图与RGB图转化为带RGB信息点云
RGB-D相机相比于3D线扫相机在获得物体深度图的同时还能够获取RGB图,将RGB图与深度图对齐后,可以将RGB图与深度图转换为转换为带颜色信息的三维点云。
通过设置颜色阈值或使用颜色特征来筛选点云,可以去除不需要的点,从而提高数据质量和减少处理的复杂性。通过使用RGB信息,可以将点云中的不同目标进行分割与分类,使得进一步的处理和分析更加容易和准确。
首先解析RGB图的数据,并通过Qt的label控件将图片显示出来,解析过程如下所示:
g_pRgbData = (unsigned char*)malloc(stFrameData.stImageData[1].nDataLen);
memset(g_pRgbData, 0, stFrameData.stImageData[1].nDataLen);
ConvertRGB8Planner2BGR8Packed(stFrameData.stImageData[1].pData, stFrameData.stImageData[1].nWidth, stFrameData.stImageData[1].nHeight, g_pRgbData);
cv::Mat mCvmat = cv::Mat(stFrameData.stImageData[1].nHeight, stFrameData.stImageData[1].nWidth, CV_8UC3, g_pRgbData);
cv::Mat bgrImage;
cvtColor(mCvmat, bgrImage,cv::COLOR_RGB2BGR);
QImage Qmtemp = QImage((const unsigned char*)(bgrImage.data), bgrImage.cols, bgrImage.rows, bgrImage.step, QImage::Format_RGB888);
Qmtemp = Qmtemp.scaled(ui.label_2->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
ui.label_2->setPixmap(QPixmap::fromImage(Qmtemp));
ui.label_2->resize(Qmtemp.size());
ui.label_2->show();

接下来解析深度图,并通过QT的label控件进行显示:
MV3D_RGBD_MapDepthToPointCloud(handle, &stFrameData.stImageData[0], &imgCloud);
cv::Mat temp = cv::Mat(stFrameData.stImageData[0].nHeight, stFrameData.stImageData[0].nWidth, CV_16UC1, stFrameData.stImageData[0].pData);
cv::Mat depthImage8Bit;
temp.convertTo(depthImage8Bit, CV_8U, 255.0 / 1000.0);
QImage Qtemp = QImage((const unsigned char*)(depthImage8Bit.data), depthImage8Bit.cols, depthImage8Bit.rows, depthImage8Bit.step, QImage::Format_Indexed8);
Qtemp = Qtemp.scaled(ui.label->width(), ui.label->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
ui.label->setPixmap(QPixmap::fromImage(Qtemp));
ui.label->resize(Qtemp.size());
ui.label->show();

将RGB与深度图转换为带RGB信息的点云,在QT中通过VTK显示:
int nPointNum = imgCloud.nDataLen / (sizeof(float) * 3); float* pSrcValue = (float*)imgCloud.pData;
uchar* rgbvalue = (uchar*)mCvmat.data;
PointCloud::Ptr cloud(new PointCloud);
PointCloudA::Ptr cloudA(new PointCloudA);
for (int nPntIndex = 0; nPntIndex < nPointNum;++nPntIndex)
{
PointT p;
p.x = pSrcValue[nPntIndex*3+0];
p.y = pSrcValue[nPntIndex * 3 + 1];
p.z = pSrcValue[nPntIndex * 3 + 2];
p.r = rgbvalue[nPntIndex * 3 + 2];
p.g = rgbvalue[nPntIndex * 3 + 1];
p.b = rgbvalue[nPntIndex * 3 + 0];
cloud->points.push_back(p);
cloudA->points.push_back(p1);
}
cloud->height = 1;
cloud->width = cloud->points.size();
cloudA->height = 1;
cloudA->width = cloudA->points.size();
pcl::io::savePCDFile("D:\\QtProject\\HK_Robot_Materials_Sorting\\HK_Robot_Materials_Sorting\\point\\a.pcd", *cloud);
cloudRGB = cloud;
viewer->removeAllPointClouds();
viewer->removeAllShapes();
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
viewer->addPointCloud<pcl::PointXYZRGB>(cloud, rgb, "point_cloud");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "point_cloud");
ui.qvtkWidget->update();
cloud->points.clear();


