我試圖在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
是什麼意思斷言?有人可以向我解釋嗎?我怎樣才能解決這個問題?
cv :: Mat testMat2 = testMat.clone()。reshape(1,1); - 我試過了,結果是一樣的。 – Makalele
嘗試加載圖像作爲灰色圖像:'imread(「test.jpg」,0)' –
我甚至嘗試過:cv :: cvtColor(testMat,greyMat,cv :: COLOR_BGR2GRAY); – Makalele