opencv错误:在cv :: Mat :: at file:mat.inl.hpp第930行中断言失败

时间:2016-01-11 11:05:00

标签: c++ visual-studio opencv

我有svm训练阶段的代码。我使用ms visual studio。执行下面的代码时出错:

#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;
}

执行此代码时,出现此错误:

我能够从文本文件中读取数据,也可以读取center.txt中的数据来定义kmeans的中心。它在mat.inl.hpp文件中的Mat :: at上显示错误。我跟着其他参考文献。还尝试将数据类型从CV_32FC1更改为CV_32F。但我无法解决错误。1

1 个答案:

答案 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)));
    }

你需要逐步完成它,看看它崩溃的地方,然后弄清楚你做错了什么。