mirror of
https://github.com/opencv/opencv.git
synced 2026-09-15 07:29:07 -05:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
@@ -490,6 +490,7 @@ public:
|
||||
|
||||
float predict( InputArray samples, OutputArray results, int flags ) const CV_OVERRIDE
|
||||
{
|
||||
CV_CheckEQ(samples.cols(), getVarCount(), "");
|
||||
return impl.predict(samples, results, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -480,6 +480,7 @@ public:
|
||||
float predict( InputArray samples, OutputArray results, int flags ) const CV_OVERRIDE
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
CV_CheckEQ(samples.cols(), getVarCount(), "");
|
||||
return impl.predict(samples, results, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
#include "precomp.hpp"
|
||||
#include <ctype.h>
|
||||
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace ml {
|
||||
|
||||
@@ -1694,11 +1696,14 @@ void DTreesImpl::write( FileStorage& fs ) const
|
||||
void DTreesImpl::readParams( const FileNode& fn )
|
||||
{
|
||||
_isClassifier = (int)fn["is_classifier"] != 0;
|
||||
/*int var_all = (int)fn["var_all"];
|
||||
int var_count = (int)fn["var_count"];
|
||||
int cat_var_count = (int)fn["cat_var_count"];
|
||||
int varAll = (int)fn["var_all"];
|
||||
int varCount = (int)fn["var_count"];
|
||||
/*int cat_var_count = (int)fn["cat_var_count"];
|
||||
int ord_var_count = (int)fn["ord_var_count"];*/
|
||||
|
||||
if (varAll <= 0)
|
||||
CV_Error(Error::StsParseError, "The field \"var_all\" of DTree classifier is missing or non-positive");
|
||||
|
||||
FileNode tparams_node = fn["training_params"];
|
||||
|
||||
TreeParams params0 = TreeParams();
|
||||
@@ -1723,11 +1728,38 @@ void DTreesImpl::readParams( const FileNode& fn )
|
||||
readVectorOrMat(fn["var_idx"], varIdx);
|
||||
fn["var_type"] >> varType;
|
||||
|
||||
int format = 0;
|
||||
fn["format"] >> format;
|
||||
bool isLegacy = format < 3;
|
||||
bool isLegacy = false;
|
||||
if (fn["format"].empty()) // Export bug until OpenCV 3.2: https://github.com/opencv/opencv/pull/6314
|
||||
{
|
||||
if (!fn["cat_ofs"].empty())
|
||||
isLegacy = false; // 2.4 doesn't store "cat_ofs"
|
||||
else if (!fn["missing_subst"].empty())
|
||||
isLegacy = false; // 2.4 doesn't store "missing_subst"
|
||||
else if (!fn["class_labels"].empty())
|
||||
isLegacy = false; // 2.4 doesn't store "class_labels"
|
||||
else if ((int)varType.size() != varAll)
|
||||
isLegacy = true; // 3.0+: https://github.com/opencv/opencv/blame/3.0.0/modules/ml/src/tree.cpp#L1576
|
||||
else if (/*(int)varType.size() == varAll &&*/ varCount == varAll)
|
||||
isLegacy = true;
|
||||
else
|
||||
{
|
||||
// 3.0+:
|
||||
// - https://github.com/opencv/opencv/blame/3.0.0/modules/ml/src/tree.cpp#L1552-L1553
|
||||
// - https://github.com/opencv/opencv/blame/3.0.0/modules/ml/src/precomp.hpp#L296
|
||||
isLegacy = !(varCount + 1 == varAll);
|
||||
}
|
||||
CV_LOG_INFO(NULL, "ML/DTrees: possible missing 'format' field due to bug of OpenCV export implementation. "
|
||||
"Details: https://github.com/opencv/opencv/issues/5412. Consider re-exporting of saved ML model. "
|
||||
"isLegacy = " << isLegacy);
|
||||
}
|
||||
else
|
||||
{
|
||||
int format = 0;
|
||||
fn["format"] >> format;
|
||||
CV_CheckGT(format, 0, "");
|
||||
isLegacy = format < 3;
|
||||
}
|
||||
|
||||
int varAll = (int)fn["var_all"];
|
||||
if (isLegacy && (int)varType.size() <= varAll)
|
||||
{
|
||||
std::vector<uchar> extendedTypes(varAll + 1, 0);
|
||||
|
||||
@@ -95,6 +95,25 @@ TEST(ML_RTrees, 11142_sample_weights_classification)
|
||||
EXPECT_GE(error_with_weights, error_without_weights);
|
||||
}
|
||||
|
||||
TEST(ML_RTrees, bug_12974_throw_exception_when_predict_different_feature_count)
|
||||
{
|
||||
int numFeatures = 5;
|
||||
// create a 5 feature dataset and train the model
|
||||
cv::Ptr<RTrees> model = RTrees::create();
|
||||
Mat samples(10, numFeatures, CV_32F);
|
||||
randu(samples, 0, 10);
|
||||
Mat labels = (Mat_<int>(10,1) << 0,0,0,0,0,1,1,1,1,1);
|
||||
cv::Ptr<TrainData> trainData = TrainData::create(samples, cv::ml::ROW_SAMPLE, labels);
|
||||
model->train(trainData);
|
||||
// try to predict on data which have fewer features - this should throw an exception
|
||||
for(int i = 1; i < numFeatures - 1; ++i) {
|
||||
Mat test(1, i, CV_32FC1);
|
||||
ASSERT_THROW(model->predict(test), Exception);
|
||||
}
|
||||
// try to predict on data which have more features - this should also throw an exception
|
||||
Mat test(1, numFeatures + 1, CV_32FC1);
|
||||
ASSERT_THROW(model->predict(test), Exception);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace
|
||||
|
||||
Reference in New Issue
Block a user