2016-01-11 2 views
0

У меня есть код для тренировочной фазы svm. Я использую ms visual studio. Я получил сообщение об ошибке при выполнении кода ниже:ошибка opencv: утверждение не выполнено в cv :: Mat :: at file: mat.inl.hpp line 930

#include <opencv/highgui.h> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/ml/ml.hpp> 
#include <fstream> 
#include <ctime> 
#include <stdio.h> 
#include <math.h> 
#include <opencv\cv.h> 
#include <opencv2\objdetect\objdetect.hpp> 
#include <opencv2\imgproc\imgproc.hpp> 
#include <opencv2\imgcodecs.hpp> 
#include <opencv2\core\core.hpp> 
#include <vector> 
#include <windows.h> 
#include <atlstr.h> 
#include <iostream> 
#include <sstream> 
#include <iomanip> 
#include <opencv2\core\core.hpp> 
#include <opencv\cvaux.hpp> 


using namespace cv; 
using namespace cv::ml; 
using namespace std; 
void readCenters(cv::Mat&, const char *); 
cv::Mat shuffleRows(const cv::Mat&,const cv::Mat&); 


int CLUSTER_COUNT=5;//number of clusters 
Mat train_data1; 
Mat test_data; 
void splitData(cv::Mat &data,cv::Mat &train_data1,cv::Mat &test_data) 
{ 
    int N=data.rows; 
    float ratio=0.7; 
    int train_data_length= N*ratio; 
    int test_data_length=N-train_data_length; 
    data(cv::Rect(0,0,data.cols,train_data_length)).copyTo(train_data1);  
     data(cv::Rect(0,train_data_length,data.cols,test_data_length)).copyTo(test_data);  
    cout<<"length : "<<train_data_length<<endl; 

} 

void readData(cv::Mat& data) 
{ 
    std::vector<const char *> filenames; 
    filenames.push_back("Data/ik147_1.txt"); 
    filenames.push_back("Data/ik147_2.txt"); 
    filenames.push_back("Data/ik147_3.txt"); 
    filenames.push_back("Data/labels.txt"); 
    std::string line; 
    std::vector<cv::Mat> raw_data(4);//= new std::vector<cv::Mat>(4); 
    int row; 
    double min,max; 
    for(int i =0;i<4;i++) 
    { 
     std::ifstream file(filenames[i]); 
     while(file>>row) 
     { 
      raw_data[i].push_back(row); 
     } 
     minMaxLoc(raw_data[i],&min,&max); 
     cout<<filenames[i]<<" min :"<<min<<", max :"<<max<<std::endl; 

    } 
    int N=raw_data[0].rows; 
    // cv::Mat data(N,3,CV_32FC1); 
    int columns_to_read=3; 
    data.create(N,columns_to_read,CV_32FC1); 
    for(int i=0;i<columns_to_read;i++) 
    { 
     raw_data[i](cv::Rect(0,0,1,N)).copyTo(data(cv::Rect(i,0,1,N))); 
    } 
} 

void computeLabelledData(cv:: Mat& data,cv::Mat &data_with_labels){ 
    cv::Mat labels,centers;  
    cv::kmeans(data, CLUSTER_COUNT, labels, 
       cv::TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0), 
       3, cv::KMEANS_PP_CENTERS, centers); 


    data_with_labels.create(data.rows,data.cols+1,CV_32FC1); 
    data.copyTo(data_with_labels(cv::Rect(0,0,data.cols,data.rows))); 
    labels.copyTo(data_with_labels(cv::Rect(data.cols,0,labels.cols,labels.rows))); 
} 

int main() 
{ 

    Mat data; 
    readData(data); 
    Mat data_with_labels,train_data_labels,test_data_labels; 
    computeLabelledData(data,data_with_labels); 
    splitData(data,train_data1,test_data); 
    // Data for visual representation 
    int width = 512, height = 512; 
    Mat image = Mat::zeros(height, width, CV_8UC3); 
    int N=data.rows; //number of data points 

    int K=5; //number of labels 

    Mat train_data(train_data1.rows,train_data1.cols,CV_32F); 
    Mat labels; 

    int clusterCount=K; 
    int sampleCount = N; 
    Mat centers(5,2,CV_32FC1); 
    readCenters(centers,"centers.txt"); 
    Point center; 
    center.x = 0;//rng_center.uniform(0, height); 
    center.y = 0;//rng_center.uniform(0, width); 

    // Set up training data 


    Mat labels_converted; 
    labels.convertTo(labels_converted, CV_32SC1); 

    Ptr<SVM> svm = SVM::create(); 
    // edit: the params struct got removed, 
    // we use setter/getter now: 
    svm->setType(SVM::C_SVC); 
// svm->setC(0.1); 
    svm->setKernel(SVM::LINEAR); 
    svm->setDegree(1./5); 
    svm->setGamma(100); 
    svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6)); 


    // Train the SVM 
    //CvSVM svm; 

     svm->train(train_data, ROW_SAMPLE, labels_converted); 
     svm->save("svm_params.xml"); 
      cout<<"svm parameters saved to : svm_params.xml"<<endl; 
getchar(); 
} 

void readCenters(cv::Mat &centers, const char * filename){ 
    const int ROWS=5; 
    const int COLS=2; 
    cout<<"reading centers "<<filename<<endl; 
    float array[ROWS][COLS]; 
    std::ifstream file(filename); 
    std::string line; 
    int row,col; 
    int i=0; 

    while(file>>row>>col) 
    { 
     centers.at<float>(i,0)=row; 
     centers.at<float>(i,1)=col; 
     i++; 
    } 
} 

cv::Mat shuffleRows(const cv::Mat &matrix,const cv::Mat &seeds) 
{ 
    cv::Mat output; 
    for (int cont = 0; cont < matrix.rows; cont++) 
    output.push_back(matrix.row((int)seeds.at<float>(cont,0))); 

    return output; 
} 

при выполнении этого кода, я получил эту ошибку:

я в состоянии считывать данные из текстовых файлов также centers.txt для определения центров kmeans. Он показывает ошибку в Mat :: at в файле mat.inl.hpp. Я следовал другим рекомендациям. Также попытался изменить типы данных с CV_32FC1 на CV_32F. Но я не могу решить ошибку. 1

+0

Это не ошибка. Утверждение - это контролируемый способ сказать вам, что что-то должно быть «X», но оценивается как «Y», поэтому оно не соответствует контракту, который вы «привязали» к нему. Он используется только для отладки. – Neijwiert

+0

Спасибо. я попытаюсь изменить x и y. –

+0

Можете ли вы мне предложить, где мне нужно изменить код? –

ответ

0

Эта ошибка часто возникает, когда вы пытаетесь получить доступ к пикселю не внутри вашей матрицы. Также известен как доступ к части памяти, которую ваша программа не ожидала.

Возьмем такой пример:

У меня есть матрицу, 10,10, и я пытаюсь получить доступ к 11,11 пиксель. Моя программа выйдет из строя, и я получу ошибку, которую вы показываете выше. Это также может произойти, даже если я попытаюсь получить доступ к 8,8, если я не загрузил изображение должным образом.

Возьмите свой код, где бы вы обращаетесь к матрице может вызвать эту проблему, например, эту часть кода:

for(int i=0;i<columns_to_read;i++) 
    { 
     raw_data[i](cv::Rect(0,0,1,N)).copyTo(data(cv::Rect(i,0,1,N))); 
    } 

Вам нужно будет пройти через него и посмотреть, куда это происходит сбой, а затем рисунок что вы делаете неправильно.