【问题标题】:OpenCV Error: Assertion failed (samples.cols == var_count && samples.type() == CV_32F) in predictOpenCV 错误:预测中的断言失败 (samples.cols == var_count && samples.type() == CV_32F)
【发布时间】:2017-07-09 21:48:58
【问题描述】:

我正在尝试在 cocos2d-x 游戏中使用 OpenCV SVM 分类器。这是一个简单的测试函数:

void HelloWorld::testOpenCV(){
    // Load SVM classifier
    auto classifierPath = FileUtils::getInstance()->fullPathForFilename("classifier.yml");
    cv::Ptr<cv::ml::SVM> svm = cv::ml::StatModel::load<cv::ml::SVM>(classifierPath);

    string filename = "test.jpg";

    auto img = new Image();
    img->initWithImageFile(filename);

    int imageSize = (int)img->getDataLen();
    int imageXW = img->getWidth();
    int imageYW = img->getHeight();
    unsigned char * srcData = img->getData();

    CCLOG("imageXW=%d, imageYW=%d", imageXW, imageYW);
    int ch = imageSize/(imageXW*imageYW);
    CCLOG("image=%dch raw data...", ch);

    cv::Mat testMat = createCvMatFromRaw(srcData, imageXW, imageYW, ch);
    testMat.convertTo(testMat, CV_32F);

    // try to predict which number has been drawn
    try{
        int predicted = svm->predict(testMat);

        CCLOG("Recognizing following number -> %d", predicted);

    }catch(cv::Exception ex){

    }
}

它给出了一个输出:

imageXW=28, imageYW=28
image=3ch raw data...
OpenCV Error: Assertion failed (samples.cols == var_count && samples.type() == CV_32F) in predict, file /Volumes/build-storage/build/master_iOS-mac/opencv/modules/ml/src/svm.cpp, line 1930

它基于本教程:

https://www.simplicity.be/article/recognizing-handwritten-digits/

尤其是这种方法:

// Standard library
#include <iostream>
#include <vector>
#include <string>

// OpenCV
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>

// POSIX
#include <unistd.h>

/**
 * main
 **/ 
int main( int argc, char** argv )
{

    //
    // Load SVM classifier 
    cv::Ptr<cv::ml::SVM> svm = cv::ml::StatModel::load<cv::ml::SVM>("classifier.yml");


    // read image file (grayscale)
    cv::Mat imgMat = cv::imread("test.jpg", 0);

    // convert 2d to 1d 
    cv::Mat testMat = imgMat.clone().reshape(1,1);
    testMat.convertTo(testMat, CV_32F);

    // try to predict which number has been drawn
    try{
        int predicted = svm->predict(testMat);

        std::cout << std::endl  << "Recognizing following number -> " << predicted << std::endl << std::endl;

        std::string notifyCmd = "notify-send -t 1000 Recognized: " + std::to_string(predicted);
        system(notifyCmd.c_str());

    }catch(cv::Exception ex){

    }

}

我已经在终端中运行它并且它工作正常。

这里是 createCvMatFromRaw 的一个实现:

cv::Mat HelloWorld::createCvMatFromRaw(unsigned char *rawData, int rawXW, int rawYW, int ch)
{
    cv::Mat cvMat( rawYW, rawXW, CV_8UC4); // 8 bits per component, 4 channels

    for (int py=0; py<rawYW; py++) {
        for (int px=0; px<rawXW; px++) {
            int nBasePos = ((rawXW * py)+px) * ch;
            cvMat.at<cv::Vec4b>(py, px) = cv::Vec4b(rawData[nBasePos + 0],
                                                    rawData[nBasePos + 1],
                                                    rawData[nBasePos + 2],
                                                    0xFF);

        }
    }

    return cvMat;
}

我在这里找到了:

http://blog.szmake.net/archives/845

这个断言是什么意思?有人可以向我解释吗?我该如何解决这个问题?

【问题讨论】:

    标签: c++ opencv cocos2d-x svm


    【解决方案1】:

    断言说

    OpenCV Error: Assertion failed (samples.cols == var_count &amp;&amp; samples.type() == CV_32F)

    这意味着样本要么没有正确的列数,要么没有类型CV_32F

    您似乎忘记了reshape 函数,因此您的数据违反了第一个条件。我认为为了应用svm,数据需要是一个向量,即1 x n矩阵。

    【讨论】:

    • cv::Mat testMat2 = testMat.clone().reshape(1, 1); - 我试过了,结果是一样的。
    • 我什至试过:cv::cvtColor(testMat, grayMat, cv::COLOR_BGR2GRAY);
    • 好的,它与 imread 一起工作!问题是我需要使用 cocos2d-x 数据数组的转换,它会动态变化,保存/读取对性能不利。
    • 我听不懂你的createCvMatFromRaw。看起来它返回一个带有 alpha=255 的 4 通道 Mat,而 ch=3 因为您正在使用 jpeg 图像。这就是cvtColor 不起作用的原因,reshape 也不起作用:数据大小不匹配。应该是cvtColor(testMat, greyMat, cv::COLOR_RGBA2GRAY)。请注意,OpenCV 的默认颜色空间是 BGR(A),而其他的 (CCImage) 通常是 RGBA。
    • 成功了! :) 那是缺失的部分。现在我应该以某种方式优化代码以减少转换次数(createCvMatFromRaw、cvtColor、reshape、convertTo)。
    猜你喜欢
    • 1970-01-01
    • 2017-10-08
    • 2013-09-28
    • 2019-07-11
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    • 2015-05-21
    相关资源
    最近更新 更多