Я пытаюсь использовать классификатор SVC OpenCV в игре cocos2d-x. Вот простой тест функции:Ошибка 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