void mlp ( cv :: Mat & trainingData , cv :: Mat & trainingClasses , cv :: Mat & testData , cv :: Mat &testClasses ) { cv :: Mat layers = cv :: Mat (4 , 1 , CV_32SC1 ) ; layers . row (0) = cv :: Scalar (2) ; layers . row (1) = cv :: Scalar (10) ; layers . row (2) = cv :: Scalar (15) ; layers . row (3) = cv :: Scalar (1) ; CvANN_MLP mlp ; CvANN_MLP_TrainParams params; CvTermCriteria criteria ; criteria.max_iter = 100; criteria.epsilon = 0.00001f ; criteria.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS ; params.train_method = CvANN_MLP_TrainParams :: BACKPROP ; params.bp_dw_scale = 0.05f; params.bp_moment_scale = 0.05f; params.term_crit = criteria; mlp.create ( layers ) ; // train mlp.train ( trainingData , trainingClasses , cv :: Mat () , cv :: Mat () , params ) ; cv::Mat response (1 , 1 , CV_32FC1 ) ; cv::Mat predicted ( testClasses . rows , 1 , CV_32F ) ; for ( int i = 0; i < testData . rows ; i ++) { cv :: Mat response (1 , 1 , CV_32FC1 ) ; cv :: Mat sample = testData . row ( i ) ; mlp . predict ( sample , response ) ; predicted . at < float >( i ,0) = response . at < float >(0 ,0) ; } cout << " Accuracy_ { MLP } = " << evaluate ( predicted , testClasses ) << endl ; plot_binary ( testData , predicted , " Predictions Backpropagation " ) ; }
void train(Mat TrainData, Mat classes, int nlayers){ Mat layers(1,3,CV_32SC1); layers.at<int>(0)= TrainData.cols; layers.at<int>(1)= nlayers; layers.at<int>(2)= numberCharacters; ann.create(layers, CvANN_MLP::SIGMOID_SYM, 1, 1); //Prepare trainClases //Create a mat with n trained data by m classes Mat trainClasses; trainClasses.create( TrainData.rows, numberCharacters, CV_32FC1 ); for( int i = 0; i < trainClasses.rows; i++ ) { for( int k = 0; k < trainClasses.cols; k++ ) { //If class of data i is same than a k class if( k == classes.at<int>(i) ) trainClasses.at<float>(i,k) = 1; else trainClasses.at<float>(i,k) = 0; } } Mat weights( 1, TrainData.rows, CV_32FC1, Scalar::all(1) ); //Learn classifier ann.train( TrainData, trainClasses, weights ); }
void annTrain(Mat TrainData, Mat classes, int nNeruns) { ann.clear(); Mat layers(1, 3, CV_32SC1); layers.at<int>(0) = TrainData.cols; layers.at<int>(1) = nNeruns; layers.at<int>(2) = numAll; ann.create(layers, CvANN_MLP::SIGMOID_SYM, 1, 1); // Prepare trainClases // Create a mat with n trained data by m classes Mat trainClasses; trainClasses.create(TrainData.rows, numAll, CV_32FC1); for (int i = 0; i < trainClasses.rows; i++) { for (int k = 0; k < trainClasses.cols; k++) { // If class of data i is same than a k class if (k == classes.at<int>(i)) trainClasses.at<float>(i, k) = 1; else trainClasses.at<float>(i, k) = 0; } } Mat weights(1, TrainData.rows, CV_32FC1, Scalar::all(1)); // Learn classifier // ann.train( TrainData, trainClasses, weights ); // Setup the BPNetwork // Set up BPNetwork's parameters CvANN_MLP_TrainParams params; params.train_method = CvANN_MLP_TrainParams::BACKPROP; params.bp_dw_scale = 0.1; params.bp_moment_scale = 0.1; // params.train_method=CvANN_MLP_TrainParams::RPROP; // params.rp_dw0 = 0.1; // params.rp_dw_plus = 1.2; // params.rp_dw_minus = 0.5; // params.rp_dw_min = FLT_EPSILON; // params.rp_dw_max = 50.; ann.train(TrainData, trainClasses, Mat(), Mat(), params); }
void Model::Train_mlp( const SampleSet& samples ) { CvANN_MLP* model = (CvANN_MLP*)m_pModel; CvANN_MLP_TrainParams* para = (CvANN_MLP_TrainParams*)m_trainPara; int dim = samples.Dim(); vector<float> classes = samples.Classes(); cv::Mat layerSize = (cv::Mat_<int>(1, 3) << dim, 100, classes.size()); model->create(layerSize); cv::Mat newLaybels = cv::Mat::zeros(samples.N(), classes.size(), CV_32F); for (int n=0; n<samples.N(); n++) { int label = samples.GetLabelAt(n); for (int c=0; c<classes.size(); c++) { if (label == classes[c]) newLaybels.at<float>(n, c) = 1.0f; } } model->train(samples.Samples(), newLaybels, cv::Mat::ones(samples.N(), 1, CV_32F), cv::Mat(), *para); }
//--------------------------------------------------------- bool COpenCV_NNet::On_Execute(void) { //------------------------------------------------- bool b_updateWeights, b_noInputScale, b_noOutputScale, b_NoData; int i_matType, i_layers, i_maxIter, i_neurons, i_areasClassId, i_trainFeatTotalCount, *i_outputFeatureIdxs, i_outputFeatureCount, i_Grid, x, y, i_evalOut, i_winner; double d_alpha, d_beta, d_eps; DATA_TYPE e_dataType; TRAINING_METHOD e_trainMet; ACTIVATION_FUNCTION e_actFunc; CSG_Table *t_Weights, *t_Indices, *t_TrainInput, *t_EvalInput, *t_EvalOutput; CSG_Parameter_Grid_List *gl_TrainInputs; CSG_Grid *g_EvalOutput, *g_EvalOutputCert; CSG_Shapes *s_TrainInputAreas; CSG_Parameters *p_TrainFeatures; TSG_Point p; CvMat *mat_Weights, *mat_Indices, **mat_data, *mat_neuralLayers, mat_layerSizesSub, *mat_EvalInput, *mat_EvalOutput; // todo: mat_indices to respect input indices, mat_weights for initialization CvANN_MLP_TrainParams tp_trainParams; CvANN_MLP model; b_updateWeights = Parameters("UPDATE_WEIGHTS" )->asBool(); b_noInputScale = Parameters("NO_INPUT_SCALE" )->asBool(); b_noOutputScale = Parameters("NO_OUTPUT_SCALE" )->asBool(); i_layers = Parameters("NNET_LAYER" )->asInt(); i_neurons = Parameters("NNET_NEURONS" )->asInt(); i_maxIter = Parameters("MAX_ITER" )->asInt(); i_areasClassId = Parameters("TRAIN_INPUT_AREAS_CLASS_FIELD" )->asInt(); e_dataType = (DATA_TYPE)Parameters("DATA_TYPE" )->asInt(); e_trainMet = (TRAINING_METHOD)Parameters("TRAINING_METHOD" )->asInt(); e_actFunc = (ACTIVATION_FUNCTION)Parameters("ACTIVATION_FUNCTION" )->asInt(); d_alpha = Parameters("ALPHA" )->asDouble(); d_beta = Parameters("BETA" )->asDouble(); d_eps = Parameters("EPSILON" )->asDouble(); t_Weights = Parameters("WEIGHTS" )->asTable(); t_Indices = Parameters("INDICES" )->asTable(); t_TrainInput = Parameters("TRAIN_INPUT_TABLE" )->asTable(); t_EvalInput = Parameters("EVAL_INPUT_TABLE" )->asTable(); t_EvalOutput = Parameters("EVAL_OUTPUT_TABLE" )->asTable(); p_TrainFeatures = Parameters("TRAIN_FEATURES_TABLE" )->asParameters(); gl_TrainInputs = Parameters("TRAIN_INPUT_GRIDS" )->asGridList(); g_EvalOutput = Parameters("EVAL_OUTPUT_GRID_CLASSES" )->asGrid(); g_EvalOutputCert = Parameters("EVAL_OUTPUT_GRID_CERTAINTY" )->asGrid(); s_TrainInputAreas = Parameters("TRAIN_INPUT_AREAS" )->asShapes(); // Fixed matrix type (TODO: Analyze what to do for other types of data (i.e. images)) i_matType = CV_32FC1; //------------------------------------------------- if (e_dataType == TABLE) { // We are working with TABLE data if( t_TrainInput->Get_Count() == 0 || p_TrainFeatures->Get_Count() == 0 ) { Error_Set(_TL("Select an input table and at least one output feature!")); return( false ); } // Count the total number of available features i_trainFeatTotalCount = t_TrainInput->Get_Field_Count(); // Count the number of selected output features i_outputFeatureIdxs = (int *)SG_Calloc(i_trainFeatTotalCount, sizeof(int)); i_outputFeatureCount = 0; for(int i=0; i<p_TrainFeatures->Get_Count(); i++) { if( p_TrainFeatures->Get_Parameter(i)->asBool() ) { i_outputFeatureIdxs[i_outputFeatureCount++] = CSG_String(p_TrainFeatures->Get_Parameter(i)->Get_Identifier()).asInt(); } } // Update the number of training features i_trainFeatTotalCount = i_trainFeatTotalCount-i_outputFeatureCount; if( i_outputFeatureCount <= 0 ) { Error_Set(_TL("Select at least one output feature!")); return( false ); } // Now convert the input and output training data into a OpenCV matrix objects mat_data = GetTrainAndOutputMatrix(t_TrainInput, i_matType, i_outputFeatureIdxs, i_outputFeatureCount); } else { // TODO: Add some grid validation logic i_trainFeatTotalCount = gl_TrainInputs->Get_Count(); i_outputFeatureCount = s_TrainInputAreas->Get_Count(); // Convert the data from the grid into the matrix from mat_data = GetTrainAndOutputMatrix(gl_TrainInputs, i_matType, s_TrainInputAreas, i_areasClassId, g_EvalOutput, g_EvalOutputCert); } //------------------------------------------------- // Add two additional layer to the network topology (0-th layer for input and the last as the output) i_layers = i_layers + 2; mat_neuralLayers = cvCreateMat(i_layers, 1, CV_32SC1); cvGetRows(mat_neuralLayers, &mat_layerSizesSub, 0, i_layers); //Setting the number of neurons on each layer for (int i = 0; i < i_layers; i++) { if (i == 0) { // The first layer needs the same size (number of nerons) as the number of columns in the training data cvSet1D(&mat_layerSizesSub, i, cvScalar(i_trainFeatTotalCount)); } else if (i == i_layers-1) { // The last layer needs the same size (number of neurons) as the number of output columns cvSet1D(&mat_layerSizesSub, i, cvScalar(i_outputFeatureCount)); } else { // On every other layer set the layer size selected by the user cvSet1D(&mat_layerSizesSub, i, cvScalar(i_neurons)); } } //------------------------------------------------- // Create the training params object tp_trainParams = CvANN_MLP_TrainParams(); tp_trainParams.term_crit = cvTermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, i_maxIter, d_eps); // Check which training method was selected and set corresponding params if(e_trainMet == RPROP) { // Set all RPROP specific params tp_trainParams.train_method = CvANN_MLP_TrainParams::RPROP; tp_trainParams.rp_dw0 = Parameters("RP_DW0" )->asDouble(); tp_trainParams.rp_dw_plus = Parameters("RP_DW_PLUS" )->asDouble(); tp_trainParams.rp_dw_minus = Parameters("RP_DW_MINUS" )->asDouble(); tp_trainParams.rp_dw_min = Parameters("RP_DW_MIN" )->asDouble(); tp_trainParams.rp_dw_max = Parameters("RP_DW_MAX" )->asDouble(); } else { // Set all BPROP specific params tp_trainParams.train_method = CvANN_MLP_TrainParams::BACKPROP; tp_trainParams.bp_dw_scale = Parameters("BP_DW_SCALE" )->asDouble(); tp_trainParams.bp_moment_scale = Parameters("BP_MOMENT_SCALE" )->asInt(); } //------------------------------------------------- // Create the model (depending on the activation function) if(e_actFunc == SIGMOID) { model.create(mat_neuralLayers); } else { model.create(mat_neuralLayers, CvANN_MLP::GAUSSIAN, d_alpha, d_beta); } //------------------------------------------------- // Now train the network // TODO: Integrate init weights and indicies for record selection // mat_Weights = GetMatrix(t_Weights, i_matType); // mat_Indices = GetMatrix(t_Indices, i_matType); //model.train(mat_TrainInput, mat_TrainOutput, NULL, NULL, tp_trainParams); model.train(mat_data[0], mat_data[1], NULL, NULL, tp_trainParams); //------------------------------------------------- // Predict data if (e_dataType == TABLE) { // Get the eavaluation/test matrix from the eval table mat_EvalInput = GetEvalMatrix(t_EvalInput, i_matType); } else { // Train and eval data overlap in grid mode mat_EvalInput = GetEvalMatrix(gl_TrainInputs, i_matType); } // Prepare output matrix mat_EvalOutput = cvCreateMat(mat_EvalInput->rows, i_outputFeatureCount, i_matType); // Start prediction model.predict(mat_EvalInput, mat_EvalOutput); Message_Add(_TL("Successfully trained the network and predicted the values. Here comes the output.")); //------------------------------------------------- // Save and print results if (e_dataType == TABLE) { // DEBUG -> Save results to output table and print results for (int i = 0; i < i_outputFeatureCount; i++) { t_EvalOutput->Add_Field(CSG_String(t_TrainInput->Get_Field_Name(i_outputFeatureIdxs[i])), SG_DATATYPE_Float); } for (int i = 0; i < mat_EvalOutput->rows; i++) { CSG_Table_Record* tr_record = t_EvalOutput->Add_Record(); for (int j = 0; j < i_outputFeatureCount; j++) { float f_targetValue = mat_EvalOutput->data.fl[i*i_outputFeatureCount+j]; tr_record->Set_Value(j, f_targetValue); } } } else { // Fill the output table output for (int i = 0; i < i_outputFeatureCount; i++) { // TODO: Get the class name t_EvalOutput->Add_Field(CSG_String::Format(SG_T("CLASS_%d"), i), SG_DATATYPE_Float); } for (int i = 0; i < mat_EvalOutput->rows; i++) { CSG_Table_Record* tr_record = t_EvalOutput->Add_Record(); for (int j = 0; j < i_outputFeatureCount; j++) { float f_targetValue = mat_EvalOutput->data.fl[i*i_outputFeatureCount+j]; tr_record->Set_Value(j, f_targetValue); } } i_evalOut = 0; // Fill the output grid for(y=0, p.y=Get_YMin(); y<Get_NY() && Set_Progress(y); y++, p.y+=Get_Cellsize()) { for(x=0, p.x=Get_XMin(); x<Get_NX(); x++, p.x+=Get_Cellsize()) { for(i_Grid=0, b_NoData=false; i_Grid<gl_TrainInputs->Get_Count() && !b_NoData; i_Grid++) { // If there is one grid that has no data in this point p, then set the no data flag if( gl_TrainInputs->asGrid(i_Grid)->is_NoData(x, y) ) { b_NoData = true; } } if (!b_NoData) { // We have data in all grids, so this is a point that was predicted // Get the winner class for this point and set it to the output grid float f_targetValue = 0; for (int j = 0; j < i_outputFeatureCount; j++) { if (mat_EvalOutput->data.fl[i_evalOut*i_outputFeatureCount+j] > f_targetValue) { // The current value is higher than the last one, so lets memorize the current class f_targetValue = mat_EvalOutput->data.fl[i_evalOut*i_outputFeatureCount+j]; i_winner = j; } } // Now finally set the values to the grids g_EvalOutput->Set_Value(x, y, i_winner); g_EvalOutputCert->Set_Value(x, y, f_targetValue); i_evalOut++; } } } } return( true ); }
// Read the training data and train the network. void trainMachine() { int i; //The number of training samples. int train_sample_count = 130; //The training data matrix. float td[130][61]; //Read the training file FILE *fin; fin = fopen("data/sonar_train.csv", "r"); //Create the matrices //Input data samples. Matrix of order (train_sample_count x 60) CvMat* trainData = cvCreateMat(train_sample_count, 60, CV_32FC1); //Output data samples. Matrix of order (train_sample_count x 1) CvMat* trainClasses = cvCreateMat(train_sample_count, 1, CV_32FC1); //The weight of each training data sample. We'll later set all to equal weights. CvMat* sampleWts = cvCreateMat(train_sample_count, 1, CV_32FC1); //The matrix representation of our ANN. We'll have four layers. CvMat* neuralLayers = cvCreateMat(4, 1, CV_32SC1); //Setting the number of neurons on each layer of the ANN /* We have in Layer 1: 60 neurons (60 inputs) Layer 2: 150 neurons (hidden layer) Layer 3: 225 neurons (hidden layer) Layer 4: 1 neurons (1 output) */ cvSet1D(neuralLayers, 0, cvScalar(60)); cvSet1D(neuralLayers, 1, cvScalar(150)); cvSet1D(neuralLayers, 2, cvScalar(225)); cvSet1D(neuralLayers, 3, cvScalar(1)); //Read and populate the samples. for (i=0;i<train_sample_count;i++) fscanf(fin,"%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &td[i][0],&td[i][1],&td[i][2],&td[i][3],&td[i][4],&td[i][5],&td[i][6],&td[i][7],&td[i][8],&td[i][9],&td[i][10],&td[i][11],&td[i][12],&td[i][13],&td[i][14],&td[i][15],&td[i][16],&td[i][17],&td[i][18],&td[i][19],&td[i][20],&td[i][21],&td[i][22],&td[i][23],&td[i][24],&td[i][25],&td[i][26],&td[i][27],&td[i][28],&td[i][29],&td[i][30],&td[i][31],&td[i][32],&td[i][33],&td[i][34],&td[i][35],&td[i][36],&td[i][37],&td[i][38],&td[i][39],&td[i][40],&td[i][41],&td[i][42],&td[i][43],&td[i][44],&td[i][45],&td[i][46],&td[i][47],&td[i][48],&td[i][49],&td[i][50],&td[i][51],&td[i][52],&td[i][53],&td[i][54],&td[i][55],&td[i][56],&td[i][57],&td[i][58],&td[i][59],&td[i][60]); //we are done reading the file, so close it fclose(fin); //Assemble the ML training data. for (i=0; i<train_sample_count; i++) { //inputs for (int j = 0; j < 60; j++) cvSetReal2D(trainData, i, j, td[i][j]); //Output cvSet1D(trainClasses, i, cvScalar(td[i][60])); //Weight (setting everything to 1) cvSet1D(sampleWts, i, cvScalar(1)); } //Create our ANN. ann.create(neuralLayers); cout << "training...\n"; //Train it with our data. ann.train( trainData, trainClasses, sampleWts, 0, CvANN_MLP_TrainParams( cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100000, 0.000001), CvANN_MLP_TrainParams::BACKPROP, 0.01, 0.05)); }
// Train void *train(Mat &trainData, Mat &response) { if(conf.classifier == "SVM") { std::cout<<"--->SVM Training ..."<<std::endl; CvSVMParams params; params.kernel_type = CvSVM::LINEAR; params.svm_type = CvSVM::C_SVC; params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,1000,1e-6); CvSVM *classifier = new CvSVM; classifier->train(trainData,response,Mat(),Mat(),params); int c = classifier->get_support_vector_count(); printf(" %d support vectors founded.\n",c); return (void *)classifier; } else if(conf.classifier == "BP") { std::cout<<"--->BP Training ..."<<std::endl; // Data transforming. int numClass = (int)conf.classes.size(); cv::Mat labelMat = Mat::zeros(response.rows, numClass, CV_32F); for(int i = 0;i<response.rows;i++) { int k = response.ptr<int>()[i]; labelMat.ptr<float>(i)[k-1] = 1.0; } // Set up BP network parameters CvANN_MLP_TrainParams params; params.term_crit = cvTermCriteria( CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 1000, 0.01 ), params.train_method = CvANN_MLP_TrainParams::BACKPROP; params.bp_dw_scale = 0.1; params.bp_moment_scale = 0.1; CvANN_MLP *classifier = new CvANN_MLP; // Set up the topology structure of BP network. int inputNodeNum = trainData.cols; float ratio = 2; int hiddenNodeNum = static_cast<float>(inputNodeNum) * ratio; int outputNodeNum = numClass; int maxHiddenLayersNum = 1; // It could be better! esp. Output node amount printf(" %d input nodes, %d output nodes.\n",inputNodeNum, outputNodeNum); Mat layerSizes; layerSizes.push_back(inputNodeNum); printf(" Hidden layers nodes' amount:"); layerSizes.push_back(hiddenNodeNum); for(int i = 0 ;i<maxHiddenLayersNum;i++) { if(hiddenNodeNum > outputNodeNum * ratio + 1 ) { hiddenNodeNum = static_cast<float>(hiddenNodeNum) / ratio; layerSizes.push_back(hiddenNodeNum); printf(" %d ",hiddenNodeNum); } else break; } printf("\n"); layerSizes.push_back(outputNodeNum); classifier->create(layerSizes, CvANN_MLP::SIGMOID_SYM); classifier->train(trainData, labelMat, Mat(),Mat(), params); return (void *)classifier; } else{ std::cout<<"--->Error: wrong classifier."<<std::endl; return NULL; } }
int cv_ann() { //Setup the BPNetwork CvANN_MLP bp; // Set up BPNetwork's parameters CvANN_MLP_TrainParams params; params.train_method=CvANN_MLP_TrainParams::BACKPROP; //(Back Propagation,BP)反向传播算法 params.bp_dw_scale=0.1; params.bp_moment_scale=0.1; // Set up training data float labels[10][2] = {{0.9,0.1},{0.1,0.9},{0.9,0.1},{0.1,0.9},{0.9,0.1},{0.9,0.1},{0.1,0.9},{0.1,0.9},{0.9,0.1},{0.9,0.1}}; //这里对于样本标记为0.1和0.9而非0和1,主要是考虑到sigmoid函数的输出为一般为0和1之间的数,只有在输入趋近于-∞和+∞才逐渐趋近于0和1,而不可能达到。 Mat labelsMat(10, 2, CV_32FC1, labels); float trainingData[10][2] = { {11,12},{111,112}, {21,22}, {211,212},{51,32}, {71,42}, {441,412},{311,312}, {41,62}, {81,52} }; Mat trainingDataMat(10, 2, CV_32FC1, trainingData); Mat layerSizes=(Mat_<int>(1,5) << 2, 2, 2, 2, 2); //5层:输入层,3层隐藏层和输出层,每层均为两个perceptron bp.create(layerSizes,CvANN_MLP::SIGMOID_SYM);//CvANN_MLP::SIGMOID_SYM ,选用sigmoid作为激励函数 bp.train(trainingDataMat, labelsMat, Mat(),Mat(), params); //训练 // Data for visual representation int width = 512, height = 512; Mat image = Mat::zeros(height, width, CV_8UC3); Vec3b green(0,255,0), blue (255,0,0); // Show the decision regions for (int i = 0; i < image.rows; ++i) { for (int j = 0; j < image.cols; ++j) { Mat sampleMat = (Mat_<float>(1,2) << i,j); Mat responseMat; bp.predict(sampleMat,responseMat); float* p=responseMat.ptr<float>(0); // if (p[0] > p[1]) { image.at<Vec3b>(j, i) = green; } else { image.at<Vec3b>(j, i) = blue; } } } // Show the training data int thickness = -1; int lineType = 8; circle( image, Point(111, 112), 5, Scalar( 0, 0, 0), thickness, lineType); circle( image, Point(211, 212), 5, Scalar( 0, 0, 0), thickness, lineType); circle( image, Point(441, 412), 5, Scalar( 0, 0, 0), thickness, lineType); circle( image, Point(311, 312), 5, Scalar( 0, 0, 0), thickness, lineType); circle( image, Point(11, 12), 5, Scalar(255, 255, 255), thickness, lineType); circle( image, Point(21, 22), 5, Scalar(255, 255, 255), thickness, lineType); circle( image, Point(51, 32), 5, Scalar(255, 255, 255), thickness, lineType); circle( image, Point(71, 42), 5, Scalar(255, 255, 255), thickness, lineType); circle( image, Point(41, 62), 5, Scalar(255, 255, 255), thickness, lineType); circle( image, Point(81, 52), 5, Scalar(255, 255, 255), thickness, lineType); imwrite("result.png", image); // save the image imshow("BP Simple Example", image); // show it to the user waitKey(0); return 0; }
int CTrain::excuteTrain() { // 读入结果responses 特征data FILE* f = fopen( "batch", "rb" ); fseek(f, 0l, SEEK_END); long size = ftell(f); fseek(f, 0l, SEEK_SET); int count = size/4/(36+256); CvMat* batch = cvCreateMat( count, 36+256, CV_32F ); fread(batch->data.fl, size-1, 1, f); CvMat outputs, inputs; cvGetCols(batch, &outputs, 0, 36); cvGetCols(batch, &inputs, 36, 36+256); fclose(f); // 新建MPL CvANN_MLP mlp; int layer_sz[] = { 256, 20, 36 }; CvMat layer_sizes = cvMat( 1, 3, CV_32S, layer_sz ); mlp.create( &layer_sizes ); // 训练 //system( "time" ); mlp.train( &inputs, &outputs, NULL, NULL, CvANN_MLP_TrainParams(cvTermCriteria(CV_TERMCRIT_ITER,300,0.01), CvANN_MLP_TrainParams::RPROP, 0.01) ); //system( "time" ); // 存储MPL mlp.save( "mpl.xml" ); // 测试 int right = 0; CvMat* output = cvCreateMat( 1, 36, CV_32F ); for(int i=0; i<count; i++) { CvMat input; cvGetRow( &inputs, &input, i ); mlp.predict( &input, output ); CvPoint max_loc = {0,0}; cvMinMaxLoc( output, NULL, NULL, NULL, &max_loc, NULL ); int best = max_loc.x;// 识别结果 int ans = -1;// 实际结果 for(int j=0; j<36; j++) { if( outputs.data.fl[i*(outputs.step/4)+j] == 1.0f ) { ans = j; break; } } cout<<(char)( best<10 ? '0'+best : 'A'+best-10 ); cout<<(char)( ans<10 ? '0'+ans : 'A'+ans-10 ); if( best==ans ) { cout<<"+"; right++; } //cin.get(); cout<<endl; } cvReleaseMat( &output ); cout<<endl<<right<<"/"<<count<<endl; cvReleaseMat( &batch ); system( "pause" ); return 0; }
int main( int argc, char* argv[] ) { // IplImage* teste = cvLoadImage(argv[1]); std::stringstream ss; String cabecalho = "1"; for (int i = 2; i <=411; i++) { ss << i ; cabecalho = cabecalho +","+ ss.str(); ss.str(""); } cabecalho = cabecalho + "\n"; String stri; String x; int contador = 0; FILE * pFile; pFile = fopen ("/Users/fabiofranca/Documents/XCode/Imagiologia/Imagiologia/dataset.csv","w+"); double* treino = new double[410*(74+39+87+14)]; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ESTOMAGO////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // double* esofago = ExDirectoria("esofago/treino",49,"caso2"); for (int i = 0; i<49*410; i++) { treino[i] = esofago[i]; } if (pFile!=NULL) { fputs (cabecalho.c_str(),pFile); } else { printf("Ficheiro nao encontrado"); } for (int i = 0; i<=(49*410); i++) { if(contador == 410) { contador = 0; if(i!=(49*410)) { fputs("esofago\n", pFile); x= std::to_string(esofago[i]).c_str(); stri = ( x+ ","); fputs(stri.c_str(), pFile); contador++; } } else { x= std::to_string(esofago[i]).c_str(); stri = ( x+ ","); fputs(stri.c_str(), pFile); contador++; } } fputs("esofago\n", pFile); // // // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ANTRUM////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // double * estomago = ExDirectoria("estomago/treino", 26,"caso2"); contador = 0; for (int i = 0; i<=26*410; i++) { if(contador == 410) { contador = 0; if(i!=26*410) { fputs("estomago\n", pFile); x= std::to_string(estomago[i]).c_str(); stri = ( x+ ","); fputs(stri.c_str(), pFile); contador++; } } else { x= std::to_string(estomago[i]).c_str(); stri = ( x+ ","); fputs(stri.c_str(), pFile); contador++; } } fputs("estomago\n", pFile); for (int i = 0; i<26*410; i++) { treino[i+(410*49)] = estomago[i]; // printf("%d TREINO - %.2f \n",i+(410*74),treino[i+(410*74)]); } // double * antrum = ExDirectoria("antrum", 18,"caso3"); // contador = 0; // // for (int i = 0; i<=18*410; i++) { // if(contador == 410){ // contador = 0; // if(i!=18*410){ // fputs("antrum\n", pFile); // x= std::to_string(antrum[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // } // }else{ // // x= std::to_string(antrum[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // } // // } // // fputs("antrum\n", pFile); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////BODY////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // double * duodeno = ExDirectoria("duodeno/treino", 58,"caso2"); contador = 0; for (int i = 0; i<=410*58; i++) { if(contador==410) { contador=0; if(i!=410*58) { fputs("duodeno\n", pFile); x= std::to_string(duodeno[i]).c_str(); stri = ( x+ ","); fputs(stri.c_str(), pFile); contador++; } } else { x= std::to_string(duodeno[i]).c_str(); stri = ( x+ ","); fputs(stri.c_str(), pFile); contador++; } } fputs("duodeno\n", pFile); for (int i = 0; i<58*410; i++) { treino[i+(410*(49+26))] = duodeno[i]; // printf("%d TREINO - %.2f \n",i+(410*(74+39)),treino[i+(410*(74+39))]); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Cardia////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // double * cardia = ExDirectoria("cardia", 2); // contador = 0; // for (int i = 0; i<=2*410; i++) { // // if(contador==410){ // contador=0; // if(i!=2*410){ // fputs("cardia\n", pFile); // x= std::to_string(cardia[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // } // }else{ // x= std::to_string(cardia[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // } // // } // fputs("cardia\n", pFile); // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Colon////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // double * colon = ExDirectoria("colon", 5); // contador = 0; // for (int i = 0; i<=410*5; i++) { // // if(contador==410){ // contador = 0; // if(i!=410*5){ // fputs("colon\n", pFile); // x= std::to_string(colon[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // // } // }else{ // x= std::to_string(colon[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // } // // } // fputs("colon\n", pFile); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Duodenum////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // double * body = ExDirectoria("body", 15,"caso3"); // contador = 0; // for (int i = 0; i<=410 * 15; i++) { // // if(contador==410){ // contador =0; // if(i!=410*15){ // fputs("body\n", pFile); // x= std::to_string(body[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // } // }else{ // x= std::to_string(body[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // } // // } // fputs("body\n", pFile); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Fundus////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // double* fundus = ExDirectoria("fundus", 16,"caso3"); // contador = 0; // for (int i = 0; i<=16*410; i++) { // // if(contador==410){ // contador = 0; // if(i!=16*410){ // // fputs("fundus\n", pFile); // x= std::to_string(fundus[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // } // }else{ // x= std::to_string(fundus[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // // } // } // fputs("fundus\n", pFile); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Ileum////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // double * ileum = ExDirectoria("ileum", 8); // contador = 0; // for (int i = 0; i<=8*410; i++) { // // if(contador==410){ // contador = 0; // if(i!=8*410){ // fputs("ileum\n", pFile); // x= std::to_string(ileum[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // } // }else{ // x= std::to_string(ileum[i]).c_str(); // stri = ( x+ ","); // fputs(stri.c_str(), pFile); // contador++; // } // // } // fputs("ileum\n", pFile); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Cardia////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// double * indef = ExDirectoria("exterior/treino", 11, "caso2"); contador=0; for (int i = 0; i<=11*410; i++) { if(contador==410) { contador = 0; if(i!=11*410) { fputs("indefenido\n", pFile); x= std::to_string(indef[i]).c_str(); stri = ( x+ ","); fputs(stri.c_str(), pFile); contador++; } } else { x= std::to_string(indef[i]).c_str(); stri = ( x+ ","); fputs(stri.c_str(), pFile); contador++; } } fputs("indefenido\n", pFile); for (int i = 0; i<11*410; i++) { treino[i+(410*(49+26+58))] = indef[i]; printf("%d TREINO - %.2f \n",i+(410*(49+26+58)),treino[i+(410*(49+26+58))]); } float labels[144]; float trainingData[144][410]; int cont = 0; for(int i = 0; i<144; i++) { // printf("I - %d \n",i); if(i < 49) { labels[i] = 1; } else if(i >= 49 && i<75) { labels[i] = 2; } else if(i >= 75 && i<133) { labels[i] = 3; } else { labels[i] = 4; } for (int j = 0; j< 410; j++) { trainingData[i][j] = treino[(410*cont)+j]; //printf("J*i - %d \n",j*i); // printf("trainingData - %.2f",trainingData[i][j]); if (j==409) { cont=cont+1; } } } cv::Mat layers = cv::Mat(11, 1, CV_32S); layers.at<int>(0,0) = 410;//input layer layers.at<int>(1,0) = 400; layers.at<int>(2,0) = 400; layers.at<int>(3,0) = 400; layers.at<int>(4,0) = 400; layers.at<int>(5,0) = 400; layers.at<int>(6,0) = 400; layers.at<int>(7,0) = 400; layers.at<int>(8,0) = 400; layers.at<int>(9,0) = 400; layers.at<int>(10,0) = 1; Mat labelsMat(144, 1, CV_32FC1, labels); Mat trainingDataMat(144, 410, CV_32FC1, trainingData); printf("%lu - %lu ",trainingDataMat.total(),labelsMat.total()); CvANN_MLP ann; //ANN criteria for termination CvTermCriteria criter; criter.max_iter = 500; criter.type = CV_TERMCRIT_ITER; //ANN parameters CvANN_MLP_TrainParams params; params.train_method = CvANN_MLP_TrainParams::BACKPROP; params.bp_dw_scale = 0.1; params.bp_moment_scale = 0.1; params.term_crit = criter; ann.create(layers,CvANN_MLP::SIGMOID_SYM); printf("Erroyo"); ann.train(trainingDataMat, labelsMat, cv::Mat(), cv::Mat(), params); ann.save("treino"); }
int main() { const int sampleTypeCount = 7; //共有几种字体 const int sampleCount = 50; //每种字体的样本数 const int sampleAllCount = sampleCount*sampleTypeCount; const int featureCount = 256; //特征维数 CvANN_MLP bp;// = CvANN_MLP(layerSizes,CvANN_MLP::SIGMOID_SYM,1,1); string str_dir[sampleTypeCount]; str_dir[0] = "A水滴渍"; str_dir[1] = "B水纹"; str_dir[2] = "C指纹"; str_dir[3] = "D釉面凹凸"; str_dir[4] = "X凹点"; str_dir[5] = "Y杂质"; str_dir[6] = "Z划痕"; float trainingData[sampleAllCount][featureCount] = { 0 }; float outputData[sampleAllCount][sampleTypeCount] = { 0 }; int itemIndex = 0; for (int index = 0; index < 7; index++) { for (int i = 1; i <= 50; i++) { outputData[itemIndex][index] = 1; cout << str_dir[index] << "_" << i << endl; stringstream ss; char num[4]; sprintf(num, "%03d", i); ss << "特征样本库\\" << str_dir[index] << "\\" << num << ".jpg"; string path; ss >> path; //读取灰度图像以便计算灰度直方图 cv::Mat f = cv::imread(path, 0); cv::Mat grayHist; // 设定bin数目,也就是灰度级别,这里选择的是0-255灰度 int histSize = 256; //cv::equalizeHist(f, f); cv::normalize(f, f, histSize, 0, cv::NORM_MINMAX); //cv::bitwise_xor(f, cv::Scalar(255), f);//反相 FeatureMaker::GetGrayHist(f, grayHist, histSize); for (int j = 0; j < 256; j++) { trainingData[itemIndex][j] = grayHist.ptr<float>(j)[0]; } itemIndex++; } } //创建一个网络 cv::Mat layerSizes = (cv::Mat_<int>(1, 3) << featureCount, 25, sampleTypeCount);//创建一个featureCount输入 IDC_EDIT_YinCangCount隐藏 sampleTypeCount输出的三层网络 CvANN_MLP_TrainParams param; param.term_crit = cvTermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 50000, 0.002); param.train_method = CvANN_MLP_TrainParams::BACKPROP; param.bp_dw_scale = 0.01;//权值更新率 param.bp_moment_scale = 0.03;//权值更新冲量 cv::Mat inputs(sampleAllCount, featureCount, CV_32FC1, trainingData);//样品总数,特征维数,储存的数据类型 cv::Mat outputs(sampleAllCount, sampleTypeCount, CV_32FC1, outputData); bp.create(layerSizes, CvANN_MLP::SIGMOID_SYM); bp.train(inputs, outputs, cv::Mat(), cv::Mat(), param); bp.save("ANN_mlp.xml"); itemIndex = 0; int zhengque = 0; for (int index = 0; index < 7; index++) { for (int i = 1; i <= 50; i++) { cv::Mat sampleMat(1, featureCount, CV_32FC1, trainingData[itemIndex]);//样品总数,特征维数,储存的数据类型 cv::Mat nearest(1, sampleTypeCount, CV_32FC1, cv::Scalar(0)); bp.predict(sampleMat, nearest); float possibility = -1; int outindex = 0; for (int i = 0; i < nearest.size().width; i++){ float x = nearest.at<float>(0, i); if (x>possibility){ possibility = x; outindex = i; } } if (outindex == index) zhengque++; cout << str_dir[index] << "_" << i << ":" << outindex << "->" << possibility << "->" << str_dir[outindex] << endl; itemIndex++; } } cout << "正确率" << ((double)zhengque / (double)sampleAllCount); return 0; }
// Read the training data and train the network. void trainMachine() { int i; //The number of training samples. int train_sample_count; //The training data matrix. //Note that we are limiting the number of training data samples to 1000 here. //The data sample consists of two inputs and an output. That's why 3. float td[10000][3]; //Read the training file /* A sample file contents(say we are training the network for generating the mean given two numbers) would be: 5 12 16 14 10 5 7.5 8 10 9 5 4 4.5 12 6 9 */ FILE *fin; fin = fopen("train.txt", "r"); //Get the number of samples. fscanf(fin, "%d", &train_sample_count); printf("Found training file with %d samples...\n", train_sample_count); //Create the matrices //Input data samples. Matrix of order (train_sample_count x 2) CvMat* trainData = cvCreateMat(train_sample_count, 2, CV_32FC1); //Output data samples. Matrix of order (train_sample_count x 1) CvMat* trainClasses = cvCreateMat(train_sample_count, 1, CV_32FC1); //The weight of each training data sample. We'll later set all to equal weights. CvMat* sampleWts = cvCreateMat(train_sample_count, 1, CV_32FC1); //The matrix representation of our ANN. We'll have four layers. CvMat* neuralLayers = cvCreateMat(4, 1, CV_32SC1); CvMat trainData1, trainClasses1, neuralLayers1, sampleWts1; cvGetRows(trainData, &trainData1, 0, train_sample_count); cvGetRows(trainClasses, &trainClasses1, 0, train_sample_count); cvGetRows(trainClasses, &trainClasses1, 0, train_sample_count); cvGetRows(sampleWts, &sampleWts1, 0, train_sample_count); cvGetRows(neuralLayers, &neuralLayers1, 0, 4); //Setting the number of neurons on each layer of the ANN /* We have in Layer 1: 2 neurons (2 inputs) Layer 2: 3 neurons (hidden layer) Layer 3: 3 neurons (hidden layer) Layer 4: 1 neurons (1 output) */ cvSet1D(&neuralLayers1, 0, cvScalar(2)); cvSet1D(&neuralLayers1, 1, cvScalar(3)); cvSet1D(&neuralLayers1, 2, cvScalar(3)); cvSet1D(&neuralLayers1, 3, cvScalar(1)); //Read and populate the samples. for (i=0;i<train_sample_count;i++) fscanf(fin,"%f %f %f",&td[i][0],&td[i][1],&td[i][2]); fclose(fin); //Assemble the ML training data. for (i=0; i<train_sample_count; i++) { //Input 1 cvSetReal2D(&trainData1, i, 0, td[i][0]); //Input 2 cvSetReal2D(&trainData1, i, 1, td[i][1]); //Output cvSet1D(&trainClasses1, i, cvScalar(td[i][2])); //Weight (setting everything to 1) cvSet1D(&sampleWts1, i, cvScalar(1)); } //Create our ANN. machineBrain.create(neuralLayers);//sigmoid 0 0(激活函数的两个参数) //Train it with our data. machineBrain.train( trainData,//输入 trainClasses,//输出 sampleWts,//输入项的权值 0, CvANN_MLP_TrainParams( cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,///类型 CV_TERMCRIT_ITER 和CV_TERMCRIT_EPS二值之一,或者二者的组合 10000000,//最大迭代次数 0.00000001//结果的精确性 两次迭代间权值变化量 ), CvANN_MLP_TrainParams::BACKPROP,//BP算法 0.01,//几个可显式调整的参数 学习速率 阿尔法 0.05 //惯性参数 ) ); }
void MainWindow::on_pushButton_test_clicked() { QString str = QFileDialog::getExistingDirectory(); QByteArray ba = str.toLocal8Bit(); char *c_str = ba.data(); string slash = "/"; Mat training; Mat response; read_num_class_data("train.txt", 4, training, response); cout<<training.rows<<endl; cout<<response.rows<<endl; ofstream output_file; output_file.open("Ratio.txt"); Mat layers = Mat(3,1,CV_32SC1); int sz = training.cols ; layers.row(0) = Scalar(sz); layers.row(1) = Scalar(16); layers.row(2) = Scalar(1); CvANN_MLP mlp; CvANN_MLP_TrainParams params; CvTermCriteria criteria; criteria.max_iter = 1000; criteria.epsilon = 0.00001f; criteria.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS; params.train_method = CvANN_MLP_TrainParams::BACKPROP; params.bp_dw_scale = 0.1f; params.bp_moment_scale = 0.1f; params.term_crit = criteria; mlp.create(layers,CvANN_MLP::SIGMOID_SYM); int i = mlp.train(training, response, Mat(),Mat(),params); // Train dataset FileStorage fs("mlp.xml", FileStorage::WRITE); // or xml mlp.write(*fs, "mlp"); // don't think too much about the deref, it casts to a FileNode ui->label_training->setText("Training finish"); //mlp.load("mlp.xml","mlp"); //Load ANN weights for each layer vector<string> img_name; string output_directory = "output_img/"; img_name = listFile(c_str); Mat testing(1, 3, CV_32FC1); Mat predict (1 , 1, CV_32F ); int file_num = 0; for(int i = 0; i < img_name.size(); i++) //size of the img_name { ui->progressBar->setValue(i*100/img_name.size()); string file_name = c_str + slash + img_name[i]; Mat img_test = imread(file_name); Mat img_test_clone = img_test.clone(); Mat img_thresh, img_thresh_copy, img_HSV, img_gray; vector<Mat> img_split; cvtColor(img_test_clone, img_HSV, CV_RGB2HSV); cvtColor(img_test_clone, img_gray, CV_RGB2GRAY); split(img_HSV, img_split); threshold(img_split[0], img_thresh, 75, 255, CV_THRESH_BINARY); img_thresh_copy = img_thresh.clone(); Mat hole = img_thresh_copy.clone(); floodFill(hole, Point(0,0), Scalar(255)); bitwise_not(hole, hole); img_thresh_copy = (img_thresh_copy | hole); Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); Mat open_result; morphologyEx(img_thresh, open_result, MORPH_CLOSE, element ); int infected_num = 0; int total_pixels = 0; if(img_test.data) { file_num++; for (int m = 0; m < img_test.rows; m++) { for (int n = 0; n < img_test.cols; n++) { if (img_thresh_copy.at<uchar>(m, n) == 255) { total_pixels++; testing.at<float>(0, 0) = (float)img_test.at<Vec3b>(m, n)[0]; testing.at<float>(0, 1) = (float)img_test.at<Vec3b>(m, n)[1]; testing.at<float>(0, 2) = (float)img_test.at<Vec3b>(m, n)[2]; mlp.predict(testing,predict); float a = predict.at<float>(0,0); if (a < 0.4) //0.4 { img_test.at<Vec3b>(m, n)[0] = 0; img_test.at<Vec3b>(m, n)[1] = 0; img_test.at<Vec3b>(m, n)[2] = 255; infected_num++; } } } } float ratio = (float)infected_num / total_pixels * 100; output_file<<img_name[i]<<" "<<(ratio)<<endl; string output_file_name = output_directory + img_name[i]; cout<<output_file_name<<endl; imwrite(output_file_name, img_test); QImage img_qt = QImage((const unsigned char*)(img_test_clone.data), img_test_clone.cols, img_test_clone.rows, QImage::Format_RGB888); QImage img_qt_result = QImage((const unsigned char*)(img_test.data), img_test.cols, img_test.rows, QImage::Format_RGB888); //ui->label_original->setPixmap(QPixmap::fromImage(img_qt.rgbSwapped())); //ui->label_resulting->setPixmap(QPixmap::fromImage((img_qt_result.rgbSwapped()))); // imshow("Ori", img_thresh_copy); imshow("split", img_test); waitKey(0); QThread::msleep(100); } else { continue; } } ui->progressBar->setValue(100); output_file<<endl<<endl<<"Number of processed images: "<<file_num<<endl; cout<<"Test finished!"; }
int main() { const int sampleTypeCount = 7; //共有几种字体 const int sampleCount = 50; //每种字体的样本数 const int sampleAllCount = sampleCount*sampleTypeCount; const int featureCount = 256; //特征维数 CvANN_MLP bp;// = CvANN_MLP(layerSizes,CvANN_MLP::SIGMOID_SYM,1,1); string str_dir[sampleTypeCount]; str_dir[0] = "A水滴渍"; str_dir[1] = "B水纹"; str_dir[2] = "C指纹"; str_dir[3] = "D釉面凹凸"; str_dir[4] = "X凹点"; str_dir[5] = "Y杂质"; str_dir[6] = "Z划痕"; float trainingData[sampleAllCount][featureCount] = { 0 }; float outputData[sampleAllCount][sampleTypeCount] = { 0 }; int itemIndex = 0; for (int index = 0; index < 7; index++) { for (int i = 1; i <= 50; i++) { outputData[itemIndex][index] = 1; cout << str_dir[index] << "_" << i << endl; stringstream ss; char num[4]; sprintf(num, "%03d", i); ss << "特征样本库\\" << str_dir[index] << "\\" << num << ".jpg"; string path; ss >> path; //读取灰度图像以便计算灰度直方图 cv::Mat f = cv::imread(path, 0); cv::Mat grayHist; // 设定bin数目,也就是灰度级别,这里选择的是0-255灰度 int histSize = 63; //cv::equalizeHist(f, f); cv::normalize(f, f, histSize, 0, cv::NORM_MINMAX); //cv::bitwise_xor(f, cv::Scalar(255), f);//反相 // 设定取值范围,设定每级灰度的范围。 float range[] = { 0, 255 }; const float* histRange = { range }; bool uniform = true; bool accumulate = false; cv::calcHist(&f, 1, 0, cv::Mat(), grayHist, 1, &histSize, &histRange, uniform, accumulate); for (int j = 0; j < 256; j++) { trainingData[itemIndex][j] = grayHist.ptr<float>(0)[0]; } itemIndex++; /* // 创建直方图画布 int hist_w = 400; int hist_h = 400; int bin_w = cvRound((double)hist_w / histSize); cv::Mat histImage(hist_w, hist_h, CV_8UC3, cv::Scalar(0, 0, 0)); /// 将直方图归一化到范围 [ 0, histImage.rows ] cv::normalize(grayHist, grayHist, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat()); /// 在直方图画布上画出直方图 for (int i = 1; i < histSize; i++) { line(histImage, cv::Point(bin_w*(i - 1), hist_h - cvRound(grayHist.at<float>(i - 1))), cv::Point(bin_w*(i), hist_h - cvRound(grayHist.at<float>(i))), cv::Scalar(0, 0, 255), 2, 8, 0); } stringstream s; s << "samples\\反相正规化直方图\\" << str_dir[index] << "\\"; //s << "samples\\正规化直方图\\" << str_dir[index] << "\\"; //s << "samples\\均衡化直方图\\" << str_dir[index] << "\\"; //s << "samples\\直方图\\" << str_dir[index] << "\\"; //string dir = s.str(); //char* c; //int len = dir.length(); //c = new char[len + 1]; //strcpy(c, dir.c_str()); //CheckDir(c); s << "" << num << ".jpg"; s >> path; cv::imwrite(path, histImage); s.clear(); s << "samples\\反相正规化直方图\\" << str_dir[index] << "\\" << "Hist_" << num << ".jpg"; //s << "samples\\正规化直方图\\" << str_dir[index] << "\\" << "Hist_" << num << ".jpg"; //s << "samples\\均衡化直方图\\" << str_dir[index] << "\\" << "Hist_" << num << ".jpg"; //s << "samples\\直方图\\" << str_dir[index] << "\\" << "Hist_" << num << ".jpg"; s >> path; cv::imwrite(path, grayHist); /// 显示直方图 //cv::namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE); //cv::imshow("calcHist Demo", histImage); //cv::waitKey(0); */ } } //创建一个网络 cv::Mat layerSizes = (cv::Mat_<int>(1, 3) << featureCount, 25, sampleTypeCount);//创建一个featureCount输入 IDC_EDIT_YinCangCount隐藏 sampleTypeCount输出的三层网络 CvANN_MLP_TrainParams param; param.term_crit = cvTermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 5000, 0.01); param.train_method = CvANN_MLP_TrainParams::BACKPROP; param.bp_dw_scale = 0.2; param.bp_moment_scale = 0.1; cv::Mat inputs(sampleAllCount, featureCount, CV_32FC1, trainingData);//样品总数,特征维数,储存的数据类型 cv::Mat outputs(sampleAllCount, sampleTypeCount, CV_32FC1, outputData); bp.create(layerSizes, CvANN_MLP::SIGMOID_SYM); bp.train(inputs, outputs, cv::Mat(), cv::Mat(), param); bp.save("ANN_mlp.xml"); itemIndex = 0; for (int index = 0; index < 7; index++) { for (int i = 1; i <= 50; i++) { cv::Mat sampleMat(1, featureCount, CV_32FC1, trainingData[itemIndex]);//样品总数,特征维数,储存的数据类型 cv::Mat nearest(1, sampleTypeCount, CV_32FC1, cv::Scalar(0)); bp.predict(sampleMat, nearest); float possibility = -1; int outindex = 0; for (int i = 0; i < nearest.size().width; i++){ float x = nearest.at<float>(0, i); if (x>possibility){ possibility = x; outindex = i; } } cout << str_dir[index] << "_" << i << ":" << outindex << "->" << possibility << "->" << str_dir[outindex] << endl; itemIndex++; } } return 0; }
static int build_mlp_classifier( char* data_filename, char* filename_to_save, char* filename_to_load ) { const int class_count = 26; CvMat* data = 0; CvMat train_data; CvMat* responses = 0; CvMat* mlp_response = 0; int ok = read_num_class_data( data_filename, 16, &data, &responses ); int nsamples_all = 0, ntrain_samples = 0; int i, j; double train_hr = 0, test_hr = 0; CvANN_MLP mlp; if( !ok ) { printf( "Could not read the database %s\n", data_filename ); return -1; } printf( "The database %s is loaded.\n", data_filename ); nsamples_all = data->rows; ntrain_samples = (int)(nsamples_all*0.8); // Create or load MLP classifier if( filename_to_load ) { // load classifier from the specified file mlp.load( filename_to_load ); ntrain_samples = 0; if( !mlp.get_layer_count() ) { printf( "Could not read the classifier %s\n", filename_to_load ); return -1; } printf( "The classifier %s is loaded.\n", data_filename ); } else { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // // MLP does not support categorical variables by explicitly. // So, instead of the output class label, we will use // a binary vector of <class_count> components for training and, // therefore, MLP will give us a vector of "probabilities" at the // prediction stage // // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CvMat* new_responses = cvCreateMat( ntrain_samples, class_count, CV_32F ); // 1. unroll the responses printf( "Unrolling the responses...\n"); for( i = 0; i < ntrain_samples; i++ ) { int cls_label = cvRound(responses->data.fl[i]) - 'A'; float* bit_vec = (float*)(new_responses->data.ptr + i*new_responses->step); for( j = 0; j < class_count; j++ ) bit_vec[j] = 0.f; bit_vec[cls_label] = 1.f; } cvGetRows( data, &train_data, 0, ntrain_samples ); // 2. train classifier int layer_sz[] = { data->cols, 100, 100, class_count }; CvMat layer_sizes = cvMat( 1, (int)(sizeof(layer_sz)/sizeof(layer_sz[0])), CV_32S, layer_sz ); mlp.create( &layer_sizes ); printf( "Training the classifier (may take a few minutes)...\n"); mlp.train( &train_data, new_responses, 0, 0, CvANN_MLP_TrainParams(cvTermCriteria(CV_TERMCRIT_ITER,300,0.01), #if 1 CvANN_MLP_TrainParams::BACKPROP,0.001)); #else CvANN_MLP_TrainParams::RPROP,0.05)); #endif cvReleaseMat( &new_responses ); printf("\n"); } mlp_response = cvCreateMat( 1, class_count, CV_32F ); // compute prediction error on train and test data for( i = 0; i < nsamples_all; i++ ) { int best_class; CvMat sample; cvGetRow( data, &sample, i ); CvPoint max_loc = {0,0}; mlp.predict( &sample, mlp_response ); cvMinMaxLoc( mlp_response, 0, 0, 0, &max_loc, 0 ); best_class = max_loc.x + 'A'; int r = fabs((double)best_class - responses->data.fl[i]) < FLT_EPSILON ? 1 : 0; if( i < ntrain_samples ) train_hr += r; else test_hr += r; } test_hr /= (double)(nsamples_all-ntrain_samples); train_hr /= (double)ntrain_samples; printf( "Recognition rate: train = %.1f%%, test = %.1f%%\n", train_hr*100., test_hr*100. ); // Save classifier to file if needed if( filename_to_save ) mlp.save( filename_to_save ); cvReleaseMat( &mlp_response ); cvReleaseMat( &data ); cvReleaseMat( &responses ); return 0; }
// Read the training data and train the network. void trainMachine() { int i; //The number of training samples. int train_sample_count; //The training data matrix. //Note that we are limiting the number of training data samples to 1000 here. //The data sample consists of two inputs and an output. That's why 3. //td es la matriz dinde se cargan las muestras float td[3000][7]; //Read the training file /* A sample file contents(say we are training the network for generating the mean given two numbers) would be: 5 12 16 14 10 5 7.5 8 10 9 5 4 4.5 12 6 9 */ FILE *fin; fin = fopen("train.txt", "r"); //Get the number of samples. fscanf(fin, "%d", &train_sample_count); printf("Found training file with %d samples...\n", train_sample_count); //Create the matrices //Input data samples. Matrix of order (train_sample_count x 2) CvMat* trainData = cvCreateMat(train_sample_count, 6, CV_32FC1); //Output data samples. Matrix of order (train_sample_count x 1) CvMat* trainClasses = cvCreateMat(train_sample_count, 1, CV_32FC1); //The weight of each training data sample. We'll later set all to equal weights. CvMat* sampleWts = cvCreateMat(train_sample_count, 1, CV_32FC1); //The matrix representation of our ANN. We'll have four layers. CvMat* neuralLayers = cvCreateMat(2, 1, CV_32SC1); CvMat trainData1, trainClasses1, neuralLayers1, sampleWts1; cvGetRows(trainData, &trainData1, 0, train_sample_count); cvGetRows(trainClasses, &trainClasses1, 0, train_sample_count); cvGetRows(trainClasses, &trainClasses1, 0, train_sample_count); cvGetRows(sampleWts, &sampleWts1, 0, train_sample_count); cvGetRows(neuralLayers, &neuralLayers1, 0, 2); //Setting the number of neurons on each layer of the ANN /* We have in Layer 1: 2 neurons (6 inputs) Layer 2: 3 neurons (hidden layer) Layer 3: 3 neurons (hidden layer) Layer 4: 1 neurons (1 output) */ cvSet1D(&neuralLayers1, 0, cvScalar(6)); //cvSet1D(&neuralLayers1, 1, cvScalar(3)); //cvSet1D(&neuralLayers1, 2, cvScalar(3)); cvSet1D(&neuralLayers1, 1, cvScalar(1)); //Read and populate the samples. for (i=0; i<train_sample_count; i++) fscanf(fin,"%f %f %f %f",&td[i][0],&td[i][1],&td[i][2],&td[i][3]); fclose(fin); //Assemble the ML training data. for (i=0; i<train_sample_count; i++) { //Input 1 cvSetReal2D(&trainData1, i, 0, td[i][0]); //Input 2 cvSetReal2D(&trainData1, i, 1, td[i][1]); cvSetReal2D(&trainData1, i, 2, td[i][2]); cvSetReal2D(&trainData1, i, 3, td[i][3]); cvSetReal2D(&trainData1, i, 4, td[i][4]); cvSetReal2D(&trainData1, i, 5, td[i][5]); //Output cvSet1D(&trainClasses1, i, cvScalar(td[i][6])); //Weight (setting everything to 1) cvSet1D(&sampleWts1, i, cvScalar(1)); } //Create our ANN. machineBrain.create(neuralLayers); //Train it with our data. //See the Machine learning reference at http://www.seas.upenn.edu/~bensapp/opencvdocs/ref/opencvref_ml.htm#ch_ann machineBrain.train( trainData, trainClasses, sampleWts, 0, CvANN_MLP_TrainParams( cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100000, 1.0 ), CvANN_MLP_TrainParams::BACKPROP, 0.01, 0.05 ) ); }
int main(int argc, char ** argv) { // read command line arguments if (argc != 5) { cerr << "usage: " << argv[0] << " <training samples> <training labels>" << " <testing samples> <testing labels>" << endl; exit(-1); } const string trainingSamplesFilename = argv[1]; const string trainingLabelsFilename = argv[2]; const string testingSamplesFilename = argv[3]; const string testingLabelsFilename = argv[4]; try { Chrono chrono; cout << fixed << showpoint << setprecision(2); ////////////////////////////////////////////////// // training ////////////////////////////////////////////////// int trainingN, trainingQ, trainingK; cv::Mat trainingSamples, trainingLabels; loadSamplesLabels(trainingSamplesFilename, trainingSamples, trainingLabelsFilename, trainingLabels, trainingN, trainingQ, trainingK); // build class probabilities cv::Mat trainingLabelsK = cv::Mat::zeros(trainingN, trainingK, CV_64FC1); cv::Mat trainingHist = cv::Mat::zeros(1, trainingK, CV_32SC1); for (int n=0; n<trainingN; n++) { int r = trainingLabels.at<int>(n, 0); assert(r>=0 and r<trainingK); trainingLabelsK.at<double>(n, r) = 1.0; trainingHist.at<int>(0, r)++; } cout << "trainingHist: " << format(trainingHist, "csv") << endl; // TODO tune network // init layers (2 hidden layers with 10 neurons per layer) cv::Mat layers = cv::Mat(3, 1, CV_32SC1); layers.row(0) = cv::Scalar(trainingQ); layers.row(1) = cv::Scalar(trainingQ*trainingK); layers.row(2) = cv::Scalar(trainingK); CvANN_MLP network; network.create(layers); // init training params CvANN_MLP_TrainParams params; CvTermCriteria criteria; criteria.max_iter = 100; criteria.epsilon = 0.00001f; criteria.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS; params.term_crit = criteria; params.train_method = CvANN_MLP_TrainParams::BACKPROP; params.bp_dw_scale = 0.05f; params.bp_moment_scale = 0.05f; // compute training network.train(trainingSamples, trainingLabelsK, cv::Mat(), cv::Mat(), params); double trainingTime = chrono.elapsedAndReset(); cout << "trainingTime: " << trainingTime << endl << endl; ////////////////////////////////////////////////// // testing ////////////////////////////////////////////////// int testingN, testingQ, testingK; cv::Mat testingSamples, testingLabels; loadSamplesLabels(testingSamplesFilename, testingSamples, testingLabelsFilename, testingLabels, testingN, testingQ, testingK); // compute testing int K = max(trainingK, testingK); cv::Mat testingHist = cv::Mat::zeros(1, K, CV_32SC1); cv::Mat positives = cv::Mat::zeros(K, K, CV_32SC1); unsigned nbTp = 0; unsigned nbFp = 0; for(int n = 0; n < testingN; n++) { // compute prediction cv::Mat sample = testingSamples.row(n); // TODO remove allocation ? cv::Mat prediction; network.predict(sample, prediction); //cout << "sample: " << format(sample, "csv") << endl; //cout << "prediction: " << format(prediction, "csv") << endl; // get the class corresponding to the prediction double vMin, vMax; cv::Point pMin, pMax; cv::minMaxLoc(prediction, &vMin, &vMax, &pMin, &pMax); // test if expected == predicted int predicted = pMax.x; int expected = testingLabels.at<int>(n, 0); //cout << "expected: " << expected << endl; //cout << "predicted: " << predicted << endl; testingHist.at<int>(0, expected)++; positives.at<int>(predicted, expected)++; if (expected == predicted) nbTp++; else nbFp++; } cout << "testingHist: " << format(testingHist, "csv") << endl; double accuracy = nbTp / double(nbTp+nbFp); double testingTime = chrono.elapsed(); cout << "testingTime: " << testingTime << endl << endl; ////////////////////////////////////////////////// // display results ////////////////////////////////////////////////// // TODO display network params cout << " " << format(positives,"csv") << endl; cout << "accuracy: " << accuracy << endl; } catch (cv::Exception & e) { cerr << "exception caught: " << e.what() << endl; } return 0; }