使用CV :: ML :: STATMODEL :: TRAIN使用KNN的OPENCV错误



问题#1:

我正在尝试使用Visual Studio 2017和C 在OpenCV 3.4中实现KNN。到目前为止,我已经能够解决我的问题,但是昨天我遇到了这个错误: "非静态成员参考必须相对于特定对象"

int main(int argc, const char *argv[]) {
ReadData("smokeDataBase.yml", 0);//14 smoke
ReadData("forestDataBase.yml" , 1); //14 forest
ReadData("skyDataBase.yml", 2); //12 sky
ReadData("testDataBase.yml", 3);

Mat trainClasses = (Mat_<float>(40, 1) << 1, 1, 1, 1, 1, 1, 1, 1,1,1, 1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0); //Couldn't figure out how to do this in some other way

//We prepare the data to use in KNN using self-made function that gets every
//vector in my .yml and appends them together
Mat trainData = prepTrain(forestDataBase, skyDataBase, smokeDataBase);

//学习分类器 int k = 10; ptr knn = ml :: nearest :: create((; ML :: Statmodel :: Train(Traindata,ML :: Row_sample,TrainClasses(;//此行给出了错误

}

由于我无法训练KNN(尽管KNN并不是严格的学习方法(,所以我无法使用最肯定的:: FindNeartest来真正从代码中获得我想要的东西。我找不到任何适合我的问题的答案,因此我正在写这个。

我删除了代码的每个部分,这些部分未使用,以使你们更容易帮助我。

问题#2:

当我创建可变的Traindata时,我将所有数据放在烟雾/森林/SkyDatabase上。换句话说,我将所有数据附加到一个单一的大量向量中。这是正确的方法吗?我应该分为一个"向量traindata"变量,其中每个traindata [i](i从0到traindata.size(是代表我数据示例的矢量吗?

这是您的第一个问题:这是官方文档中删除功能列车的签名

virtual bool cv::ml::StatModel::train   (   InputArray      samples,
        int     layout,
        InputArray      responses 
    )   

您可以看到,该方法是虚拟的,意思是您无法以这种方式调用它!。该功能应由STATMODEL的子类实施。因此,当您想使用该方法时,您可以从实现此方法的子类中调用该方法。班级最能实现这一点。您的代码应更改为:

Ptr<ml::KNearest> knn = ml::KNearest::create();  
knn->train(trainData, ml::ROW_SAMPLE , trainClasses);

现在是您的第二个问题:

您可以作为row_sample或col_sample准备数据。在row_sample中,每个样品中的每个样本都在一行中。因此,如果您的样本由三个浮子组成,并且您有10个样品,则应最终得到一个具有10行和3列的垫子对象。在col_sample中,一切都倒了。因此,您最终有3行和10列。