编译环境:vs2017,debug×64
使用svm分类器一直报错 error LNK2019: 无法解析的外部符号 svm_save_model,该符号在函数 "public: void __cdecl pcl::SVM::saveClassifierModel(char const *)" (?saveClassifierModel@SVM@pcl@@QEAAXPEBD@Z) 中被引用
在github上搜索过解决方案,说是修改svm_wrapper.h和svm.h这两个文件,这是解决方案https://github.com/PointCloudLibrary/pcl/issues/1726
照上面的修改依然报错。
这是我的代码
#include <vector>
#include <iostream>
#include <Eigen/Core>
#include "pcl/point_types.h"
#include "pcl/point_cloud.h"
#include "pcl/io/pcd_io.h"
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/vfh.h>
#include <pcl/visualization/pcl_plotter.h>
#include <pcl/ml/svm_wrapper.h>
//#include <pcl/ml/svm.h>
int number_(142);
pcl::SVMParam param_;
int nr_fold_(0);
//点云下采样
void
downsample(pcl::PointCloud<pcl::PointXYZ>::Ptr &points, float leaf_size,
pcl::PointCloud<pcl::PointXYZ>::Ptr &downsampled_out)
{
pcl::VoxelGrid<pcl::PointXYZ> vox_grid;
vox_grid.setLeafSize(leaf_size, leaf_size, leaf_size);
vox_grid.setInputCloud(points);
vox_grid.filter(*downsampled_out);
}
//计算表面法向量
void
compute_surface_normals(pcl::PointCloud<pcl::PointXYZ>::Ptr &points, float normal_radius,
pcl::PointCloud<pcl::Normal>::Ptr &normals_out)
{
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> norm_est;
// Use a KdTree to perform neighborhood searches
norm_est.setSearchMethod(pcl::search::KdTree<pcl::PointXYZ>::Ptr(new pcl::search::KdTree<pcl::PointXYZ>));
// Specify the size of the local neighborhood to use when computing the surface normals
norm_est.setRadiusSearch(normal_radius);
// Set the input points
norm_est.setInputCloud(points);
// Estimate the surface normals and store the result in "normals_out"
norm_est.compute(*normals_out);
}
//计算VFH特征值
void
compute_VFH_features(pcl::PointCloud<pcl::PointXYZ>::Ptr &points,
pcl::PointCloud<pcl::Normal>::Ptr &normals,
pcl::PointCloud<pcl::VFHSignature308>::Ptr &descriptors_out)
{
// 创建一个VFH特征描述对象
pcl::VFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::VFHSignature308> vfh_est;
//设置输入点云和表面法向量
vfh_est.setInputCloud(points);
vfh_est.setInputNormals(normals);
vfh_est.setSearchMethod(pcl::search::KdTree<pcl::PointXYZ>::Ptr(new pcl::search::KdTree<pcl::PointXYZ>));
// 可选的, 我们能够规范化结果直方图的值,
// 利用全部的点.
vfh_est.setNormalizeBins(true);
// Also, we can normalize the SDC with the maximum size found between
// the centroid and any of the cluster's points.
vfh_est.setNormalizeDistance(false);
// std::cout << "start compute VFH features descriptors" << std::endl;
//计算特征值
vfh_est.compute(*descriptors_out);
// std::cout << "Compute VFH descriptors successfully" << std::endl;
}
/* Function : output the *.txt file for Libsvm use*/
void
write2file(pcl::PointCloud<pcl::VFHSignature308>::Ptr &descriptors_vfh, const int count)
{
if (count == 0)
{
ofstream outFile("VFH_svm_features.txt");
if (!outFile)
{
printf("Error opening output file: %s!\n", "VFH_svm_features.txt");
exit(1);
}
for (size_t j = 0; j < descriptors_vfh->size(); j++)
{
outFile << "0 ";
for (int q = 0; q < 308; q++)
{
outFile << (q + 1) << ":" << descriptors_vfh->at(j).histogram[q] << " ";
}
}
outFile << std::endl;
}
else
{
ofstream ofresult("VFH_svm_features.txt", ios::app);
for (size_t k = 0; k < descriptors_vfh->size(); k++)
{
ofresult << count << " ";
for (int p = 0; p < 308; p++)
{
ofresult << (p + 1) << ":" << descriptors_vfh->at(k).histogram[p] << " ";
}
}
ofresult << std::endl;
if (count == number_) ofresult.close();
}
}
void
write2svmdata(pcl::PointCloud<pcl::VFHSignature308>::Ptr &descriptors_vfh,
const int count, std::vector<pcl::SVMData> &trainning_set)
{
std::vector<pcl::SVMDataPoint> svm_set;
for (size_t j = 0; j < descriptors_vfh->size(); j++)
{
for (int q = 0; q < 308; q++)
{
pcl::SVMDataPoint svm_point;
svm_point.idx = int(q + 1);
svm_point.value = descriptors_vfh->at(j).histogram[q];
svm_set.push_back(svm_point);
}
}
pcl::SVMData svm_data;
svm_data.label = count;
svm_data.SV = svm_set;
trainning_set.push_back(svm_data);
}
int main()
{
const char *modelFileName = "person_svm";//训练模型名称
std::vector<pcl::SVMData> tranning_dataset;
for (int i = 0; i < (number_ + 1); i++)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr points1(new pcl::PointCloud<pcl::PointXYZ>);//原始点云
pcl::PointCloud<pcl::PointXYZ>::Ptr downsampled1(new pcl::PointCloud<pcl::PointXYZ>);//点云下采样后
pcl::PointCloud<pcl::Normal>::Ptr normals1(new pcl::PointCloud<pcl::Normal>);//表面法向量
pcl::PointCloud<pcl::VFHSignature308>::Ptr descriptors_vfh1(new pcl::PointCloud<pcl::VFHSignature308>);//VFH特征描述子
std::stringstream ss0;
std::stringstream ss1, ss2;
//C://Users//QYQY//Desktop//np
ss1 << "C://Users//QYQY//Desktop//np//pedestrian" << i << ".pcd";
pcl::io::loadPCDFile(ss1.str(), *points1);
const float voxel_grid_leaf_size1 = 4.0;
downsample(points1, voxel_grid_leaf_size1, downsampled1);
const float normal_radius1 = 4.5;
compute_surface_normals(downsampled1, normal_radius1, normals1);
compute_VFH_features(downsampled1, normals1, descriptors_vfh1);
std::cout << "write features of model No." << i << std::endl;
// Store the VF histogram into the txt for libsvm input
write2svmdata(descriptors_vfh1, i, tranning_dataset);
}
std::cout << "All the SVM datas have been created" << std::endl;
// SVM trainning
pcl::SVMTrain Mytrainner;
Mytrainner.setParameters(param_);
Mytrainner.resetTrainingSet();
Mytrainner.setInputTrainingSet(tranning_dataset);
Mytrainner.trainClassifier();
Mytrainner.saveClassifierModel(modelFileName);
std::cout << "Output trainning model : " << modelFileName << std::endl;
return (0);
}
你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答
本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。
因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。
请问解决了吗