【问题标题】:opencv error: assertion failed in cv::Mat::at file: mat.inl.hpp line 930opencv 错误:cv::Mat::at 文件中的断言失败:mat.inl.hpp 第 930 行
【发布时间】:2016-04-15 15:57:17
【问题描述】:

我有 svm 训练阶段的代码。我使用 ms 视觉工作室。执行以下代码时出现错误:

#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

【问题讨论】:

  • 这并不是真正的错误。断言是一种受控方式,它告诉您某些东西应该是X,但计算结果为Y,因此它没有遵循您“绑定”到它的合同。真的只用于调试。
  • 谢谢。我会尝试改变 x 和 y。
  • 你能建议我,我需要在哪里更改代码吗?
  • @Neijwiert 它仅用于调试目的,但它表示一个重大错误(在这种情况下调用 Mat::at() 时出现 Mat 越界错误),直到您尝试覆盖受保护的内存。基本上你必须仔细检查所有 Mat::at() 调用

标签: c++ visual-studio opencv


【解决方案1】:

当您尝试访问不在矩阵内的像素时,通常会发生此错误。也称为访问您的程序未预料到的内存部分。

举个例子:

我有一个 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)));
    }

您需要逐步检查它,看看它在哪里崩溃,然后找出您做错了什么。

【讨论】:

    猜你喜欢
    • 2014-11-25
    • 2019-05-04
    • 2017-12-24
    • 2016-02-21
    • 2023-03-23
    • 2018-11-29
    • 1970-01-01
    • 2021-02-26
    • 2015-09-26
    相关资源
    最近更新 更多