|
@@ -8,7 +8,8 @@
|
|
#include <pcl/filters/statistical_outlier_removal.h>
|
|
#include <pcl/filters/statistical_outlier_removal.h>
|
|
#include <pcl/filters/project_inliers.h>
|
|
#include <pcl/filters/project_inliers.h>
|
|
#include <pcl/surface/convex_hull.h>
|
|
#include <pcl/surface/convex_hull.h>
|
|
-
|
|
|
|
|
|
+#include <pcl/features/moment_of_inertia_estimation.h>
|
|
|
|
+#include <pcl/common/centroid.h>
|
|
void save_rgb_cloud_txt(std::string txt, pcl::PointCloud<pcl::PointXYZRGB>::Ptr pCloud)
|
|
void save_rgb_cloud_txt(std::string txt, pcl::PointCloud<pcl::PointXYZRGB>::Ptr pCloud)
|
|
{
|
|
{
|
|
std::ofstream os;
|
|
std::ofstream os;
|
|
@@ -169,13 +170,15 @@ Cnn3d_segmentation::Cnn3d_segmentation(int l, int w, int h,int freq,int classes)
|
|
|
|
|
|
Cnn3d_segmentation::~Cnn3d_segmentation()
|
|
Cnn3d_segmentation::~Cnn3d_segmentation()
|
|
{
|
|
{
|
|
- tf_wheel_3dcnn_close();
|
|
|
|
|
|
+ //3dcnn 原校验功能保留,不加载网络
|
|
|
|
+ //tf_wheel_3dcnn_close();
|
|
}
|
|
}
|
|
|
|
|
|
Error_manager Cnn3d_segmentation::init(std::string weights)
|
|
Error_manager Cnn3d_segmentation::init(std::string weights)
|
|
{
|
|
{
|
|
-
|
|
|
|
- if (0 != tf_wheel_3dcnn_init(weights, m_lenth,m_width,m_height))
|
|
|
|
|
|
+ //3dcnn 原校验功能保留,不加载网络
|
|
|
|
+ return SUCCESS;
|
|
|
|
+ /*if (0 != tf_wheel_3dcnn_init(weights, m_lenth,m_width,m_height))
|
|
{
|
|
{
|
|
std::string error_description="tf_wheel_3Dcnn model load failed :";
|
|
std::string error_description="tf_wheel_3Dcnn model load failed :";
|
|
error_description+=weights;
|
|
error_description+=weights;
|
|
@@ -193,11 +196,20 @@ Error_manager Cnn3d_segmentation::init(std::string weights)
|
|
}
|
|
}
|
|
free(data);
|
|
free(data);
|
|
free(pout);
|
|
free(pout);
|
|
- return SUCCESS;
|
|
|
|
|
|
+ return SUCCESS;*/
|
|
}
|
|
}
|
|
|
|
|
|
-std::vector<cv::Point2f> Cnn3d_segmentation::kmeans(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud, std::string file_path)
|
|
|
|
|
|
+std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> Cnn3d_segmentation::kmeans(
|
|
|
|
+ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud,std::string file_path)
|
|
{
|
|
{
|
|
|
|
+ std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> kmens_out_clouds;
|
|
|
|
+ for(int i=0;i<4;++i)
|
|
|
|
+ {
|
|
|
|
+ pcl::PointCloud<pcl::PointXYZ>::Ptr t_cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
|
|
|
+ kmens_out_clouds.push_back(t_cloud);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //开始分割
|
|
std::vector<cv::Point2f> cv_points;
|
|
std::vector<cv::Point2f> cv_points;
|
|
for (int i = 0; i < cloud->size(); ++i)
|
|
for (int i = 0; i < cloud->size(); ++i)
|
|
{
|
|
{
|
|
@@ -228,6 +240,16 @@ std::vector<cv::Point2f> Cnn3d_segmentation::kmeans(pcl::PointCloud<pcl::PointXY
|
|
clusters[cluste_index].push_back(point);
|
|
clusters[cluste_index].push_back(point);
|
|
sumX[cluste_index] += point.x;
|
|
sumX[cluste_index] += point.x;
|
|
sumY[cluste_index] += point.y;
|
|
sumY[cluste_index] += point.y;
|
|
|
|
+
|
|
|
|
+ pcl::PointXYZ t_point3d;
|
|
|
|
+ t_point3d.x=cloud->points[i].x;
|
|
|
|
+ t_point3d.y=cloud->points[i].y;
|
|
|
|
+ t_point3d.z=cloud->points[i].z;
|
|
|
|
+ if(cluste_index>=0&&cluste_index<4)
|
|
|
|
+ {
|
|
|
|
+ kmens_out_clouds[cluste_index]->push_back(t_point3d);
|
|
|
|
+ }
|
|
|
|
+
|
|
if (cluste_index == 0)
|
|
if (cluste_index == 0)
|
|
{
|
|
{
|
|
cloud->points[i].r = 255;
|
|
cloud->points[i].r = 255;
|
|
@@ -268,7 +290,7 @@ std::vector<cv::Point2f> Cnn3d_segmentation::kmeans(pcl::PointCloud<pcl::PointXY
|
|
}
|
|
}
|
|
std::string save_file=file_path+"/cnn3d.txt";
|
|
std::string save_file=file_path+"/cnn3d.txt";
|
|
save_rgb_cloud_txt(save_file, cloud);
|
|
save_rgb_cloud_txt(save_file, cloud);
|
|
- return rets;
|
|
|
|
|
|
+ return kmens_out_clouds;
|
|
|
|
|
|
|
|
|
|
/*int clusterCount = 4;
|
|
/*int clusterCount = 4;
|
|
@@ -283,24 +305,31 @@ std::vector<cv::Point2f> Cnn3d_segmentation::kmeans(pcl::PointCloud<pcl::PointXY
|
|
clusterCount = MIN(clusterCount, sampleCount);
|
|
clusterCount = MIN(clusterCount, sampleCount);
|
|
cv::Mat centers(clusterCount, 1, points.type()); //�����洢���������ĵ�
|
|
cv::Mat centers(clusterCount, 1, points.type()); //�����洢���������ĵ�
|
|
cv::RNG rng(12345); //�����������
|
|
cv::RNG rng(12345); //�����������
|
|
- / * generate random sample from multigaussian distribution * /
|
|
|
|
|
|
+
|
|
|
|
|
|
cv::kmeans(points, clusterCount, labels,
|
|
cv::kmeans(points, clusterCount, labels,
|
|
cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 500, 15.0),
|
|
cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 500, 15.0),
|
|
- 5, cv::KMEANS_PP_CENTERS, centers); //����3�Σ�ȡ�����õ��ǴΣ�����ij�ʼ������PP�ض�������㷨��
|
|
|
|
|
|
+ 5, cv::KMEANS_PP_CENTERS, centers);
|
|
|
|
+
|
|
|
|
|
|
- std::vector<cv::Point2f> rets;
|
|
|
|
- for (int i = 0; i < clusterCount; ++i)
|
|
|
|
- rets.push_back(centers.at<cv::Point2f>(i));
|
|
|
|
|
|
|
|
for (int i = 0; i < sampleCount; i++)
|
|
for (int i = 0; i < sampleCount; i++)
|
|
{
|
|
{
|
|
int clusterIdx = labels.at<int>(i);
|
|
int clusterIdx = labels.at<int>(i);
|
|
|
|
+ pcl::PointXYZ point;
|
|
|
|
+ point.x=cloud->points[i].x;
|
|
|
|
+ point.y=cloud->points[i].y;
|
|
|
|
+ point.z=cloud->points[i].z;
|
|
|
|
+ if(clusterIdx>=0&&clusterIdx<4)
|
|
|
|
+ {
|
|
|
|
+ kmens_out_clouds[clusterIdx]->push_back(point);
|
|
|
|
+ }
|
|
if (clusterIdx == 0)
|
|
if (clusterIdx == 0)
|
|
{
|
|
{
|
|
cloud->points[i].r = 255;
|
|
cloud->points[i].r = 255;
|
|
cloud->points[i].g = 0;
|
|
cloud->points[i].g = 0;
|
|
cloud->points[i].b = 0;
|
|
cloud->points[i].b = 0;
|
|
|
|
+
|
|
}
|
|
}
|
|
else if (clusterIdx == 1)
|
|
else if (clusterIdx == 1)
|
|
{
|
|
{
|
|
@@ -323,8 +352,9 @@ std::vector<cv::Point2f> Cnn3d_segmentation::kmeans(pcl::PointCloud<pcl::PointXY
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
- save_rgb_cloud_txt(sava_path + "/kmeans.txt", cloud);
|
|
|
|
- return rets;*/
|
|
|
|
|
|
+ std::string save_file=file_path+"/cnn3d.txt";
|
|
|
|
+ save_rgb_cloud_txt(save_file, cloud);*/
|
|
|
|
+ return kmens_out_clouds;
|
|
}
|
|
}
|
|
|
|
|
|
Error_manager Cnn3d_segmentation::isRect(std::vector<cv::Point2f>& points)
|
|
Error_manager Cnn3d_segmentation::isRect(std::vector<cv::Point2f>& points)
|
|
@@ -451,98 +481,192 @@ void save_cloudT(std::string txt, pcl::PointCloud<pcl::PointXYZ>& pCloud)
|
|
os.close();
|
|
os.close();
|
|
}
|
|
}
|
|
|
|
|
|
-Error_manager Cnn3d_segmentation::predict(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, cv::RotatedRect& rect,
|
|
|
|
- std::string cluster_file_path)
|
|
|
|
|
|
+Error_manager Cnn3d_segmentation::predict(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
|
|
|
|
+ float& center_x,float& center_y,float& wheel_base,
|
|
|
|
+ float& width,float& angle,std::string cluster_file_path)
|
|
{
|
|
{
|
|
|
|
+ if(cloud.get()==NULL)
|
|
|
|
+ {
|
|
|
|
+ return Error_manager(LOCATER_3DCNN_INPUT_CLOUD_EMPTY,NORMAL,"3dcnn predict input cloud uninit");
|
|
|
|
+ }
|
|
if(cloud->size()==0)
|
|
if(cloud->size()==0)
|
|
{
|
|
{
|
|
return Error_manager(LOCATER_3DCNN_INPUT_CLOUD_EMPTY,NORMAL,"3dcnn predict input cloud empty");
|
|
return Error_manager(LOCATER_3DCNN_INPUT_CLOUD_EMPTY,NORMAL,"3dcnn predict input cloud empty");
|
|
}
|
|
}
|
|
|
|
|
|
- pcl::PointXYZ minp, maxp;
|
|
|
|
- pcl::getMinMax3D(*cloud, minp, maxp);
|
|
|
|
- float center_x = (minp.x + maxp.x) / 2.0;
|
|
|
|
- float center_y = (minp.y + maxp.y) / 2.0;
|
|
|
|
- float center_z = (minp.z + maxp.z) / 2.0;
|
|
|
|
- float min_x = center_x - m_lenth / 2.0*m_freq;
|
|
|
|
- float max_x = center_x + m_lenth / 2.0*m_freq;
|
|
|
|
- float min_y = center_y - m_width / 2.0*m_freq;
|
|
|
|
- float max_y = center_y + m_width / 2.0*m_freq;
|
|
|
|
- float min_z = center_z - m_height / 2.0*m_freq;
|
|
|
|
- float max_z = center_z + m_height / 2.0*m_freq;
|
|
|
|
-
|
|
|
|
- float* data = generate_tensor(cloud, min_x, max_x, min_y, max_y, min_z, max_z);
|
|
|
|
- float* pout = (float*)malloc(m_lenth*m_width*m_height*m_nClass*sizeof(float));
|
|
|
|
clock_t clock1 = clock();
|
|
clock_t clock1 = clock();
|
|
- if (!tf_wheel_3dcnn_predict(data, pout))
|
|
|
|
- {
|
|
|
|
- free(data);
|
|
|
|
- free(pout);
|
|
|
|
- return Error_manager(LOCATER_3DCNN_PREDICT_FAILED,NORMAL,"3dcnn first predict failed");
|
|
|
|
- }
|
|
|
|
|
|
|
|
- std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> cloudout = decodeCloud(*cloud, pout, min_x, max_x, min_y, max_y, min_z, max_z);
|
|
|
|
- free(data);
|
|
|
|
- free(pout);
|
|
|
|
|
|
+ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudout(new pcl::PointCloud<pcl::PointXYZRGB>);
|
|
|
|
+ pcl::copyPointCloud(*cloud,*cloudout);
|
|
|
|
|
|
|
|
|
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr last_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
|
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr last_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
|
|
- for (int i = 0; i < cloudout.size(); ++i)
|
|
|
|
- {
|
|
|
|
- last_cloud->operator+=(*cloudout[i]);
|
|
|
|
- }
|
|
|
|
|
|
|
|
- if (cloudout.size() == 0)
|
|
|
|
- {
|
|
|
|
- return Error_manager(LOCATER_3DCNN_PREDICT_FAILED,NORMAL,"tf pred classes ==0");
|
|
|
|
- }
|
|
|
|
- if (cloudout[0]->size() == 0)
|
|
|
|
|
|
+ if (cloudout->size() == 0)
|
|
{
|
|
{
|
|
return Error_manager(LOCATER_3DCNN_PREDICT_FAILED,NORMAL,"tf pred class[wheel].points size ==0");
|
|
return Error_manager(LOCATER_3DCNN_PREDICT_FAILED,NORMAL,"tf pred class[wheel].points size ==0");
|
|
}
|
|
}
|
|
//离群点过滤
|
|
//离群点过滤
|
|
pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> sorfilter(true); // Initializing with true will allow us to extract the removed indices
|
|
pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> sorfilter(true); // Initializing with true will allow us to extract the removed indices
|
|
- sorfilter.setInputCloud(cloudout[0]);
|
|
|
|
- sorfilter.setMeanK(15);
|
|
|
|
- sorfilter.setStddevMulThresh(4.0);
|
|
|
|
- sorfilter.filter(*cloudout[0]);
|
|
|
|
|
|
+ sorfilter.setInputCloud(cloudout);
|
|
|
|
+ sorfilter.setMeanK(20);
|
|
|
|
+ sorfilter.setStddevMulThresh(2.0);
|
|
|
|
+ sorfilter.filter(*cloudout);
|
|
|
|
|
|
- if (cloudout[0]->size() < 4 )
|
|
|
|
|
|
+ if (cloudout->size() < 4 )
|
|
{
|
|
{
|
|
return Error_manager(LOCATER_3DCNN_PREDICT_FAILED,NORMAL,"tf pred wheel points size <4");
|
|
return Error_manager(LOCATER_3DCNN_PREDICT_FAILED,NORMAL,"tf pred wheel points size <4");
|
|
}
|
|
}
|
|
//kmeans
|
|
//kmeans
|
|
- std::vector<cv::Point2f> centers = kmeans(cloudout[0], cluster_file_path);
|
|
|
|
|
|
+ std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> kmeans_out_clouds = kmeans(cloudout, cluster_file_path);
|
|
|
|
+ //对kmeans结果点云作pca filter
|
|
|
|
+ std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> pca_filter_clouds;
|
|
|
|
+ for(int i=0;i<4;++i)
|
|
|
|
+ {
|
|
|
|
+ pcl::PointCloud<pcl::PointXYZ>::Ptr t_cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
|
|
|
+ pca_filter_clouds.push_back(t_cloud);
|
|
|
|
+ }
|
|
|
|
+ for(int i=0;i<kmeans_out_clouds.size();++i)
|
|
|
|
+ {
|
|
|
|
+ pca_minist_axis_filter(kmeans_out_clouds[i],pca_filter_clouds[i]);
|
|
|
|
+
|
|
|
|
+ char buf[255]={0};
|
|
|
|
+ sprintf(buf,"%s/pca_wheel_%d.txt",cluster_file_path.c_str(),i);
|
|
|
|
+ save_cloudT(buf,*pca_filter_clouds[i]);
|
|
|
|
+ }
|
|
|
|
+ //计算pca filter点云中心
|
|
|
|
+ std::vector<cv::Point2f> centers;
|
|
|
|
+ for(int i=0;i<pca_filter_clouds.size();++i)
|
|
|
|
+ {
|
|
|
|
+ if(pca_filter_clouds[i]->size()!=0) {
|
|
|
|
+ Eigen::Vector4f centroid;
|
|
|
|
+ pcl::compute3DCentroid(*pca_filter_clouds[i], centroid);
|
|
|
|
+ centers.push_back(cv::Point2f(centroid[0],centroid[1]));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ //将pca过滤后的轮胎点转换成opencv点,用于计算角度与宽
|
|
std::vector<cv::Point2f> wheel_points;
|
|
std::vector<cv::Point2f> wheel_points;
|
|
- for(int i=0;i<cloudout[0]->size();++i)
|
|
|
|
|
|
+ for(int i=0;i<pca_filter_clouds.size();++i)
|
|
{
|
|
{
|
|
- wheel_points.push_back(cv::Point2f(cloudout[0]->points[i].x,cloudout[0]->points[i].y));
|
|
|
|
|
|
+ for(int j=0;j<pca_filter_clouds[i]->size();++j)
|
|
|
|
+ wheel_points.push_back(cv::Point2f(pca_filter_clouds[i]->points[j].x,
|
|
|
|
+ pca_filter_clouds[i]->points[j].y));
|
|
}
|
|
}
|
|
if (centers.size() != 4 && centers.size()!=3)
|
|
if (centers.size() != 4 && centers.size()!=3)
|
|
{
|
|
{
|
|
return Error_manager(LOCATER_3DCNN_KMEANS_FAILED,NORMAL,"3dcnn cluster center size != 4 & 3");
|
|
return Error_manager(LOCATER_3DCNN_KMEANS_FAILED,NORMAL,"3dcnn cluster center size != 4 & 3");
|
|
}
|
|
}
|
|
|
|
+ //取四轮中心计算轴长
|
|
Error_manager code=isRect(centers);
|
|
Error_manager code=isRect(centers);
|
|
if(code!=SUCCESS)
|
|
if(code!=SUCCESS)
|
|
{
|
|
{
|
|
return code;
|
|
return code;
|
|
}
|
|
}
|
|
|
|
+
|
|
if(centers.size()==3)
|
|
if(centers.size()==3)
|
|
{
|
|
{
|
|
wheel_points.push_back(centers[centers.size()-1]);
|
|
wheel_points.push_back(centers[centers.size()-1]);
|
|
}
|
|
}
|
|
- rect = minAreaRect_cloud(centers);
|
|
|
|
|
|
+
|
|
|
|
+ cv::RotatedRect rect_center = minAreaRect_cloud(centers);
|
|
cv::RotatedRect rect_wheels=minAreaRect_cloud(wheel_points);
|
|
cv::RotatedRect rect_wheels=minAreaRect_cloud(wheel_points);
|
|
- rect.center=rect_wheels.center;
|
|
|
|
- bool IOU = check_box(rect, cloud);
|
|
|
|
- if(IOU==false){
|
|
|
|
|
|
+ bool IOU = check_box(rect_center, cloud);
|
|
|
|
+ if(IOU==false){
|
|
return Error_manager(LOCATER_3DCNN_IIU_FAILED,NORMAL,"IIU check box failed");
|
|
return Error_manager(LOCATER_3DCNN_IIU_FAILED,NORMAL,"IIU check box failed");
|
|
- }
|
|
|
|
- LOG(INFO)<<"3dcnn rotate rect center :"<<rect.center<<" size : "<<rect.size;
|
|
|
|
|
|
+ }
|
|
|
|
+ //开始赋值
|
|
|
|
+ center_x=rect_center.center.x;
|
|
|
|
+ center_y=rect_center.center.y;
|
|
|
|
+ wheel_base=std::max(rect_center.size.height,rect_center.size.width);
|
|
|
|
+ width=std::min(rect_center.size.height,rect_center.size.width);
|
|
|
|
+ //根据 rect_wheel 计算角度
|
|
|
|
+ const double C_PI=3.14159265;
|
|
|
|
+ cv::Point2f vec;
|
|
|
|
+ cv::Point2f vertice[4];
|
|
|
|
+ rect_wheels.points(vertice);
|
|
|
|
+ float len1 = pow(vertice[0].x - vertice[1].x, 2.0) + pow(vertice[0].y - vertice[1].y, 2.0);
|
|
|
|
+ float len2 = pow(vertice[1].x - vertice[2].x, 2.0) + pow(vertice[1].y - vertice[2].y, 2.0);
|
|
|
|
+ if (len1 > len2) {
|
|
|
|
+ vec.x = vertice[0].x - vertice[1].x;
|
|
|
|
+ vec.y = vertice[0].y - vertice[1].y;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ vec.x = vertice[1].x - vertice[2].x;
|
|
|
|
+ vec.y = vertice[1].y - vertice[2].y;
|
|
|
|
+ }
|
|
|
|
+ angle = 180.0 / C_PI * acos(vec.x / sqrt(vec.x * vec.x + vec.y * vec.y));
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ LOG(INFO)<<"3dcnn rotate rect center :"<<rect_center.center<<" size : "<<rect_center.size<<" angle:"<<angle;
|
|
|
|
|
|
return SUCCESS;
|
|
return SUCCESS;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+Error_manager Cnn3d_segmentation::pca_minist_axis_filter(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in,
|
|
|
|
+ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out)
|
|
|
|
+{
|
|
|
|
+ if(cloud_in.get()==NULL)
|
|
|
|
+ {
|
|
|
|
+ return Error_manager(PARAMETER_ERROR,NORMAL,"pca_minist_axis_filter input cloud uninit");
|
|
|
|
+ }
|
|
|
|
+ if(cloud_in->size()==0)
|
|
|
|
+ {
|
|
|
|
+ return Error_manager(PARAMETER_ERROR,NORMAL,"pca_minist_axis_filter input cloud empty");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //pca寻找主轴
|
|
|
|
+ pcl::MomentOfInertiaEstimation <pcl::PointXYZ> feature_extractor;
|
|
|
|
+ feature_extractor.setInputCloud (cloud_in);
|
|
|
|
+ feature_extractor.compute ();
|
|
|
|
+
|
|
|
|
+ std::vector <float> moment_of_inertia;
|
|
|
|
+ std::vector <float> 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);
|
|
|
|
+
|
|
|
|
+ //根据minor_vector 最小主轴方向,以及中心点, 计算轴所在三维平面
|
|
|
|
+ float x=mass_center[0];
|
|
|
|
+ float y=mass_center[1];
|
|
|
|
+ float z=mass_center[2];
|
|
|
|
+ float a=minor_vector[0];
|
|
|
|
+ float b=minor_vector[1];
|
|
|
|
+ float c=minor_vector[2];
|
|
|
|
+ float d=-(a*x+b*y+c*z);
|
|
|
|
+
|
|
|
|
+ //计算各点距离平面的距离,距离操过轮胎的一半厚,舍弃(100mm)
|
|
|
|
+ float S=sqrt(a*a+b*b+c*c);
|
|
|
|
+ for(int i=0;i<cloud_in->size();++i)
|
|
|
|
+ {
|
|
|
|
+ pcl::PointXYZ point=cloud_in->points[i];
|
|
|
|
+ if(fabs(point.x*a+point.y*b+point.z*c+d)/S <40 )
|
|
|
|
+ {
|
|
|
|
+ cloud_out->push_back(point);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*if(cloud_out->size()==0)
|
|
|
|
+ {
|
|
|
|
+ return Error_manager(LOCATER_3DCNN_PCA_OUT_CLOUD_EMPTY,NORMAL,"wheel pca filter out cloud empty");
|
|
|
|
+ }*/
|
|
|
|
+ return SUCCESS;
|
|
|
|
+}
|
|
|
|
+
|
|
bool Cnn3d_segmentation::check_box(cv::RotatedRect& box, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
|
|
bool Cnn3d_segmentation::check_box(cv::RotatedRect& box, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
|
|
{
|
|
{
|
|
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected_XY(new pcl::PointCloud<pcl::PointXYZ>);
|
|
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected_XY(new pcl::PointCloud<pcl::PointXYZ>);
|