Commit 16039af1b0aa1394033257f41f96e867102e98d0

Authored by Charles Otto
1 parent f7368019

Preliminary API changes towards reducing special casing of subject/label

Remove subject/label methods from the API, replace some methods with general
methods taking a property name as an argument.

This breaks quite a few things
app/examples/age_estimation.cpp
... ... @@ -29,7 +29,7 @@
29 29  
30 30 static void printTemplate(const br::Template &t)
31 31 {
32   - printf("%s age: %d\n", qPrintable(t.file.fileName()), int(t.file.label()));
  32 + printf("%s age: %d\n", qPrintable(t.file.fileName()), int(t.file.get<float>("Label")));
33 33 }
34 34  
35 35 int main(int argc, char *argv[])
... ...
app/examples/gender_estimation.cpp
... ... @@ -29,7 +29,7 @@
29 29  
30 30 static void printTemplate(const br::Template &t)
31 31 {
32   - printf("%s gender: %s\n", qPrintable(t.file.fileName()), t.file.label() == 1 ? "Female" : "Male");
  32 + printf("%s gender: %s\n", qPrintable(t.file.fileName()), qPrintable(t.file.get<QString>("Subject")));
33 33 }
34 34  
35 35 int main(int argc, char *argv[])
... ...
openbr/core/bee.cpp
... ... @@ -96,7 +96,7 @@ void BEE::writeSigset(const QString &amp;sigset, const br::FileList &amp;files, bool ign
96 96 if ((key == "Index") || (key == "Subject")) continue;
97 97 metadata.append(key+"=\""+QtUtils::toString(file.value(key))+"\"");
98 98 }
99   - lines.append("\t<biometric-signature name=\"" + file.subject() +"\">");
  99 + lines.append("\t<biometric-signature name=\"" + file.get<QString>("Subject") +"\">");
100 100 lines.append("\t\t<presentation file-name=\"" + file.name + "\" " + metadata.join(" ") + "/>");
101 101 lines.append("\t</biometric-signature>");
102 102 }
... ... @@ -260,8 +260,8 @@ void BEE::makeMask(const QString &amp;targetInput, const QString &amp;queryInput, const
260 260  
261 261 cv::Mat BEE::makeMask(const br::FileList &targets, const br::FileList &queries, int partition)
262 262 {
263   - QList<float> targetLabels = targets.labels();
264   - QList<float> queryLabels = queries.labels();
  263 + QList<float> targetLabels = targets.collectValues<float>("Label");
  264 + QList<float> queryLabels = queries.collectValues<float>("Label");
265 265 QList<int> targetPartitions = targets.crossValidationPartitions();
266 266 QList<int> queryPartitions = queries.crossValidationPartitions();
267 267  
... ...
openbr/core/classify.cpp
... ... @@ -45,8 +45,8 @@ void br::EvalClassification(const QString &amp;predictedInput, const QString &amp;truthI
45 45 qFatal("Input order mismatch.");
46 46  
47 47 // Typically these lists will be of length one, but this generalization allows measuring multi-class labeling accuracy.
48   - QString predictedSubject = predicted[i].file.subject();
49   - QString trueSubject = truth[i].file.subject();
  48 + QString predictedSubject = predicted[i].file.get<QString>("Subject");
  49 + QString trueSubject = truth[i].file.get<QString>("Subject");
50 50  
51 51 QStringList predictedSubjects(predictedSubject);
52 52 QStringList trueSubjects(trueSubject);
... ... @@ -80,7 +80,8 @@ void br::EvalClassification(const QString &amp;predictedInput, const QString &amp;truthI
80 80 const float precision = counter.truePositive / (float)(counter.truePositive + counter.falsePositive);
81 81 const float recall = counter.truePositive / (float)(counter.truePositive + counter.falseNegative);
82 82 const float fscore = 2 * precision * recall / (precision + recall);
83   - output->setRelative(File("", subject).label(), i, 0);
  83 + // problem -cao
  84 + output->setRelative(File("", subject).get<int>("Label"), i, 0);
84 85 output->setRelative(count, i, 1);
85 86 output->setRelative(precision, i, 2);
86 87 output->setRelative(recall, i, 3);
... ... @@ -103,9 +104,9 @@ void br::EvalRegression(const QString &amp;predictedInput, const QString &amp;truthInput
103 104 for (int i=0; i<predicted.size(); i++) {
104 105 if (predicted[i].file.name != truth[i].file.name)
105 106 qFatal("Input order mismatch.");
106   - rmsError += pow(predicted[i].file.label()-truth[i].file.label(), 2.f);
107   - truthValues.append(QString::number(truth[i].file.label()));
108   - predictedValues.append(QString::number(predicted[i].file.label()));
  107 + rmsError += pow(predicted[i].file.get<float>("Label")-truth[i].file.get<float>("Label"), 2.f);
  108 + truthValues.append(QString::number(truth[i].file.get<float>("Label")));
  109 + predictedValues.append(QString::number(predicted[i].file.get<float>("Label")));
109 110 }
110 111  
111 112 QStringList rSource;
... ...
openbr/core/cluster.cpp
... ... @@ -278,7 +278,7 @@ void br::EvalClustering(const QString &amp;csv, const QString &amp;input)
278 278 {
279 279 qDebug("Evaluating %s against %s", qPrintable(csv), qPrintable(input));
280 280  
281   - QList<float> labels = TemplateList::fromGallery(input).files().labels();
  281 + QList<float> labels = TemplateList::fromGallery(input).files().collectValues<float>("Label");
282 282  
283 283 QHash<int, int> labelToIndex;
284 284 int nClusters = 0;
... ...
openbr/frvt2012.cpp
... ... @@ -132,7 +132,7 @@ int32_t SdkEstimator::estimate_age(const ONEFACE &amp;input_face, int32_t &amp;age)
132 132 TemplateList templates;
133 133 templates.append(templateFromONEFACE(input_face));
134 134 templates >> *frvt2012_age_transform.data();
135   - age = templates.first().file.label();
  135 + age = templates.first().file.get<float>("Label");
136 136 return templates.first().file.failed() ? 4 : 0;
137 137 }
138 138  
... ... @@ -141,6 +141,6 @@ int32_t SdkEstimator::estimate_gender(const ONEFACE &amp;input_face, int8_t &amp;gender,
141 141 TemplateList templates;
142 142 templates.append(templateFromONEFACE(input_face));
143 143 templates >> *frvt2012_gender_transform.data();
144   - mf = gender = templates.first().file.label();
  144 + mf = gender = templates.first().file.get<float>("Label");
145 145 return templates.first().file.failed() ? 4 : 0;
146 146 }
... ...
openbr/gui/classifier.cpp
... ... @@ -42,15 +42,16 @@ void Classifier::_classify(File file)
42 42 if (!f.contains("Label"))
43 43 continue;
44 44  
  45 + // What's with the special casing -cao
45 46 if (algorithm == "GenderClassification") {
46 47 key = "Gender";
47   - value = (f.label() == 0 ? "Male" : "Female");
  48 + value = (f.get<QString>("Subject"));
48 49 } else if (algorithm == "AgeRegression") {
49 50 key = "Age";
50   - value = QString::number(int(f.label()+0.5)) + " Years";
  51 + value = QString::number(int(f.get<float>("Label")+0.5)) + " Years";
51 52 } else {
52 53 key = algorithm;
53   - value = QString::number(f.label());
  54 + value = QString::number(f.get<float>("Label"));
54 55 }
55 56 break;
56 57 }
... ...
openbr/openbr_plugin.cpp
... ... @@ -167,34 +167,6 @@ bool File::getBool(const QString &amp;key, bool defaultValue) const
167 167 return variant.value<bool>();
168 168 }
169 169  
170   -QString File::subject() const
171   -{
172   - const QVariant l = m_metadata.value("Label");
173   - if (!l.isNull()) return Globals->subjects.key(l.toFloat(), l.toString());
174   - return m_metadata.value("Subject").toString();
175   -}
176   -
177   -float File::label() const
178   -{
179   - const QVariant l = m_metadata.value("Label");
180   - if (!l.isNull()) return l.toFloat();
181   -
182   - const QVariant s = m_metadata.value("Subject");
183   - if (s.isNull()) return -1;
184   -
185   - const QString subject = s.toString();
186   -
187   - bool is_num = false;
188   - float num = subject.toFloat(&is_num);
189   - if (is_num) return num;
190   -
191   - static QMutex mutex;
192   - QMutexLocker mutexLocker(&mutex);
193   - if (!Globals->subjects.contains(subject))
194   - Globals->subjects.insert(subject, Globals->subjects.size());
195   - return Globals->subjects.value(subject);
196   -}
197   -
198 170 QList<QPointF> File::namedPoints() const
199 171 {
200 172 QList<QPointF> landmarks;
... ... @@ -360,14 +332,6 @@ void FileList::sort(const QString&amp; key)
360 332 *this = sortedList;
361 333 }
362 334  
363   -QList<float> FileList::labels() const
364   -{
365   - QList<float> labels; labels.reserve(size());
366   - foreach (const File &f, *this)
367   - labels.append(f.label());
368   - return labels;
369   -}
370   -
371 335 QList<int> FileList::crossValidationPartitions() const
372 336 {
373 337 QList<int> crossValidationPartitions; crossValidationPartitions.reserve(size());
... ... @@ -451,7 +415,7 @@ TemplateList TemplateList::fromGallery(const br::File &amp;gallery)
451 415  
452 416 newTemplates[i].file.set("Partition", -1);
453 417 } else {
454   - const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.subject().toLatin1(), QCryptographicHash::Md5);
  418 + const QByteArray md5 = QCryptographicHash::hash(newTemplates[i].file.get<QString>("Subject").toLatin1(), QCryptographicHash::Md5);
455 419 // Select the right 8 hex characters so that it can be represented as a 64 bit integer without overflow
456 420 newTemplates[i].file.set("Partition", md5.toHex().right(8).toULongLong(0, 16) % crossValidate);
457 421 }
... ... @@ -471,9 +435,9 @@ TemplateList TemplateList::fromGallery(const br::File &amp;gallery)
471 435 return templates;
472 436 }
473 437  
474   -TemplateList TemplateList::relabel(const TemplateList &tl)
  438 +TemplateList TemplateList::relabel(const TemplateList &tl, const QString & propName)
475 439 {
476   - const QList<int> originalLabels = tl.labels<int>();
  440 + const QList<int> originalLabels = tl.collectValues<int>(propName);
477 441 QHash<int,int> labelTable;
478 442 foreach (int label, originalLabels)
479 443 if (!labelTable.contains(label))
... ...
openbr/openbr_plugin.h
... ... @@ -254,8 +254,6 @@ struct BR_EXPORT File
254 254 return variant.value<T>();
255 255 }
256 256  
257   - QString subject() const; /*!< \brief Looks up the subject from the file's label. */
258   - float label() const; /*!< \brief Convenience function for retrieving the file's \c Label. */
259 257 inline bool failed() const { return getBool("FTE") || getBool("FTO"); } /*!< \brief Returns \c true if the file failed to open or enroll, \c false otherwise. */
260 258  
261 259 QList<QPointF> namedPoints() const; /*!< \brief Returns points convertible from metadata keys. */
... ... @@ -299,7 +297,15 @@ struct BR_EXPORT FileList : public QList&lt;File&gt;
299 297 QStringList flat() const; /*!< \brief Returns br::File::flat() for each file in the list. */
300 298 QStringList names() const; /*!< \brief Returns #br::File::name for each file in the list. */
301 299 void sort(const QString& key); /*!< \brief Sort the list based on metadata. */
302   - QList<float> labels() const; /*!< \brief Returns br::File::label() for each file in the list. */
  300 + /*!< \brief Returns br::File::label() for each file in the list. */
  301 + template<typename T>
  302 + QList<T> collectValues(const QString & propName) const
  303 + {
  304 + QList<T> values; values.reserve(size());
  305 + foreach (const File &f, *this)
  306 + values.append(f.get<T>(propName));
  307 + return values;
  308 + }
303 309 QList<int> crossValidationPartitions() const; /*!< \brief Returns the cross-validation partition (default=0) for each file in the list. */
304 310 int failures() const; /*!< \brief Returns the number of files with br::File::failed(). */
305 311 };
... ... @@ -383,7 +389,9 @@ struct TemplateList : public QList&lt;Template&gt;
383 389 TemplateList(const QList<Template> &templates) : uniform(false) { append(templates); } /*!< \brief Initialize the template list from another template list. */
384 390 TemplateList(const QList<File> &files) : uniform(false) { foreach (const File &file, files) append(file); } /*!< \brief Initialize the template list from a file list. */
385 391 BR_EXPORT static TemplateList fromGallery(const File &gallery); /*!< \brief Create a template list from a br::Gallery. */
386   - BR_EXPORT static TemplateList relabel(const TemplateList &tl); /*!< \brief Ensure labels are in the range [0,numClasses-1]. */
  392 +
  393 + /*!< \brief Ensure labels are in the range [0,numClasses-1]. */
  394 + BR_EXPORT static TemplateList relabel(const TemplateList & tl, const QString & propName);
387 395  
388 396 /*!
389 397 * \brief Returns the total number of bytes in all the templates.
... ... @@ -457,23 +465,24 @@ struct TemplateList : public QList&lt;Template&gt;
457 465 /*!
458 466 * \brief Returns br::Template::label() for each template in the list.
459 467 */
460   - template <typename T>
461   - QList<T> labels() const
  468 + template<typename T>
  469 + QList<T> collectValues(const QString & propName) const
462 470 {
463   - QList<T> labels; labels.reserve(size());
464   - foreach (const Template &t, *this) labels.append(t.file.label());
465   - return labels;
  471 + QList<T> values; values.reserve(size());
  472 + foreach (const Template &t, *this) values.append(t.file.get<T>(propName));
  473 + return values;
466 474 }
467 475  
468 476 /*!
469 477 * \brief Returns the number of occurences for each label in the list.
470 478 */
471   - QMap<int,int> labelCounts(bool excludeFailures = false) const
  479 + template<typename T>
  480 + QMap<T,int> countValues(const QString & propName, bool excludeFailures = false) const
472 481 {
473   - QMap<int, int> labelCounts;
  482 + QMap<T, int> labelCounts;
474 483 foreach (const File &file, files())
475 484 if (!excludeFailures || !file.failed())
476   - labelCounts[file.label()]++;
  485 + labelCounts[file.get<T>(propName)]++;
477 486 return labelCounts;
478 487 }
479 488  
... ...
openbr/plugins/cluster.cpp
... ... @@ -111,13 +111,13 @@ class KNNTransform : public Transform
111 111 QHash<QString, float> votes;
112 112 const int max = (k < 1) ? sortedScores.size() : std::min(k, sortedScores.size());
113 113 for (int j=0; j<max; j++)
114   - votes[gallery[sortedScores[j].second].file.subject()] += (weighted ? sortedScores[j].first : 1);
  114 + votes[gallery[sortedScores[j].second].file.get<QString>("Subject")] += (weighted ? sortedScores[j].first : 1);
115 115 subjects.append(votes.keys()[votes.values().indexOf(Common::Max(votes.values()))]);
116 116  
117 117 // Remove subject from consideration
118 118 if (subjects.size() < numSubjects)
119 119 for (int j=sortedScores.size()-1; j>=0; j--)
120   - if (gallery[sortedScores[j].second].file.subject() == subjects.last())
  120 + if (gallery[sortedScores[j].second].file.get<QString>("Subject") == subjects.last())
121 121 sortedScores.removeAt(j);
122 122 }
123 123  
... ...
openbr/plugins/eigen3.cpp
... ... @@ -329,7 +329,7 @@ class LDATransform : public Transform
329 329  
330 330 void train(const TemplateList &_trainingSet)
331 331 {
332   - TemplateList trainingSet = TemplateList::relabel(_trainingSet);
  332 + TemplateList trainingSet = TemplateList::relabel(_trainingSet, "Label");
333 333  
334 334 int instances = trainingSet.size();
335 335  
... ... @@ -342,13 +342,14 @@ class LDATransform : public Transform
342 342  
343 343 TemplateList ldaTrainingSet;
344 344 static_cast<Transform*>(&pca)->project(trainingSet, ldaTrainingSet);
345   - ldaTrainingSet = TemplateList::relabel(ldaTrainingSet);
  345 + ldaTrainingSet = TemplateList::relabel(ldaTrainingSet, "Label");
346 346  
347 347 int dimsIn = ldaTrainingSet.first().m().rows * ldaTrainingSet.first().m().cols;
348 348  
349 349 // OpenBR ensures that class values range from 0 to numClasses-1.
350   - QList<int> classes = trainingSet.labels<int>();
351   - QMap<int, int> classCounts = trainingSet.labelCounts();
  350 + // Assumed label is stored as float or int? -cao
  351 + QList<int> classes = trainingSet.collectValues<int>("Label");
  352 + QMap<int, int> classCounts = trainingSet.countValues<int>("Label");
352 353 const int numClasses = classCounts.size();
353 354  
354 355 // Map Eigen into OpenCV
... ...
openbr/plugins/gallery.cpp
... ... @@ -71,7 +71,7 @@ class arffGallery : public Gallery
71 71 }
72 72  
73 73 arffFile.write(qPrintable(OpenCVUtils::matrixToStringList(t).join(',')));
74   - arffFile.write(qPrintable(",'" + t.file.subject() + "'\n"));
  74 + arffFile.write(qPrintable(",'" + t.file.get<QString>("Subject") + "'\n"));
75 75 }
76 76 };
77 77  
... ... @@ -878,7 +878,7 @@ class statGallery : public Gallery
878 878  
879 879 void write(const Template &t)
880 880 {
881   - subjects.insert(t.file.subject());
  881 + subjects.insert(t.file.get<QString>("Subject"));
882 882 bytes.append(t.bytes());
883 883 }
884 884 };
... ...
openbr/plugins/independent.cpp
... ... @@ -20,11 +20,11 @@ static TemplateList Downsample(const TemplateList &amp;templates, const Transform *t
20 20 const bool atLeast = transform->instances < 0;
21 21 const int instances = abs(transform->instances);
22 22  
23   - QList<int> allLabels = templates.labels<int>();
  23 + QList<int> allLabels = templates.collectValues<int>("Label");
24 24 QList<int> uniqueLabels = allLabels.toSet().toList();
25 25 qSort(uniqueLabels);
26 26  
27   - QMap<int,int> counts = templates.labelCounts(instances != std::numeric_limits<int>::max());
  27 + QMap<int,int> counts = templates.countValues<int>("Label", instances != std::numeric_limits<int>::max());
28 28 if ((instances != std::numeric_limits<int>::max()) && (transform->classes != std::numeric_limits<int>::max()))
29 29 foreach (int label, counts.keys())
30 30 if (counts[label] < instances)
... ...
openbr/plugins/meta.cpp
... ... @@ -453,7 +453,7 @@ private:
453 453 const QString &file = src.file;
454 454 if (cache.contains(file)) {
455 455 dst = cache[file];
456   - dst.file.set("Label", src.file.label());
  456 + dst.file.set("Label", src.file.value("Label"));
457 457 } else {
458 458 transform->project(src, dst);
459 459 cacheLock.lock();
... ...
openbr/plugins/normalize.cpp
... ... @@ -126,7 +126,7 @@ private:
126 126 {
127 127 Mat m;
128 128 OpenCVUtils::toMat(data.data()).convertTo(m, CV_64F);
129   - const QList<int> labels = data.labels<int>();
  129 + const QList<int> labels = data.collectValues<int>("Label");
130 130 const int dims = m.cols;
131 131  
132 132 vector<Mat> mv, av, bv;
... ...
openbr/plugins/output.cpp
... ... @@ -153,8 +153,8 @@ class meltOutput : public MatrixOutput
153 153  
154 154 QStringList lines;
155 155 if (file.baseName() != "terminal") lines.append(QString("Query,Target,Mask,Similarity%1").arg(keys));
156   - QList<float> queryLabels = queryFiles.labels();
157   - QList<float> targetLabels = targetFiles.labels();
  156 + QList<float> queryLabels = queryFiles.collectValues<float>("Label");
  157 + QList<float> targetLabels = targetFiles.collectValues<float>("Label");
158 158 for (int i=0; i<queryFiles.size(); i++) {
159 159 for (int j=(selfSimilar ? i+1 : 0); j<targetFiles.size(); j++) {
160 160 const bool genuine = queryLabels[i] == targetLabels[j];
... ... @@ -304,7 +304,7 @@ class txtOutput : public MatrixOutput
304 304 if (file.isNull() || targetFiles.isEmpty() || queryFiles.isEmpty()) return;
305 305 QStringList lines;
306 306 foreach (const File &file, queryFiles)
307   - lines.append(file.name + " " + file.subject());
  307 + lines.append(file.name + " " + file.get<QString>("Subject"));
308 308 QtUtils::writeFile(file, lines);
309 309 }
310 310 };
... ...
openbr/plugins/pixel.cpp
... ... @@ -166,7 +166,7 @@ class PerPixelClassifierTransform : public MetaTransform
166 166 }
167 167  
168 168 transform->project(temp,dstTemp);
169   - pdst[r*cols+c] = dstTemp.file.label();
  169 + pdst[r*cols + c] = dstTemp.file.get<float>("Label");
170 170 }
171 171 }
172 172 }
... ...
openbr/plugins/quality.cpp
... ... @@ -26,10 +26,10 @@ class ImpostorUniquenessMeasureTransform : public Transform
26 26  
27 27 float calculateIUM(const Template &probe, const TemplateList &gallery) const
28 28 {
29   - const int probeLabel = probe.file.label();
  29 + const int probeLabel = probe.file.get<float>("Label");
30 30 TemplateList subset = gallery;
31 31 for (int j=subset.size()-1; j>=0; j--)
32   - if (subset[j].file.label() == probeLabel)
  32 + if (subset[j].file.get<int>("Label") == probeLabel)
33 33 subset.removeAt(j);
34 34  
35 35 QList<float> scores = distance->compare(subset, probe);
... ... @@ -159,7 +159,7 @@ class MatchProbabilityDistance : public Distance
159 159 {
160 160 distance->train(src);
161 161  
162   - const QList<int> labels = src.labels<int>();
  162 + const QList<int> labels = src.collectValues<int>("Label");
163 163 QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(src.size()), FileList(src.size())));
164 164 distance->compare(src, src, matrixOutput.data());
165 165  
... ... @@ -219,7 +219,7 @@ class UnitDistance : public Distance
219 219 void train(const TemplateList &templates)
220 220 {
221 221 const TemplateList samples = templates.mid(0, 2000);
222   - const QList<float> sampleLabels = samples.labels<float>();
  222 + const QList<float> sampleLabels = samples.collectValues<float>("Label");
223 223 QScopedPointer<MatrixOutput> matrixOutput(MatrixOutput::make(FileList(samples.size()), FileList(samples.size())));
224 224 Distance::compare(samples, samples, matrixOutput.data());
225 225  
... ...
openbr/plugins/quantize.cpp
... ... @@ -150,7 +150,7 @@ class BayesianQuantizationDistance : public Distance
150 150 qFatal("Expected sigle matrix templates of type CV_8UC1!");
151 151  
152 152 const Mat data = OpenCVUtils::toMat(src.data());
153   - const QList<int> templateLabels = src.labels<int>();
  153 + const QList<int> templateLabels = src.collectValues<int>("Label");
154 154 loglikelihoods = QVector<float>(data.cols*256, 0);
155 155  
156 156 QFutureSynchronizer<void> futures;
... ... @@ -473,7 +473,7 @@ private:
473 473 {
474 474 Mat data = OpenCVUtils::toMat(src.data());
475 475 const int step = getStep(data.cols);
476   - const QList<int> labels = src.labels<int>();
  476 + const QList<int> labels = src.collectValues<int>("Label");
477 477  
478 478 Mat &lut = ProductQuantizationLUTs[index];
479 479 lut = Mat(getDims(data.cols), 256*(256+1)/2, CV_32FC1);
... ...
openbr/plugins/quantize2.cpp
... ... @@ -77,7 +77,7 @@ class BayesianQuantizationTransform : public Transform
77 77 void train(const TemplateList &src)
78 78 {
79 79 const Mat data = OpenCVUtils::toMat(src.data());
80   - const QList<int> labels = src.labels<int>();
  80 + const QList<int> labels = src.collectValues<int>("Label");
81 81  
82 82 thresholds = QVector<float>(256*data.cols);
83 83  
... ...
openbr/plugins/svm.cpp
... ... @@ -125,7 +125,7 @@ private:
125 125 void train(const TemplateList &_data)
126 126 {
127 127 Mat data = OpenCVUtils::toMat(_data.data());
128   - Mat lab = OpenCVUtils::toMat(_data.labels<float>());
  128 + Mat lab = OpenCVUtils::toMat(_data.collectValues<float>("Label"));
129 129 trainSVM(svm, data, lab, kernel, type, C, gamma);
130 130 }
131 131  
... ... @@ -182,7 +182,7 @@ private:
182 182 void train(const TemplateList &src)
183 183 {
184 184 const Mat data = OpenCVUtils::toMat(src.data());
185   - const QList<int> lab = src.labels<int>();
  185 + const QList<int> lab = src.collectValues<int>("Label");
186 186  
187 187 const int instances = data.rows * (data.rows+1) / 2;
188 188 Mat deltaData(instances, data.cols, data.type());
... ...