我试图使用模糊c-means聚类方法对pointcloud进行去噪,但是一旦我运行代码我得到调试错误R6010 - abort()已被调用。我该如何解决这个问题?
#include <pcl/point_cloud.h>
#include <pcl/octree/octree.h>
#include<pcl/filters/voxel_grid.h>
#include <iostream>
#include<pcl/io/pcd_io.h>
#include <vector>
#include<pcl/point_types.h>
#include<math.h>
#include<stdio.h>
int main()
{
//半径搜索中的邻居
//创建一个存储云点的向量
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
//加载文件
pcl::io::loadPCDFile("F:\\c++tutorial\\myproject\\10.11tomanikin\\objtopcd\\objtopcd\\0-2.pcd", *cloud);
//创建一个矢量来存储过滤后的浊点
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>());
pcl::VoxelGrid<pcl::PointXYZ>sor;
sor.setInputCloud(cloud);
sor.setLeafSize(0.01f, 0.01f, 0.01f);
sor.filter(*cloud_filtered);
std::vector<int> pointIdxRadiusSearch;
std::vector<float> pointRadiusSquaredDistance;
float radius = 0.02;
float resolution = 0.01f;
int m = 2;//smoothing weight
int c = 2;//Number of cluster centers
pcl::octree::OctreePointCloudSearch<pcl::PointXYZ> octree(resolution);
octree.setInputCloud(cloud_filtered);
octree.addPointsFromInputCloud();
int mount = cloud_filtered->points.size();
class point
{
public:
float x, y, z;
};
point Z;
float M = 0.0;
int s = 0, a = 0, n = 0;
float J1, J2;
//创建一个二维数组来存储成员矩阵
float U[5][50] = { 0 };
float G[50] = { 0 };
//创建一个二维数组来存储模糊权重 系数
float W[5][50] = { 0 };
point center[5];
for (int i = 0; i < c; i++)
{
center[i].x = 0;
center[i].y = 0;
center[i].z = 0;
}
//创建一个二维数组来存储距离的平方 从点到集群中心
float D2[5][50] = {0};
//开始迭代
for (int l = 0; l <mount; l++)
{
octree.radiusSearch(cloud_filtered->points[l], radius, pointIdxRadiusSearch, pointRadiusSquaredDistance);
n = pointIdxRadiusSearch.size();
//删除点
if (n< 10)
{
cloud_filtered->erase(cloud_filtered->begin() + l);
std::cout << l << std::endl;
l--;
mount--;
continue;
}
//清空所有数组
for (int i = 0; i < c; i++)
{
for (int j = 0; j < n; j++)
{
U[i][j] = 0;
}
}
for (int i = 0; i < c; i++)
{
for (int j = 0; j < n; j++)
{
W[i][j] = 0;
}
}
for (int i = 0; i < c; i++)
{
for (int j = 0; j < n; j++)
{
D2[i][j] = 0;
}
}
for (int i = 0; i < c; i++)
{
center[i].x = 0;
center[i].y = 0;
center[i].z = 0;
}
for (int i = 0; i < n; i++)
{
G[i] = 0;
}
//初始会员矩阵
for (int i = 0; i < c; i++)
{
for (int j = 0; j < n; j++)
{
U[i][j] = rand() % 100;
//std::cout << U[i][j] << "\t";
}
}
//规范化处理
for (int j = 0; j < n; j++)
{
for (int k = 0; k < c; k++)
{
G[j] = G[j] + U[k][j];
//std::cout << G[j];
}
std::cout << "\t";
}
for (int i = 0; i < c; i++)
{
for (int j = 0; j < n; j++)
{
U[i][j] /= G[j];
//std::cout << U[i][j] << "\t";
}
}
J1 = 0;
J2 = 0;
do
{
J1 = J2;
J2 = 0;
//计算集群中心
for (int i = 0; i < c; i++)
{
Z.x = 0; Z.y = 0; Z.z = 0, M = 0;
for (int j = 0; j < n; j++)
{
Z.x += pow(U[i][j], m)*cloud_filtered->points[pointIdxRadiusSearch[j]].x;
Z.y += pow(U[i][j], m)*cloud_filtered->points[pointIdxRadiusSearch[j]].y;
Z.z += pow(U[i][j], m)*cloud_filtered->points[pointIdxRadiusSearch[j]].z;
M += pow(U[i][j], m);
}
center[i].x = Z.x / M;
center[i].y = Z.y / M;
center[i].z = Z.z / M;
}
//计算模糊加权系数
for (int i = 0; i < c; i++)
{
M = 0;
for (int j = 0; j < n; j++)
{
M += U[i][j];
}
for (int j = 0; j < n; j++)
{
W[i][j] = U[i][j] / M;
}
}
//计算从点到群集的距离的平方 中心
for (int i = 0; i < c; i++)
{
for (int j = 0; j < n; j++)
{
D2[i][j] = (pow(cloud_filtered->points[pointIdxRadiusSearch[j]].x - center[i].x, 2) + pow(cloud_filtered->points[pointIdxRadiusSearch[j]].y - center[i].y, 2) + pow(cloud_filtered->points[pointIdxRadiusSearch[j]].z - center[i].z, 2)) / pow(W[i][j], 2);
}
}
//计算会员函数值
for (int i = 0; i < c; i++)
{
for (int j = 0; j < n; j++)
{
M = 0;
for (int k = 0; k < c; k++)
{
M += pow(D2[i][j] / D2[k][j], 1 / (m - 1));
}
U[i][j] = 1.0 / M;
}
}
//计算目标函数值
for (int i = 0; i < c; i++)
{
for (int j = 0; j < n; j++)
{
J2 += pow(U[i][j], m)*D2[i][j];
}
}
} while (abs(J1 - J2) > 1e-6);
//找到最大隶属函数值
s = 0;
for (int j = 0; j < n; j++)
{
if (cloud_filtered->points[l].x == cloud_filtered->points[pointIdxRadiusSearch[j]].x&&cloud_filtered->points[l].y == cloud_filtered->points[pointIdxRadiusSearch[j]].y&&cloud_filtered->points[l].z == cloud_filtered->points[pointIdxRadiusSearch[j]].z)
{
s = j;
break;
}
}
M = 0;
a = 0;
for (int i = 0; i < c; i++)
{
if (U[i][s]>M)
{
M = U[i][s];
a = i;
}
}
//std::cout << "this point" << cloud_filtered->points[l].x << "\t" << cloud_filtered->points[l].y << "\t" << cloud_filtered->points[l].z << std::endl;
//将此点更改为群集中心
cloud_filtered->points[l].x = center[a].x;
cloud_filtered->points[l].y = center[a].y;
cloud_filtered->points[l].z = center[a].z;
/*for (int i = 0; i < c; i++)
{
for (int j = 0; j < n; j++)
{
std::cout << U[i][j] << "\t";
}
std::cout << std::endl;
}
*/
//std::cout << "new point" << cloud_filtered->points[l].x << "\t" << cloud_filtered->points[l].y << "\t" << cloud_filtered->points[l].z << std::endl;
}
pcl::io::savePCDFile("cloud_after_fcm.pcd", *cloud_filtered);
return 0;
}