Opencv学习记录【十】——神经网络MLP(多层感知机)

opencv为我们提供了多种机器学习方法,比如adaboost、svm、神经网络等。本文主要记录其神经网络的原理和用法(参考赵春江的“机器学习经典算法剖析基于opencv”,人民邮电出版社,214-220)

下面就以照片的方式贴出其原理:
在这里插入图片描述在这里插入图片描述

OpenCV的人工神经网络是机器学习算法中的其中一种,使用的是多层感知器(Multi- Layer Perception,MLP),是常见的一种ANN算法。MLP算法一般包括三层,分别是一个输入层,一个输出层和一个或多个隐藏层的神经网络组成。每一层由一个或多个神经元互相连结。一个“神经元”的输出便是另一个“神经元”的输入。
OpenCV中的神经网络的训练,需要创建两个数据矩阵,一个是特征数据矩阵,一个是标签矩阵。但要注意的是标签矩阵是一个N*M的矩阵,N表示训练样本数,M是类标签。如果第i行的样本属于第j类,那么该标签矩阵的(i,j)位置为1。 OpenCV中ANN定义了CvANN_MLP类。使用ANN算法之前,必须先初始化参数,比如神经网络的层数、神经元数,激励函数、α和β。然后使用train函数进行训练,训练完成可以训练好的参数以xml的格式保存在本地文件夹。最后就可以使用predict函数来预测测试集。

如何利用opencv的神经网络api呢,很简单,可以看其官网或者按照下面的例子进行实践。
这个例子是人脸贴图利用opencv神经网络对脸部区域的位置和脸部器官位置信息进行训练,然后达到检测到脸部后通过神经网络即可定位相关器官。(这样免去了各个器官的检测,器官定位更快速)

代码说明:

先进行脸部、眼部、鼻子、嘴巴的检测(opencv提供的haar特征分类器)
都检测到后每帧的四个Rect信息存在一个文件中
读取该文件,face Rect 作为输入,其他作为输出,进行训练

源码:

#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/ml/ml.hpp>  
#include <iostream>   
#include <fstream>
#include<string>
using namespace std;
using namespace cv;

//从眼部得到全脸  Mat eyesdata(Mat_<float>(1,3) << eyesRect.x,eyesRect.y,eyesRect.width)
cv::Mat  getFace_Bpnet(char *bpxml,cv::Mat eyesdata)
{
   CvANN_MLP bp; //bp网络
   bp.load(bpxml);//读取模型
   Mat facedata; //一组预测结果  facedata(1, 3,CV_32FC1)(Mat_<int>(1, 3) << 3,18,3)
   bp.predict(eyesdata, facedata);
   return facedata;
}

int test_cvNNapi(int group_data,int cmd)
{
    CvANN_MLP bp; //bp网络
    string datafile = "/home/jiang/Repositories/FaceDeal_Class/train_data/mydata.txt";
    string testfile = "/home/jiang/Repositories/FaceDeal_Class/train_data/testdata.txt";
    string resultfile = "/home/jiang/Repositories/FaceDeal_Class/train_data/resultfile.txt";
    char buffer[50];
    if(cmd == 1)
    {                      // trainning
        int *IN_data = new int[3];
        int *OUT_data = new int[3];
        //建立一个标签矩阵
        Mat labelsMat(group_data, 3, CV_32FC1);
        //建立一个训练样本矩阵
        Mat trainingDataMat(group_data, 3, CV_32FC1);           // cols = 3 ; rows = group_data  at(y,x)

        fstream ifile;
        int count_hang = 0;
        ifile.open(datafile,ios::in);
        for(int i=0;i<group_data;i++)
        {
            //每行格式          ,101,22,333,120,333,12,
            ifile.getline(buffer, 50, '\n');     //getline(char *,int,char) 表示该行字符达到 50 个或遇到换行就结束;
            int num_count = -1;
            for(int j = 0; j < 50; ){
                if(num_count >=5 )
                    break;
                else if(buffer[j] == ','){
                    num_count++;
                    if(num_count < 3){
                        if(buffer[j+4] == ','){
                            IN_data[num_count] = (buffer[j+1] - '0')*100 + (buffer[j+2] - '0')*10 + (buffer[j+3] - '0')*1;
                            j = j+4;
                        }

                        else if (buffer[j+3] == ','){
                            IN_data[num_count] = (buffer[j+1] - '0')*10 + (buffer[j+2] - '0')*1;
                            j = j+3;
                        }

                        else if(buffer[j+2] == ','){
                            IN_data[num_count] = (buffer[j+1] - '0')*1;
                            j = j+2;
                        }
                        else
                            break;
                    }
                    else {
                        if(buffer[j+4] == ','){
                            OUT_data[num_count-3] = (buffer[j+1] - '0')*100 + (buffer[j+2] - '0')*10 + (buffer[j+3] - '0')*1;
                            j = j+4;
                        }

                        else if (buffer[j+3] == ','){
                            OUT_data[num_count-3] = (buffer[j+1] - '0')*10 + (buffer[j+2] - '0')*1;
                            j = j+3;
                        }

                        else if(buffer[j+2] == ','){
                            OUT_data[num_count-3] = (buffer[j+1] - '0')*1;
                            j = j+2;
                     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值