I follow opencv documentation. I have hve txt file (512 by 512 type:double) I cannot upload them here.. They are generated with envy software. I combine those file and made data of 262144 by 3 dimension. I generate image from it. it.
For function for read data :
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/ik147_4.txt");
string line;
vector<Mat> raw_data(cl);//= new std::vector<cv::Mat>(4);
int row;
double min,max;
for(int i =0;i<cl;i++)
{
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);
cout<<"Number of data (row) : "<< N << endl;
int columns_to_read=cl;
data.create(N,columns_to_read,CV_32FC1);
for(int i=0;i<columns_to_read;i++)
{
raw_data[i](Rect(0,0,1,N)).copyTo(data(Rect(i,0,1,N)));
}
}
int main()
{
int width = 512, height = 512;
Mat image = Mat::zeros(height, width, CV_8UC3);
Mat img = Mat::zeros(height, width, CV_8UC3);
Mat img_kmeans = Mat::zeros(height, width, CV_8UC3);
// Mat image3 = Mat::zeros(height, width, CV_8UC3);
Mat data, train_data11, test_data11;
readData(data);
printDim(data,"data");
//print(mat1,3); // direct reshape train to 512 by 512//
// printDim(mat1, "Dimension of Mat1");
Mat train_data1 = data.reshape(3, 512 ); // Mat train_data1 = data.reshape(3, 512 );
printDim(train_data1, "Dimension of train_data1");
Mat image1;
double Min, Max;
minMaxLoc(train_data1, &Min, &Max);
// train_data.convertTo(train_data,CV_8UC3);
train_data1.convertTo(image1,CV_8U,255.0/(Max-Min),-255.0/Min);
printDim(image1,"Dimension of Image");
//Mat img1 = image1.reshape(3, 512 );
//printDim(img1,"Dimension of Image");
imshow( "window_name", image1 );
imwrite("3channel.jpg",image1);
/*For take 30% of total data, i randomly generate numbers and with help of it, i store pixel values of image in other matrix(78642 by 3) . Than perform kmeans for generating labels. I use 10 clusters. Than I perform training phase.
phase.* /
int N1=78642;
Mat location(N1, 1, CV_32FC1);
RNG rng((unsigned)time(NULL));
RNG rng_center(20);
//RNG rng(0xFFFF);
cout<<"New 1 :"<< endl;
//rng.fill(location, RNG::UNIFORM, Scalar(0,5), Scalar(4,8));
rng.fill(location, RNG::UNIFORM, 0, 1);
//print(location,3);
cout<<"New 2 :"<< endl;
location=78642 * location;
//print(location,3);
for(int i=0;i<N1;++i)
{
location.at<float>(i,0)= cvCeil(location.at<float>(i,0));
// labelsMat.at<int>(i)= cvCeil(labelsMat.at<int>(i));
}
location=abs(location);
cout<<"New 2 :"<< endl;
//print(location,3);
//cout << "test of .data : "<< (int)location.data << endl;
Mat image3 = imread("3channel.jpg", 1);
imshow("value test",image3);
vector<int> c1;
vector<int> r1;
// int i,j;
for(int i=0;i<location.rows;i++)
//for(int j=0; j<image.cols; j++ )
{
// cout<< "value of t : "<< location.at<float>(i,0) << endl;
int t=location.at<float>(i,0);
// cout<< "value of t.1 : "<< t << endl;
int s= 512;
int c= t % s;
// cout<< "value of c : "<< c << endl;
//vector<int> c1;
c1.push_back (c);
int r = (t-c)/ s;
// cout<< "value of r : "<< r << endl;
r1.push_back (r);
//cout<< "value of pixel at (" << r <<","<< c << ") : " <<train_data1.at<float>(r,c) << endl;
// cout<< "value of pixel at (" << r <<","<< c << ") : " <<image3.at<Vec3b>(r,c) << endl;
}
cout << "Number of elements in r1 : " << int(r1.size()) << " and c1 :" << int(c1.size()) << endl;
vector<float> v;
for(int i=0; i<int(r1.size()); i++ )
{
v.push_back(image3.at<Vec3b>(r1[i],c1[i])[0]);
v.push_back(image3.at<Vec3b>(r1[i],c1[i])[1]);
v.push_back(image3.at<Vec3b>(r1[i],c1[i])[2]);
}
cout << "----------------------- " << endl;
// cout<<"30 % of data :"<< endl<< Mat(v) << endl;
cout << "----------------------- " << endl;
printDim(Mat(v),"MAT(v)");
// printDim(train1,"train 1");
Mat vv = Mat(v).reshape(1,78642);
//Mat vv = train1.reshape(2,78642);
printDim( vv,"MAT vv");
int N=vv.rows; //number of data points
cout << "N of vv rows:"<< N << endl;
cout <<" "<<endl;
int K=10;
int clusterCount=K;
int sampleCount = N;
Mat labelsMatKMeans;
Mat centers;
kmeans(vv, clusterCount, labelsMatKMeans,
TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1),
3, KMEANS_PP_CENTERS, centers);
cout<< " " << endl;
cout<< "final center :"<<endl;
printDim(centers,"Dim of centers");
// print(centers, 3);
cout<< " " << endl;
cout<< "labels :"<<endl;
printDim(labelsMatKMeans,"Dim of labels");
cout<< " " << endl;
vector<Vec3b> colors_region;
vector<Vec3b> colors_data;
//generate random colors for each label
for(int i=0;i<K;++i)
{
int icolor = (unsigned) rng;
colors_region.push_back( Vec3b( icolor&255, (icolor>>8)&255, (icolor>>16)&255 ));
icolor=(unsigned)rng;
colors_data.push_back( Vec3b( icolor&255, (icolor>>8)&255, (icolor>>16)&255 ));
}
Ptr<SVM> svm = SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::LINEAR);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));
svm->train(vv, ROW_SAMPLE, labelsMatKMeans);
svm->save("svm_params.xml");
After that i perform prediction. I got decisoin region like this
My prediction code :
svm->Algorithm::load<SVM>("svm_params.xml");
int i;
int j;
Mat sampleMat;
Mat results(0, 1, CV_32FC1);
for ( i = 0; i < image.rows; ++i)
for ( j = 0; j < image.cols; ++j)
{
sampleMat = (Mat_<float>(1, 3) << (0,i),(1,i),(2,i));
// Mat sampleMat = (Mat_<float>(1, 3) << 2,i);
float response = svm->predict(sampleMat);
results.push_back(response);
image.at<Vec3b>(i,j)= colors_region[(float)response];
}
printDim(sampleMat, "samplemat1");
cout<< "total response1 : " << (int)results.data << endl;
// print(results,3);
imshow("Test1",image);
As per image, my decision region should difference. Please suggest me , where i need to change.