Я пытаюсь использовать нечеткий метод кластеризации c-средних, который уничтожает 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;
}
Задача ещё не решена.
Других решений пока нет …