您的位置:首页 > 理论基础 > 计算机网络

【opencv】神经网络CvANN_MLP分类

2016-05-10 08:47 891 查看
参考

小魏的修行路

/article/1351978.html

文中向量坐标选择的不太直观,所以简单修改了一下

关于opencv 神经网络函数的一些可以参考 water_93的博客

http://blog.csdn.net/water_93/article/details/51244987

CvANN_MLP::predict(constMat&inputs,Mat&outputs)


在这篇中提到图像进行特征提取,把它保存在inputs里,通过调用predict函数,我们得到一个输出向量,它是一个1*nClass的行向量,其中每一列说明它与该类的相似程度(0-1之间),也可以说是置信度。我们只用对output求一个最大值,就可得到结果。

以下程序CvANN_MLP::predict只有一个输出,label中有3类,0,1,2,分开这三类用相邻两类的均值,0.5,1.5

//编程环境:VS2012 + Opencv2.4.9
#include <fstream>
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;
#define COUNT 21 //读入的点个数

int main()
{
//从文件载入数据
float data[COUNT][2];
ifstream fin1("data.txt");
for(int i=0;i<COUNT;i++)
{
fin1>>data[i][0];
fin1>>data[i][1];
}
fin1.close();
//显示读入的数据
for(int i=0;i<COUNT;i++)
{
cout<<data[i][0]<<" ";
cout<<data[i][1]<<" "<<endl;
}

float label[COUNT][1];
ifstream fin2("label.txt");
for(int i=0;i<COUNT;i++)
{
fin2>>label[i][0];
}
fin2.close();
//显示读入的数据
for(int i=0;i<COUNT;i++)
{
cout<<label[i][0]<<" "<<endl;
}

Mat trainData(COUNT, 2, CV_32FC1, data);
Mat trainLabel(COUNT, 1, CV_32FC1, label);

cout<<"trainData"<<trainData<<endl;
cout<<"trainLabel"<<trainLabel<<endl;

CvANN_MLP bp;
CvANN_MLP_TrainParams param;
param.term_crit = cvTermCriteria(CV_TERMCRIT_ITER,10000,0.001);  //设置结束条件
param.train_method = CvANN_MLP_TrainParams::BACKPROP;       //训练方法采用BackProgation
param.bp_dw_scale=0.1;
param.bp_moment_scale=0.1;

Mat layerSizes=(Mat_<int>(1,3) << 2,8,1);
bp.create(layerSizes, CvANN_MLP::SIGMOID_SYM);
//bp.create(layerSizes, CvANN_MLP::GAUSSIAN);
//bp.create(layerSizes, CvANN_MLP::IDENTITY);
bp.train(trainData, trainLabel, Mat(), Mat(), param);
bp.save("bp.xml");

Mat image = Mat::zeros(500, 500, CV_8UC3);
Vec3b white(255,255,255), black (0,0,0), gray(125,125,125);

for (int i = 0; i < image.cols; i++)
{
for (int j = 0; j < image.rows; j++)
{
Mat sampleMat = (Mat_<float>(1,2) << i,j);
Mat responseMat;
bp.predict(sampleMat, responseMat);
float* p=responseMat.ptr<float>(0);
if (p[0] > 1.5) //这里选择1.5 是 1类与2类的均值
image.at<Vec3b>(j, i)  = white;
else if(p[0] > 0.5)//这里选择0.5 是 0类与1类的均值
image.at<Vec3b>(j, i)  = black;
else
image.at<Vec3b>(j, i)  = gray;

}
}

for (int i = 0; i < COUNT; i++)
{
Point p(data[i][0],data[i][1]);
if (label[i][0]>1.5)//这里选择1.5 是 1类与2类的均值
circle( image, p, 3, Scalar(255, 255, 0), -1, 8);
else if(label[i][0]>0.5)//这里选择0.5 是 0类与1类的均值
circle( image, p, 3, Scalar(255, 0, 255), -1, 8);
else
circle( image, p, 3, Scalar(0, 255, 255), -1, 8);

}

imshow("result",image);
imwrite("output.jpg",image);
waitKey(0);

return 0;
}


label.txt

0
1
0
1
0
0
0
1
0
1
1
1
0
1
1
2
2
1
0
0
2


data.txt

100 250
250 450
150 160
300 420
210 120
90 20
70 60
330 210
80 200
400 120
420 200
300 300
50 130
270 300
320 310
490 450
480 480
420 400
250 250
230 270
400 300


结果

神经网络Mat layerSizes=(Mat_(1,3) << 2,8,1);



神经网络Mat layerSizes=(Mat_(1,4) << 2,8,8,1);



感觉这样分类也是可以的啊~

以下程序CvANN_MLP::predict有3个输出,label中有3类,按照water_93的博客编写

//编程环境:VS2012 + Opencv2.4.9

#include <fstream>
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;
#define COUNT 21 //读入的点个数

int main()
{
//从文件载入数据
float data[COUNT][2];
ifstream fin1("data.txt");
for(int i=0;i<COUNT;i++)
{
fin1>>data[i][0];
fin1>>data[i][1];
}
fin1.close();
//显示读入的数据
for(int i=0;i<COUNT;i++)
{
cout<<data[i][0]<<" ";
cout<<data[i][1]<<" "<<endl;
}

float label[COUNT][3];
ifstream fin2("label2.txt");
for(int i=0;i<COUNT;i++)
{
fin2>>label[i][0];
fin2>>label[i][1];
fin2>>label[i][2];
}
fin2.close();
//显示读入的数据
for(int i=0;i<COUNT;i++)
{
cout<<label[i][0]<<" "<<label[i][1]<<" "<<label[i][2]<<endl;
}

Mat trainData(COUNT, 2, CV_32FC1, data);
Mat trainLabel(COUNT, 3, CV_32FC1, label);

cout<<"trainData"<<trainData<<endl;
cout<<"trainLabel"<<trainLabel<<endl;

CvANN_MLP bp;
CvANN_MLP_TrainParams param;
param.term_crit = cvTermCriteria(CV_TERMCRIT_ITER,10000,0.001);  //设置结束条件
param.train_method = CvANN_MLP_TrainParams::BACKPROP;       //训练方法采用BackProgation
param.bp_dw_scale=0.1;
param.bp_moment_scale=0.1;

Mat layerSizes=(Mat_<int>(1,3) << 2,8,3);
bp.create(layerSizes, CvANN_MLP::SIGMOID_SYM);
//bp.create(layerSizes, CvANN_MLP::GAUSSIAN);
//bp.create(layerSizes, CvANN_MLP::IDENTITY);
bp.train(trainData, trainLabel, Mat(), Mat(), param);
bp.save("bp.xml");

Mat image = Mat::zeros(500, 500, CV_8UC3);
Vec3b white(255,255,255), black (0,0,0), gray(125,125,125);

for (int i = 0; i < image.cols; i++)
{
for (int j = 0; j < image.rows; j++)
{
Mat sampleMat = (Mat_<float>(1,2) << i,j);
Mat responseMat;
bp.predict(sampleMat, responseMat);
Point maxLoc;
minMaxLoc(responseMat,NULL,NULL,NULL,&maxLoc);
if (maxLoc.x == 0)
image.at<Vec3b>(j, i)  = white;
if (maxLoc.x == 1)
image.at<Vec3b>(j, i)  = black;
if (maxLoc.x == 2)
image.at<Vec3b>(j, i)  = gray;

}
}

for (int i = 0; i < COUNT; i++)
{
Point p(data[i][0],data[i][1]);
if (label[i][0]>0)
circle( image, p, 3, Scalar(255, 255, 0), -1, 8);
if (label[i][1]>0)
circle( image, p, 3, Scalar(255, 0, 255), -1, 8);
if (label[i][2]>0)
circle( image, p, 3, Scalar(0, 255, 255), -1, 8);

}

imshow("result",image);
imwrite("output.jpg",image);
waitKey(0);

return 0;
}


data.txt同上

label2.txt

1 0 0
0 1 0
1 0 0
0 1 0
1 0 0
1 0 0
1 0 0
0 1 0
1 0 0
0 1 0
0 1 0
0 1 0
1 0 0
0 1 0
0 1 0
0 0 1
0 0 1
0 1 0
1 0 0
1 0 0
0 0 1


结果

神经网络 Mat layerSizes=(Mat_(1,3) << 2,8,3);



神经网络 Mat layerSizes=(Mat_(1,4) << 2,8,8,3);



后者的代码已上传,见链接:

http://download.csdn.net/detail/qq_15947787/9515042
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: