我在处理OpenCV
/ C++
项目时遇到了一个奇怪的问题。我只是想在KNN
课程中使用ClassifierManager
。出于这个原因,我正在使用cv::flann::Index * knnFlan
,它在构造函数中初始化,如下所示:
·H
class ClassifierManager
{
private:
Mat dataToTrain;
Mat classesData;
int kNearestNeighborToConsider;
CvKNearest *classifier;
cv::flann::Index *knnFlan;
public:
ClassifierManager();
ClassifierManager(Mat trainData, Mat dataClasses, int numberOfNearestNeighborToConsider);
vector < vector <int> > annotateTheTilesInImages(Mat trainData, vector < vector < vector <double> > > featuresPerImageForTiles, int numberOfNearestNeighborToConsider);
};
的.m
ClassifierManager::ClassifierManager()
{}
ClassifierManager::ClassifierManager(Mat trainData, Mat dataClasses, int numberOfNearestNeighborToConsider)
{
// dataToTrain = trainData;
// classesData = dataClasses;
kNearestNeighborToConsider = numberOfNearestNeighborToConsider;
try
{
dataClasses.convertTo(dataClasses,CV_32FC1);
trainData.convertTo(trainData,CV_32FC1);
knnFlan = new flann::Index( trainData, flann::KDTreeIndexParams(1), cvflann::FLANN_DIST_EUCLIDEAN);
} catch (std::exception& ex)
{
cout << ex.what() << endl;
}
}
vector < vector <int> > ClassifierManager::annotateTheTilesInImages( vector < vector < vector <double> > > featuresPerImageForTiles, int numberOfNearestNeighborToConsider)
{
vector < vector <int> > resultForImagePerTile;
for (int imageIndex = 0; imageIndex < featuresPerImageForTiles.size(); imageIndex++ )
{
vector < vector <double> >featuresPerTile = featuresPerImageForTiles[imageIndex];
vector <int> resultPerTile;
for (int tileIndex = 0; tileIndex < featuresPerTile.size(); tileIndex ++)
{
vector <double> featureForTile = featuresPerTile[tileIndex];
// estimate the response and get the neighbors' labels
cv::Mat results, dists;
Mat featureOfTileInMat(featureForTile);
featureOfTileInMat.convertTo(featureOfTileInMat, CV_32FC1);
featureOfTileInMat = featureOfTileInMat.t();
//int result = classifier->find_nearest(featureOfTileInMat,numberOfNearestNeighborToConsider, &results, 0, &neighborResponses, &dists);
//float percentageOfInstrumentForThisWindow = (float(countNonZero(neighborResponses)) / numberOfNearestNeighborToConsider) * 100;
knnFlan->knnSearch(featureOfTileInMat, results, dists, numberOfNearestNeighborToConsider, flann::SearchParams());
//..... Things to add
}
}
return resultForImagePerTile;
}
的main.m
/*Step 9: Knn Classifier train data */
Mat trainData = VectorUtility <double>::toMat(featuresPerTile);
Mat dataClasses = VectorUtility <int>::toMat(annotationPerTile);
ClassifierManager classifier(trainData, dataClasses, kNearestNeighbor);
/*Step 10: Annotation Step*/
vector < vector <int> > resultsForEachImagePerTile = classifier.annotateTheTilesInImages(trainData, featuresPerImageForTiles, kNearestNeighbor);
问题是,当我尝试annotateTheTilesInImages
main
knnFlan->knnSearch(featureOfTileInMat, results, dists, numberOfNearestNeighborToConsider, flann::SearchParams());
项目崩溃segmentation fault
时,通过投掷class ClassifierManager
{
private:
Mat dataToTrain;
Mat classesData;
int kNearestNeighborToConsider;
CvKNearest *classifier;
cv::flann::Index *knnFlan;
public:
ClassifierManager();
ClassifierManager(Mat &trainData, Mat &dataClasses, int numberOfNearestNeighborToConsider);
vector < vector <int> > annotateTheTilesInImages(Mat trainData, vector < vector < vector <double> > > featuresPerImageForTiles, int numberOfNearestNeighborToConsider);
};
无法通过尝试抓住ClassifierManager::ClassifierManager()
{}
ClassifierManager::ClassifierManager(Mat &trainData, Mat &dataClasses, int numberOfNearestNeighborToConsider)
{
dataToTrain = trainData;
classesData = dataClasses;
kNearestNeighborToConsider = numberOfNearestNeighborToConsider;
try
{
dataToTrain .convertTo(dataToTrain ,CV_32FC1);
knnFlan = new flann::Index( dataToTrain , flann::KDTreeIndexParams(1), cvflann::FLANN_DIST_EUCLIDEAN);
} catch (std::exception& ex)
{
cout << ex.what() << endl;
}
}
....
抓住指示。在我看来,如何管理类中的实例变量存在问题,但不确定它是什么!任何帮助表示赞赏。
@updated 只删除不必要的代码
@Edited:正确的代码:
·H
[1, 0, 0]
的.m
sin(90) = 1
答案 0 :(得分:0)
代码中还有一些问题(例如,我没有看到CvKNearest *classifier
初始化的任何地方),但我认为您的问题是由以下原因引起的:
您通过值将trainData
传递给annotateTheTilesInImages
,而不是引用或常量引用。这意味着此函数中的trainData
是另一个对象(当然具有相同的数据 - OpenCV 支持隐式共享),但对于flann::Index
这可能是一个问题。
编辑:对不起,我的意思是您将值矩阵传递给ClassifierManager
构造函数,而不仅仅是annotateTheTilesInImages
。 I. e。传递给cv::Mat
构造函数的flann::Index
对象在ClassifierManager
构造函数之外不存在(尽管数据仍由其他cv::Mat
对象处理)。