#include "AerobicVision.h" #include //TODO: Implement Filterfunction in calibration function //TODO: SORT GROWING ALGORITHM OUTPUT VECTOR ON Z AXIS HIGH TO LOW AerobicVision::AerobicVision(std::string IP){ //logging method o3d3xx::Logging::Init(); //initialise camera constructor expects IP address, using default one cam = std::make_shared(IP); //create buffer to fetch image img = std::make_shared(); //framegrabber fg = std::make_shared(cam, o3d3xx::IMG_AMP|o3d3xx::IMG_RDIS|o3d3xx::IMG_CART); } bool wayToSort(objectData i, objectData j){ // point x = real z return i.xyz.x < j.xyz.x; } pcl::PointCloud::Ptr AerobicVision::PassFilterPCD(pcl::PointCloud::Ptr cloudIn, double xmin, double xmax, double ymin, double ymax, double zmin, double zmax){ pcl::PointCloud::Ptr zfilt (new pcl::PointCloud), yfilt (new pcl::PointCloud); //passthrough filter pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud); pcl::PassThrough passX, passY, passZ; passZ.setInputCloud(cloudIn); passZ.setFilterFieldName("z"); // blauw = z REAL = X passZ.setFilterLimits(xmin,xmax); //passZ.setFilterLimits(-0.05,0.05); //calibration passZ.filter(*zfilt); passY.setInputCloud(zfilt); passY.setFilterFieldName("y"); // y= groen REAL = Y passY.setFilterLimits(ymin,ymax); // //passY.setFilterLimits(-0.05,0.05); //calibratiom passY.filter(*yfilt); passX.setInputCloud(yfilt); passX.setFilterFieldName("x"); // rood = x REAL = Z passX.setFilterLimits(zmin,zmax); //passX.setFilterLimits(0.35,0.38); //calibration passX.filter(*cloud_filtered); return cloud_filtered; } pcl::PointCloud::Ptr AerobicVision::convertCloudXYZItoXYZ(pcl::PointCloud cloudIn){ pcl::PCDWriter writer; pcl::PCDReader reader; writer.write("tmp_pcd.pcd", cloudIn, false); pcl::PointCloud::Ptr cloudOut (new pcl::PointCloud); reader.read("tmp_pcd.pcd", *cloudOut); return cloudOut; } pcl::PointXYZ AerobicVision::Calibrate(int samples){ std::vector average; cout << "Start Calibration with " << samples << " samples" << endl; //get frame from camera (could be looped to create an actual live feed) for(int cnt = 0; cnt < samples; cnt++){ if (! fg->WaitForFrame(img.get(), 2000)) { std::cerr << "Timeout waiting for camera!" << std::endl; } //3D pointcloud //convert o3d3xx cloud to PointXYZI pcl::PointCloud::Ptr cloudIn = img->Cloud(); pcl::PointCloud::Ptr zfilt (new pcl::PointCloud), yfilt (new pcl::PointCloud); //passthrough filter pcl::PointCloud::Ptr cloud_filtered2 (new pcl::PointCloud); pcl::PassThrough passX, passY, passZ; passZ.setInputCloud(cloudIn); passZ.setFilterFieldName("z"); // blauw = z REAL = X passZ.setFilterLimits(-0.125,0.105); //calibration passZ.filter(*zfilt); passY.setInputCloud(zfilt); passY.setFilterFieldName("y"); // y= groen REAL = Y //passY.setFilterLimits(-0.11,0.09); //ops passY.setFilterLimits(-0.1,0.075); //calibratiom passY.filter(*yfilt); passX.setInputCloud(yfilt); passX.setFilterFieldName("x"); // rood = x REAL = Z //passX.setFilterLimits(0.0,0.60); passX.setFilterLimits(0.27,0.33); //calibration passX.filter(*cloud_filtered2); pcl::PointCloud::Ptr cloud (convertCloudXYZItoXYZ(*cloud_filtered2)); pcl::MomentOfInertiaEstimation feature_extractor; feature_extractor.setInputCloud (cloud); feature_extractor.compute(); pcl::PointXYZ min_point_AABB; pcl::PointXYZ max_point_AABB; feature_extractor.getAABB (min_point_AABB, max_point_AABB); pcl::PointXYZ middle_point; middle_point.x = min_point_AABB.x + ((max_point_AABB.x - min_point_AABB.x) / 2); middle_point.y = min_point_AABB.y + ((max_point_AABB.y - min_point_AABB.y) / 2); middle_point.z = min_point_AABB.z + ((max_point_AABB.z - min_point_AABB.z) / 2); average.push_back(middle_point); } double x = 0; double y = 0; double z = 0; int cnt; pcl::PointXYZ ret; for(cnt = 0; cnt < samples; cnt++){ x = x + average[cnt].x; y = y + average[cnt].y; z = z + average[cnt].z; } //set correct XYZ format z = (z / (double)samples); y = (y / (double)samples); x = (x / (double)samples); ret.z = x; ret.y = y; ret.x = z; cout << "Finished Vision Calibration" << endl; return ret; } std::vector AerobicVision::RegionGrowing(){ pcl::console::TicToc tt; // Load the input point cloud std::cerr << "Loading...\n", tt.tic (); if (! fg->WaitForFrame(img.get(), 2000)) { std::cerr << "Timeout waiting for camera!" << std::endl; } pcl::PCDWriter writer; pcl::PointCloud::Ptr cloud (new pcl::PointCloud); pcl::PointCloud::Ptr cloudIn = img->Cloud(); writer.write("tmp_pcd.pcd", *cloudIn, false); pcl::io::loadPCDFile ("tmp_pcd.pcd", *cloud); //std::cerr << ">> Done: " << tt.toc () << " ms, " << cloud->points.size () << " points\n"; pcl::PointCloud::Ptr zfilt (new pcl::PointCloud), yfilt (new pcl::PointCloud); //passthrough filter pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud); pcl::PassThrough passX, passY, passZ; passZ.setInputCloud(cloud); passZ.setFilterFieldName("y"); // blauw = z REAL = X passZ.setFilterLimits(-0.1,0.1); //calibration passZ.filter(*zfilt); passY.setInputCloud(zfilt); passY.setFilterFieldName("z"); // y= groen REAL = Y //passY.setFilterLimits(-0.11,0.09); //ops passY.setFilterLimits(-0.12,0.12); //calibratiom passY.filter(*yfilt); passX.setInputCloud(yfilt); passX.setFilterFieldName("x"); // rood = x REAL = Z //passX.setFilterLimits(0.0,0.60); passX.setFilterLimits(0.0,0.6); //calibration passX.filter(*cloud_filtered); std::vector temp; pcl::removeNaNFromPointCloud(*cloud_filtered, *cloud_filtered, temp); pcl::search::Search::Ptr tree = boost::shared_ptr > (new pcl::search::KdTree); pcl::PointCloud ::Ptr normals (new pcl::PointCloud ); pcl::NormalEstimation normal_estimator; normal_estimator.setSearchMethod (tree); normal_estimator.setInputCloud (cloud_filtered); normal_estimator.setKSearch (100); normal_estimator.compute (*normals); pcl::IndicesPtr indices (new std::vector ); pcl::PassThrough pass; pass.setInputCloud (cloud_filtered); pass.setFilterFieldName ("z"); pass.setFilterLimits (0.0, 1.0); pass.filter (*indices); pcl::RegionGrowing reg; reg.setMinClusterSize (50); //minimum points to find before assigning a cluster reg.setMaxClusterSize (1000); //maximum points to find reg.setSearchMethod (tree); //search using the KdTree reg.setNumberOfNeighbours (15); //number of neighbours?? reg.setInputCloud (cloud_filtered); //input cloud is filtered on xyz axis //reg.setIndices (indices); reg.setInputNormals (normals); //input normals used to find the region reg.setSmoothnessThreshold (5.0 / 180.0 * M_PI); //how smooth has the surface to be in degrees reg.setCurvatureThreshold (1.0); //how much curvature can there be?? std::vector clusters; reg.extract (clusters); std::vector> clusters_with_points; std::vector cluster_middle_points; for(int cnt = 0; cnt < clusters.size(); cnt++){ //Create the filtering object pcl::ExtractIndices extract; pcl::PointCloud::Ptr tmpcloud (new pcl::PointCloud), cloud_f (new pcl::PointCloud);; pcl::PointIndices::Ptr inliers (new pcl::PointIndices (clusters[cnt])); extract.setInputCloud (cloud_filtered); extract.setIndices (inliers); extract.setNegative (false); extract.filter (*tmpcloud); clusters_with_points.push_back(*tmpcloud); pcl::MomentOfInertiaEstimation feature_extractor; feature_extractor.setInputCloud (tmpcloud); feature_extractor.compute(); normal_estimator.setSearchMethod (tree); normal_estimator.setInputCloud (tmpcloud); normal_estimator.setKSearch (100); normal_estimator.compute (*normals); pcl::PointXYZ min_point_AABB; pcl::PointXYZ max_point_AABB; feature_extractor.getAABB (min_point_AABB, max_point_AABB); objectData middle_point; middle_point.xyz.x = min_point_AABB.x + ((max_point_AABB.x - min_point_AABB.x) / 2); middle_point.xyz.y = min_point_AABB.y + ((max_point_AABB.y - min_point_AABB.y) / 2); middle_point.xyz.z = min_point_AABB.z + ((max_point_AABB.z - min_point_AABB.z) / 2); //calculate single normal vector float normal_x = 0.0f; float normal_y = 0.0f; float normal_z = 0.0f; for (int i = 0; i < normals->size();i++){ normal_x = normal_x + normals->points[i].normal_x; normal_y = normal_y + normals->points[i].normal_y; normal_z = normal_z + normals->points[i].normal_z; } normal_x = (normal_x/normals->size()); normal_y = (normal_y/normals->size()); normal_z = (normal_z/normals->size()); if(normal_x > 1 || normal_y > 1 || normal_z > 1 || normal_x < -1 || normal_y < -1 || normal_z < -1) { cout << "Normals not correct, try again." << endl; } else { pcl::Normal normal = pcl::Normal(-normal_x,-normal_y,-normal_z); float pitch = asin(-normal_y); float yaw = atan2(normal_z,normal_x); float roll = 0.0; pcl::PointXYZ rpy = pcl::PointXYZ(roll,pitch,yaw); middle_point.pitch = pitch; middle_point.yaw = yaw; Eigen::AngleAxisd rollAngle(roll, Eigen::Vector3d::UnitZ()); Eigen::AngleAxisd yawAngle(yaw, Eigen::Vector3d::UnitY()); Eigen::AngleAxisd pitchAngle(pitch, Eigen::Vector3d::UnitX()); Eigen::Quaternion q = rollAngle * yawAngle * pitchAngle; Eigen::Matrix3d rotationMatrix = q.matrix(); double rotSum = rotationMatrix(0,0) + rotationMatrix(1,1) + rotationMatrix(2,2) - 1; double alpha = acos(rotSum / 2); double theta = 0; if (roll >= 0) theta = alpha; else theta = 2 * 3.1415926535897 - alpha; double my = 1.0 / (2 * sin(theta)); double rx = my * (rotationMatrix(2,1) - rotationMatrix(1,2)) * theta; double ry = my * (rotationMatrix(0,2) - rotationMatrix(2,0)) * theta; double rz = my * (rotationMatrix(1,0) - rotationMatrix(0,1)) * theta; pcl::PointXYZ rotationVector = pcl::PointXYZ(); rotationVector.x = (float)rx; rotationVector.y = (float)ry; rotationVector.z = (float)rz; middle_point.rx = rotationVector.x; middle_point.ry = rotationVector.y; middle_point.rz = rotationVector.z; } //add found point to vector cluster_middle_points.push_back(middle_point); } //Sort found clusters from closest to farest sort(cluster_middle_points.begin(), cluster_middle_points.end(), wayToSort); return cluster_middle_points; } /////////////////////////////////////////////////////// //Projectgroep 2 test pogingen /////////////////////////////////////////////////////// pcl::PointCloud AerobicVision::AverageCloud(std::vector::Ptr> totalList) { /* pcl::PointCloud::Ptr toReturn = totalList[0]->makeShared(); for(int i = 0; i< totalList[0]->points.size(); i++) { pcl::PointXYZI averagePoint = pcl::PointXYZI(0.0f); for(int k = 0; k< totalList.size();k++) { toReturn[i]->x += totalList[k]->points[i].x; toReturn[i]->y += totalList[k]->points[i].y; toReturn[i]->z += totalList[k]->points[i].z; toReturn[i]->intensity += totalList[k]->points[i].intensity; } toReturn[i]->x /= totalList.size(); toReturn[i]->y /= totalList.size(); toReturn[i]->z /= totalList.size(); toReturn[i]->intensity /= totalList.size(); } return toReturn;*/ pcl::PointCloud toReturn; for(int i = 0; i< totalList[0]->points.size(); i++) { if(isnan(totalList[0]->points[i].x )) { toReturn.push_back(totalList[0]->points[i]); } else{ pcl::PointXYZI averagePoint = pcl::PointXYZI(0.0f); for(int k = 0; k< totalList.size();k++) { averagePoint.x += totalList[k]->points[i].x; averagePoint.y += totalList[k]->points[i].y; averagePoint.z += totalList[k]->points[i].z; averagePoint.intensity += totalList[k]->points[i].intensity; } averagePoint.x /= totalList.size(); averagePoint.y /= totalList.size(); averagePoint.z /= totalList.size(); averagePoint.intensity /= totalList.size(); toReturn.push_back(averagePoint); } } return toReturn; } void AerobicVision::PrintClouds(std::vector::Ptr> totalList) { for(int i = 0; i< totalList[0]->points.size(); i++) { cout << "[" << i << "] "; for(int k = 0; k< totalList.size();k++) { cout << std::setprecision(8) << "(" << totalList[k]->points[i].x << "," << totalList[k]->points[i].y << "," << totalList[k]->points[i].z << ")"; } cout << endl; } } void AerobicVision::PrintCloud(pcl::PointCloud::Ptr cloud) { for(int i = 0; i< cloud->points.size(); i++) { cout << "[" << i << "] "; cout << std::setprecision(5) << "(" << cloud->points[i].x << ", " << cloud->points[i].y << ", " << cloud->points[i].z << ")"; cout << endl; } } void AerobicVision::Test(){ pcl::console::TicToc tt; // Load the input point cloud std::cerr << "Loading...\n", tt.tic (); usleep(2000000); std::vector::Ptr> allClouds; pcl::PointCloud cloudAverage; for(int i = 0; i< 4; i++) { usleep(500000); if (! fg->WaitForFrame(img.get(), 2000)) { std::cerr << "Timeout waiting for camera!" << std::endl; } usleep(2000000); pcl::PointCloud::Ptr cloudIn = img->Cloud()->makeShared(); allClouds.push_back(cloudIn); std::cout << "Stored pic " << i << endl; } //cloudAverage = AverageCloud(allClouds); PrintClouds(allClouds); /* PrintCloud(cloudAverage); pcl::PointCloud::Ptr m_ptrCloud(&cloudAverage); pcl::visualization::CloudViewer viewer("Cloud Viewer", false); //blocks until the cloud is actually rendered viewer.showCloud(m_ptrCloud); */ cout << "Press Enter" << endl; cin.get(); return; } void AerobicVision::AverageCloudsKdTree(pcl::PointCloud::Ptr &average, std::vector::Ptr> allClouds) { vector> kdtree; if(allClouds.size() <= 2) return; for(int g= 0; g< allClouds.size();g++) { kdtree.push_back(pcl::KdTreeFLANN()); kdtree[g].setInputCloud(allClouds[g]); } for(int i = 0; i< allClouds[0]->points.size(); i++) { pcl::PointXYZI averagePoint = pcl::PointXYZI(0.0f); if(isnan(allClouds[0]->points[i].x)) { averagePoint.x = 0; averagePoint.y = 0; averagePoint.z = 0; averagePoint.intensity =0; average->push_back(averagePoint); continue; } pcl::PointXYZI searchPoint; searchPoint.x = allClouds[0]->points[i].x; searchPoint.y = allClouds[0]->points[i].y; searchPoint.z = allClouds[0]->points[i].y; searchPoint.intensity = allClouds[0]->points[i].intensity; averagePoint.x = searchPoint.x; averagePoint.y = searchPoint.y; averagePoint.z = searchPoint.z; averagePoint.intensity = searchPoint.intensity; cout << "[" << i << "] (" << searchPoint.x << "," << searchPoint.y << "," << searchPoint.z << ") > "; for(int k = 1; k< allClouds.size();k++) { std::vector pointIndex(1); std::vector pointDistance(1); if(kdtree[k].nearestKSearch(searchPoint, 1, pointIndex, pointDistance) > 0) { cout << pointDistance[0] << ", "; averagePoint.x += allClouds[k]->points[pointIndex[0]].x; averagePoint.y += allClouds[k]->points[pointIndex[0]].y; averagePoint.z += allClouds[k]->points[pointIndex[0]].z; averagePoint.intensity += allClouds[k]->points[pointIndex[0]].intensity; } else { averagePoint.x += searchPoint.x; averagePoint.y += searchPoint.y; averagePoint.z += searchPoint.z; averagePoint.intensity += searchPoint.intensity; } } averagePoint.x /= allClouds.size(); averagePoint.y /= allClouds.size(); averagePoint.z /= allClouds.size(); averagePoint.intensity /= allClouds.size(); average->push_back(averagePoint); cout << " < (" << averagePoint.x << "," << averagePoint.y << "," << averagePoint.z << ")" << endl; } } void AerobicVision::Test2() { cout << "Starting..." << endl; usleep(500000); std::vector::Ptr> allClouds; for(int i = 0; i< 4; i++) { usleep(200000); if (! fg->WaitForFrame(img.get(), 2000)) { std::cerr << "Timeout waiting for camera!" << std::endl; } usleep(500000); pcl::PointCloud::Ptr cloudIn = img->Cloud()->makeShared(); allClouds.push_back(cloudIn); std::cout << "Taken pic " << i << endl; } //New cloud pcl::PointCloud::Ptr average (new pcl::PointCloud); average->width = allClouds[0]->width; average->height = allClouds[0]->height; average->points.resize(allClouds[0]->points.size()); //Average all clouds AverageCloudsKdTree(average, allClouds); //PrintCloud(average); //Visualize cloud pcl::visualization::CloudViewer viewer("Cloud Viewer"); viewer.showCloud(average); cout << "Press Enter" << endl; cin.get(); return; } /////////////////////////////////////////////////////// //Projectgroep 2 implementatie /////////////////////////////////////////////////////// pcl::PointXYZ AerobicVision::runAlgorithm(double &rotation, pcl::PointCloud::Ptr &showcloud) { //logging method o3d3xx::Logging::Init(); //initialise camera constructor expects IP address, using default one o3d3xx::Camera::Ptr cam = std::make_shared("192.168.1.69"); //create buffer to fetch image o3d3xx::ImageBuffer::Ptr img = std::make_shared(); //framegrabber o3d3xx::FrameGrabber::Ptr fg =std::make_shared(cam, o3d3xx::IMG_AMP|o3d3xx::IMG_RDIS|o3d3xx::IMG_CART); if (! fg->WaitForFrame(img.get(), 2000)) { std::cerr << "Timeout waiting for camera!" << std::endl; return pcl::PointXYZ(0,0,0); } //3D pointcloud pcl::PointCloud::Ptr xfilt (new pcl::PointCloud); pcl::PointCloud::Ptr yfilt (new pcl::PointCloud); pcl::PointCloud::Ptr zfilt (new pcl::PointCloud); //convert o3d3xx cloud to PointXYZ pcl::PointCloud::Ptr temp_cloud = img->Cloud(); pcl::PointCloud::Ptr cloud (new pcl::PointCloud); pcl::PointCloud::Ptr segment (new pcl::PointCloud); copyCloud(temp_cloud,cloud); pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud); pcl::PointCloud::Ptr vox_cloud (new pcl::PointCloud); // cut the z axis of pcl pcl::PassThrough passz; passz.setInputCloud (cloud); passz.setFilterFieldName ("z"); passz.setFilterLimits (-0.125,0.105); passz.filter (*zfilt); // cut the y axis of pcl pcl::PassThrough passy; passy.setInputCloud (zfilt); passy.setFilterFieldName ("y"); passy.setFilterLimits (-0.1,0.075); passy.filter (*yfilt); // Create the filtering object pcl::StatisticalOutlierRemoval sor; sor.setInputCloud (yfilt); sor.setMeanK (100); sor.setStddevMulThresh (0.5); sor.filter (*cloud_filtered); // Create the filtering object pcl::VoxelGrid vox; pcl::PointCloud::Ptr cluster_cloud (new pcl::PointCloud); vox.setInputCloud (cloud_filtered); vox.setLeafSize (0.001f, 0.001f, 0.001f); vox.filter (*vox_cloud); // cut the x axis of pcl pcl::PassThrough passx; passx.setInputCloud (vox_cloud); passx.setFilterFieldName ("x"); passx.setFilterLimits (0.3, .63);//0.3,0.63 passx.filter (*xfilt); /* pcl::visualization::CloudViewer viewer("Filtered cloud"); viewer.showCloud(xfilt); while (!viewer.wasStopped ()) { }*/ vector points; if(xfilt->points.size()>0) { GetObject(xfilt, points); } else { return pcl::PointXYZ(1000,1000,1000); } showcloud = xfilt; rotation = GetRotation(xfilt,points); /* std::vector indices; std::vector::Ptr> filteredCloud; pcl::PointCloud::Ptr color (new pcl::PointCloud); //Eigen::Vector4f min_pt,max_pt; //pcl::getMinMax3D(xfilt,indices,min_pt,max_pt); getClusters(xfilt, indices, color); for(int i = 0; i < indices.size();i++) { pcl::PointCloud::Ptr cld (new pcl::PointCloud); filteredCloud.push_back(cld); for(int k = 0; k < indices[i].indices.size(); k++) { filteredCloud[i]->push_back(xfilt->points[ indices[i].indices[k] ]); } } FeatureExtractor(filteredCloud); /* for(int i = 0; i < filteredCloud.size(); i++) { cout << "Opening viewer for cloud " << to_string(i) << "/" << filteredCloud.size() << endl; pcl::visualization::CloudViewer viewer("Filtered cloud #" + to_string(i)); viewer.showCloud(filteredCloud[i]); usleep(1000000); cout << "Press enter to continue" << endl; while (!viewer.wasStopped ()){} //pcl::visualization::PCLVisualizer viewer ("Filtered cloud #" + to_string(i)); //viewer.addPointCloud(filteredCloud[i],"cloud"); //while (!viewer.wasStopped ()) //{ // viewer.spinOnce(100); //} } cin.ignore(); */ return points[2]; } double AerobicVision::GetRotation(pcl::PointCloud::Ptr &in,vector &points) { Eigen::Vector3f major,middle,minor; double rotation; pcl::MomentOfInertiaEstimation feature_extractor; feature_extractor.setInputCloud(in); feature_extractor.compute(); feature_extractor.getEigenVectors (major,middle,minor); float length,height; length = points[1].y - points[0].y; height = points[1].z - points[0].z; bool useMajorVector = false; if(height > length) { if(height < 0.04) { useMajorVector = true; } } else { if(length > height) { if(length < 0.04) { useMajorVector = true; } } } if(useMajorVector) { rotation = acos(major[2]); } else { rotation = acos(middle[2]); } cout << setprecision(15) << rotation << endl; //cout << major[0] << "," << major[1] << "," << major[2] << endl; //cout << middle[0] << "," << middle[1] << "," << middle[2] << endl; //cout<< rotation.x <<"," << rotation.y << "," << rotation.z << endl; return rotation; } bool AerobicVision::GetObject(pcl::PointCloud::Ptr &in, vector &out) { float treshold = 0.01f; pcl::PointXYZ highPoint = pcl::PointXYZ(1000,1000,1000); pcl::PointXYZ AA,BB; pcl::PointCloud::Ptr toFilter(new pcl::PointCloud); for(int i = 0; i< in->points.size();i++) { if(in->points[i].x < highPoint.x) { highPoint = in->points[i]; } } // cut the z axis of pcl // cut the x axis of pcl pcl::PassThrough passx; passx.setInputCloud (in); passx.setFilterFieldName ("x"); passx.setFilterLimits (highPoint.x-treshold, highPoint.x +treshold);//0.3,0.63 passx.filter (*toFilter); std::vector::Ptr> clusters; pcl::PointCloud::Ptr color (new pcl::PointCloud); getClusters(toFilter, clusters, color); AA = clusters[0]->points[0]; BB = clusters[0]->points[0]; /* pcl::visualization::CloudViewer viewer("Filtered cloud #"); viewer.showCloud(clusters[0]); while (!viewer.wasStopped ()) { } */ for(pcl::PointXYZ point : clusters[0]->points) { if(point.y < AA.y) { AA.y = point.y; } if(point.y > BB.y) { BB.y = point.y; } if(point.z < AA.z) { AA.z = point.z; } if(point.z> BB.z) { BB.z = point.z; } } out.push_back(AA); out.push_back(BB); highPoint.y = (AA.y+BB.y)/2; highPoint.z = (AA.z+BB.z)/2; out.push_back(highPoint); std::cout << "Found AA " << AA.x << ", " << AA.y << ", " << AA.z << endl; std::cout << "Found BB " << BB.x << ", " << BB.y << ", " << BB.z << endl; std::cout << "Found CC " << highPoint.x << ", " << highPoint.y << ", " << highPoint.z << endl; return true; } void AerobicVision::copyCloud(pcl::PointCloud::Ptr &in, pcl::PointCloud::Ptr &out) { for(int i = 0; i< in->points.size(); i++) { pcl::PointXYZ p = pcl::PointXYZ(in->points[i].x, in->points[i].y, in->points[i].z); out->push_back(p); } } void AerobicVision::getClusters(pcl::PointCloud::Ptr &in, std::vector::Ptr> &out, pcl::PointCloud::Ptr &colorout) { // find the normals pcl::search::Search::Ptr tree = boost::shared_ptr > (new pcl::search::KdTree); pcl::PointCloud::Ptr normals (new pcl::PointCloud); tree->setInputCloud(in); pcl::NormalEstimation normal_estimator; normal_estimator.setSearchMethod (tree); normal_estimator.setInputCloud (in); //normal_estimator.setKSearch (50); normal_estimator.setRadiusSearch (0.001); normal_estimator.compute (*normals); // region growing pcl::RegionGrowing reg; std::vector indices; reg.setMinClusterSize (25); reg.setMaxClusterSize (2000); reg.setSearchMethod (tree); reg.setNumberOfNeighbours (15); reg.setInputCloud (in); //reg.setIndices (indices); reg.setInputNormals (normals); reg.setSmoothnessThreshold (2.0 / 180.0 * M_PI);// graden naar radial reg.setCurvatureThreshold (1.0); reg.extract (indices); colorout = reg.getColoredCloud(); for(int i = 0; i < indices.size();i++) { pcl::PointCloud::Ptr cld (new pcl::PointCloud); out.push_back(cld); for(int k = 0; k < indices[i].indices.size(); k++) { out[i]->push_back(in->points[ indices[i].indices[k] ]); } } } bool AerobicVision::FeatureExtractor(std::vector::Ptr> &in) { for(int i = 0; i < in.size()-1; i++) { cout << "Showing object " << i << endl; pcl::MomentOfInertiaEstimation feature_extractor; feature_extractor.setInputCloud (in[i]); feature_extractor.compute (); std::vector moment_of_inertia; std::vector eccentricity; pcl::PointXYZ min_point_AABB; pcl::PointXYZ max_point_AABB; pcl::PointXYZ min_point_OBB; pcl::PointXYZ max_point_OBB; pcl::PointXYZ position_OBB; Eigen::Matrix3f rotational_matrix_OBB; float major_value, middle_value, minor_value; Eigen::Vector3f major_vector, middle_vector, minor_vector; Eigen::Vector3f mass_center; feature_extractor.getMomentOfInertia (moment_of_inertia); feature_extractor.getEccentricity (eccentricity); feature_extractor.getAABB (min_point_AABB, max_point_AABB); feature_extractor.getOBB (min_point_OBB, max_point_OBB, position_OBB, rotational_matrix_OBB); feature_extractor.getEigenValues (major_value, middle_value, minor_value); feature_extractor.getEigenVectors (major_vector, middle_vector, minor_vector); feature_extractor.getMassCenter (mass_center); boost::shared_ptr viewer (new pcl::visualization::PCLVisualizer ("3D Viewer")); viewer->setBackgroundColor (0, 0, 0); viewer->addCoordinateSystem (1.0); viewer->initCameraParameters (); viewer->addPointCloud (in[i], "sample cloud"); viewer->addCube (min_point_AABB.x, max_point_AABB.x, min_point_AABB.y, max_point_AABB.y, min_point_AABB.z, max_point_AABB.z, 1.0, 1.0, 0.0, "AABB"); Eigen::Vector3f position (position_OBB.x, position_OBB.y, position_OBB.z); Eigen::Quaternionf quat (rotational_matrix_OBB); viewer->addCube (position, quat, max_point_OBB.x - min_point_OBB.x, max_point_OBB.y - min_point_OBB.y, max_point_OBB.z - min_point_OBB.z, "OBB"); pcl::PointXYZ center (mass_center (0), mass_center (1), mass_center (2)); pcl::PointXYZ x_axis (major_vector (0) + mass_center (0), major_vector (1) + mass_center (1), major_vector (2) + mass_center (2)); pcl::PointXYZ y_axis (middle_vector (0) + mass_center (0), middle_vector (1) + mass_center (1), middle_vector (2) + mass_center (2)); pcl::PointXYZ z_axis (minor_vector (0) + mass_center (0), minor_vector (1) + mass_center (1), minor_vector (2) + mass_center (2)); viewer->addLine (center, x_axis, 1.0f, 0.0f, 0.0f, "major eigen vector"); viewer->addLine (center, y_axis, 0.0f, 1.0f, 0.0f, "middle eigen vector"); viewer->addLine (center, z_axis, 0.0f, 0.0f, 1.0f, "minor eigen vector"); while(!viewer->wasStopped()) { viewer->spinOnce (100); boost::this_thread::sleep (boost::posix_time::microseconds (100000)); } } return true; }