2017-02-20 958 views
1

我試圖在cocos2d-x遊戲中使用OpenCV SVM分類器。這裏有一個簡單的測試功能:OpenCV錯誤:斷言失敗(samples.cols == var_count && samples.type()== CV_32F)預測

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

是什麼意思斷言?有人可以向我解釋嗎?我怎樣才能解決這個問題?

回答

2

斷言說

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

這意味着該樣品或者不具有列的權數或不具有類型CV_32F

看起來您忘記了reshape函數,所以您的數據違反了第一個條件。我認爲爲了應用svm,數據需要是一個向量,即1 x n矩陣。

+0

cv :: Mat testMat2 = testMat.clone()。reshape(1,1); - 我試過了,結果是一樣的。 – Makalele

+0

嘗試加載圖像作爲灰色圖像:'imread(「test.jpg」,0)' –

+0

我甚至嘗試過:cv :: cvtColor(testMat,greyMat,cv :: COLOR_BGR2GRAY); – Makalele

相關問題