pcl库使用svm报错LNK2019无法解析的外部符号

编译环境: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天,您在需要使用的时候【私信】联系我,我会为您补发。

请问解决了吗