PointCloudLibrary / PointCloudLibrary/pcl
Possible Bug in PCL_visualizer when adding model object.
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.1k
- Forks
- 4.7k
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 6
Description
I can say that there is a bug in PCL_visualizer for the pcl version 1.7.2 and version 1.8.0.
I have tested the code on three different version of pcl 1.6 - 1.8 on different machines.
windows 7 32bit All-in-one pcl installer - v1.6
ubuntu 14.04 LTS repo install - v1.7.2
Windows 10 64bit source compiled - v1.8
the issue is related to co-ordinate shown in the visualizer which seems to be not correct.
THE CODE:
#include <vtkIdList.h>
#include <vtkPoints.h>
#include <vtkOBBTree.h>
#include <vtkBoundingBox.h>
#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/io/pcd_io.h>
#include <pcl/common/centroid.h>
#include <pcl/common/common.h>
#include <pcl/common/transforms.h>
#include <pcl/filters/project_inliers.h>
int
main()
{
pcl::ModelCoefficients::Ptr cylinder_Coeff (new pcl::ModelCoefficients);
for(int i = 0; i < 7; i++)
{
cylinder_Coeff->values.push_back(i);
}
std::string filename;
double corner[3], max[3], min[3], mid[3], size[3];
vtkSmartPointer<vtkOBBTree> OBB = vtkSmartPointer<vtkOBBTree>::New();
pcl::visualization::PCLVisualizer *visu;
std::cout << "Enter the filename\n";
std::cin >> filename;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile<pcl::PointXYZ> (filename, *cloud);
///pointCloud to VtkIDlist
vtkIdType nr_points = cloud->points.size();
vtkPoints* points = vtkPoints::New();
points->SetDataTypeToFloat();
points->SetNumberOfPoints(nr_points);
/*vtkBoundingBox Bounding;
for (int i = 0; i < cloud->points.size(); i++)
{
Bounding.AddPoint(cloud->points[i].x, cloud->points[i].y, cloud->points[i].z);
}
double bounds[6];
Bounding.GetBounds(bounds);*/
if (cloud->is_dense)
{
for (vtkIdType i = 0; i < nr_points; ++i) {
float point[3] = {cloud->points[i].x, cloud->points[i].y, cloud->points[i].z};
points->SetPoint(i, point);
}
}
else
{
vtkIdType j = 0; // true point index
for (vtkIdType i = 0; i < nr_points; ++i)
{
// Check if the point is invalid
if (!pcl_isfinite (cloud->points[i].x) ||
!pcl_isfinite (cloud->points[i].y) ||
!pcl_isfinite (cloud->points[i].z))
continue;
float point[3] = {cloud->points[i].x, cloud->points[i].y, cloud->points[i].z};
points->SetPoint(j, point);
j++;
}
nr_points = j;
points->SetNumberOfPoints(nr_points);
}
OBB->ComputeOBB(points, corner, max, mid, min, size);
//below code is required to get correct length of the vectors
Eigen::Vector4f pcaCentroid,pcaCentroidTransformed;
pcl::compute3DCentroid(*cloud, pcaCentroid);
Eigen::Matrix3f covariance;
computeCovarianceMatrixNormalized(*cloud, pcaCentroid, covariance);
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigen_solver(covariance, Eigen::ComputeEigenvectors);
Eigen::Matrix3f eigenVectorsPCA = eigen_solver.eigenvectors();
eigenVectorsPCA.col(2) = eigenVectorsPCA.col(0).cross(eigenVectorsPCA.col(1));
Eigen::Matrix4f projectionTransform(Eigen::Matrix4f::Identity());
projectionTransform.block<3,3>(0,0) = eigenVectorsPCA.transpose();
projectionTransform.block<3,1>(0,3) = -1.f * (projectionTransform.block<3,3>(0,0) * pcaCentroid.head<3>());
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudPointsProjected (new pcl::PointCloud<pcl::PointXYZ>);
pcl::transformPointCloud(*cloud, *cloudPointsProjected, projectionTransform);
pcl::compute3DCentroid(*cloudPointsProjected, pcaCentroidTransformed);
pcl::PointXYZ minPoint, maxPoint, lineP1, lineP2;
pcl::getMinMax3D(*cloudPointsProjected, minPoint, maxPoint);
const Eigen::Vector3f meanDiagonal = 0.5f *(maxPoint.getVector3fMap() + minPoint.getVector3fMap());
const Eigen::Quaternionf bboxQuaternion(eigenVectorsPCA); //Quaternions are a way to do rotations https://www.youtube.com/watch?v=mHVwd8gYLnI
const Eigen::Vector3f bboxTransform = eigenVectorsPCA * meanDiagonal + pcaCentroid.head<3>();
double height, width, depth, a, b, c, radius;
a = maxPoint.y - minPoint.y;
b = maxPoint.x - minPoint.x;
c = maxPoint.z - minPoint.z;
if(a > b && a > c){
height = a;
if (b > c)
{
cylinder_Coeff->values[6] = b/2;
}
else
{
cylinder_Coeff->values[6] = c/2;
}
}
else if (b > a && b > c){
height = b;
if(a > c)
{
cylinder_Coeff->values[6] = a/2;
}
else
{
cylinder_Coeff->values[6] = c/2;
}
}
else if (c > a && c >b){
height = c;
if(a > b)
{
cylinder_Coeff->values[6] = a/2;
}
else
{
cylinder_Coeff->values[6] = b/2;
}
}
pcl::ModelCoefficients::Ptr sphere_Coeff (new pcl::ModelCoefficients);
//this will make sphere at the origin
sphere_Coeff->values.push_back(0);
sphere_Coeff->values.push_back(0);
sphere_Coeff->values.push_back(0);
sphere_Coeff->values.push_back(2);
//Normalizing the vectors
double n_max[3], n_min[3], n_mid[3], l_max, l_min, l_mid;
l_max = sqrt( pow(max[0],2) + pow(max[1],2) + pow(max[2],2));
l_min = sqrt( pow(min[0],2) + pow(min[1],2) + pow(min[2],2));
l_mid = sqrt( pow(mid[0],2) + pow(mid[1],2) + pow(mid[2],2));
n_max[0] = max[0]/l_max;
n_max[1] = max[1]/l_max;
n_max[2] = max[2]/l_max;
n_min[0] = min[0]/l_min;
n_min[1] = min[1]/l_min;
n_min[2] = min[2]/l_min;
n_mid[0] = mid[0]/l_mid;
n_mid[1] = mid[1]/l_mid;
n_mid[2] = mid[2]/l_mid;
pcl::ModelCoefficients::Ptr line_Coeff (new pcl::ModelCoefficients);
line_Coeff->values.resize(6);
line_Coeff->values[0] = pcaCentroid(0) - ((height/2) * n_max[0]) + (cylinder_Coeff->values[6] * n_mid[0]);
line_Coeff->values[1] = pcaCentroid(1) - ((height/2) * n_max[1]) + (cylinder_Coeff->values[6] * n_mid[1]);
line_Coeff->values[2] = pcaCentroid(2) - ((height/2) * n_max[2]) + (cylinder_Coeff->values[6] * n_mid[2]);
line_Coeff->values[3] = ((height/2) * n_max[0]);
line_Coeff->values[4] = ((height/2) * n_max[1]);
line_Coeff->values[5] = ((height/2) * n_max[2]);
lineP1.x = pcaCentroid(0) - ((height/2) * n_max[0]);// + (cylinder_Coeff->values[6] * n_min[0]);
lineP1.y = pcaCentroid(1) - ((height/2) * n_max[1]);// + (cylinder_Coeff->values[6] * n_min[1]);
lineP1.z = pcaCentroid(2) - ((height/2) * n_max[2]);// + (cylinder_Coeff->values[6] * n_min[2]);
lineP2.x = pcaCentroid(0) + ((height/2) * n_max[0]);// + (cylinder_Coeff->values[6] * n_min[0]);
lineP2.y = pcaCentroid(1) + ((height/2) * n_max[1]);//+ (cylinder_Coeff->values[6] * n_min[1]);
lineP2.z = pcaCentroid(2) + ((height/2) * n_max[2]);// + (cylinder_Coeff->values[6] * n_min[2]);
cylinder_Coeff->values[0] = pcaCentroid(0) - ((height/2) * n_max[0]);
cylinder_Coeff->values[1] = pcaCentroid(1) - ((height/2) * n_max[1]);
cylinder_Coeff->values[2] = pcaCentroid(2) - ((height/2) * n_max[2]);
cylinder_Coeff->values[3] = ((height) * n_max[0]);
cylinder_Coeff->values[4] = ((height) * n_max[1]);
cylinder_Coeff->values[5] = ((height) * n_max[2]);
for(int i = 0; i < 3; i++)
{
std::cout << corner[i] << " " << max[i] << " " << mid[i] << " " << min[i] << " " << size[i] << std::endl;
}
visu = new pcl::visualization::PCLVisualizer ("PlyViewer");
int vp;
visu->addLine(lineP1, lineP2, "line");
visu->addSphere(*sphere_Coeff, "sph");
visu->addCylinder(*cylinder_Coeff, "cyl");
visu->addCube(bboxTransform, bboxQuaternion, maxPoint.x - minPoint.x, maxPoint.y - minPoint.y, maxPoint.z - minPoint.z, "bbox");
visu->addCoordinateSystem(0.5);
visu->addPointCloud(cloud, "ogCloud");
visu->updatePointCloud(cloud, "ogCloud");
while (!visu->wasStopped ())
{
visu->spinOnce (100);
boost::this_thread::sleep (boost::posix_time::microseconds (100000));
}
return 0;
}



Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the supplied program with the listed PCL 1.6, 1.7.2, and 1.8 environments, focusing on PCLVisualizer calls such as addLine, addCylinder, addCube, and addCoordinateSystem. Compare the displayed coordinates with the computed point-cloud and bounding-box values. Done means identifying and documenting a reproducible visualization defect with a consistent result across supported versions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- computer-graphics, computer-vision
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100