【opencv】神经网络CvANN_MLP分类

参考
小魏的修行路
http://blog.csdn.net/xiaowei_cqu/article/details/9027617
文中向量坐标选择的不太直观,所以简单修改了一下

关于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 
#include 
#include 

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

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

    cout<<"trainData"<cout<<"trainLabel"<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(j, i)  = white;  
            else if(p[0] > 0.5)//这里选择0.5 是 0类与1类的均值
                image.at(j, i)  = black;  
            else
                image.at(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);
【opencv】神经网络CvANN_MLP分类_第1张图片
神经网络Mat layerSizes=(Mat_(1,4) << 2,8,8,1);
【opencv】神经网络CvANN_MLP分类_第2张图片

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

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

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

#include 
#include 
#include 

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

int main()
{
    //从文件载入数据
    float data[COUNT][2];   
    ifstream fin1("data.txt");  
    for(int i=0;i>data[i][0];   
        fin1>>data[i][1];
    }
    fin1.close();   
    //显示读入的数据
    for(int i=0;icout<0]<<" ";
        cout<1]<<" "<float label[COUNT][3];  
    ifstream fin2("label2.txt");    
    for(int i=0;i>label[i][0];  
        fin2>>label[i][1];  
        fin2>>label[i][2];  
    }
    fin2.close();   
    //显示读入的数据
    for(int i=0;icout<0]<<" "<1]<<" "<2]<2, CV_32FC1, data);
    Mat trainLabel(COUNT, 3, CV_32FC1, label);

    cout<<"trainData"<cout<<"trainLabel"<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(j, i)  = white;  
            if (maxLoc.x == 1)
                image.at(j, i)  = black;  
            if (maxLoc.x == 2)
                image.at(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);
【opencv】神经网络CvANN_MLP分类_第3张图片
神经网络 Mat layerSizes=(Mat_(1,4) << 2,8,8,3);
【opencv】神经网络CvANN_MLP分类_第4张图片

后者的代码已上传,见链接:
http://download.csdn.net/detail/qq_15947787/9515042

你可能感兴趣的:(opencv,opencv)