The relevant code is in tree.cpp.
When using int
labels, this line will cause the crash:
float DTreesImpl::predictTrees( const Range& range, const Mat& sample, int flags ) const
{
...
if( predictType == PREDICT_MAX_VOTE ) {
...
sum = (flags & RAW_OUTPUT) ? (float)best_idx : classLabels[best_idx]; // Line 1487
...
}
}
bacause classLabels
is empty (even if it's present in the xml file).
When using float
labels, this line won't be executed, since predictType
would be PREDICT_SUM
instead of PREDICT_MAX_VOTE
. (The relevant code is in the same function).
The cause for this is that the file is not loaded correctly (this may be a bug). In fact, when reading the file there is this check
void DTreesImpl::readParams( const FileNode& fn )
{
...
int format = 0; // line 1720
fn["format"] >> format;
bool isLegacy = format < 3;
...
if (isLegacy) { ... }
else
{
...
fn["class_labels"] >> classLabels;
}
}
but when writing the file, the field "format" is not there. So, you are in fact reading the file in the wrong format, because you enter the isLegacy
part.
A workaround for this, is to save the file as:
...
std::vector<int> labels;
...
rtrees->write(cv::FileStorage("smoke_classifier.xml", cv::FileStorage::WRITE));
// Add this
{
cv::FileStorage fs("smoke_classifier.xml", cv::FileStorage::APPEND);
fs << "format" << 3; // So "isLegacy" return false;
}
cv::FileStorage read("smoke_classifier.xml",
cv::FileStorage::READ);
auto rtrees2 = cv::ml::RTrees::create();
rtrees2->read(read.root());
Doing so, the file will be loaded correctly, and the program won't crash.
Since I'm not able to reproduce your other problem in calcDir
, let me know if this works.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…