我有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 ¢ers, 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
答案 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)));
}
你需要逐步完成它,看看它崩溃的地方,然后弄清楚你做错了什么。