예제 #1
0
void CImageProcess::ANN_Region()
{
	char path[512] = {0};
	float obj[MAX_TRAIN_COLS] = {0};
	Sample("./sources/0 (1).bmp", obj, MAX_TRAIN_COLS);

	CvANN_MLP bpANN;

	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.1;
	param.bp_moment_scale = 0.1;

	Mat	layerSize = (Mat_<int>(1,3)<<MAX_TRAIN_COLS ,MAX_OBJ_COLS,MAX_OBJ_COLS);
	bpANN.create(layerSize, CvANN_MLP::SIGMOID_SYM);


	//m_bpANN.load("./sources/mlp.xml");

	Mat input(1, MAX_TRAIN_COLS, CV_32FC1, obj);
	float _obj[MAX_OBJ_COLS] ={0};
	Mat out(1, MAX_OBJ_COLS, CV_32FC1, _obj);
	//Mat out;
	bpANN.predict(input,out);

	int i=0;
	i+=i;

}
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 " ) ;
}
예제 #3
0
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 );
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
//---------------------------------------------------------
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));
}
예제 #8
0
// 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;
	}	
}
예제 #9
0
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;
}
예제 #10
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;
}
예제 #13
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;
}
예제 #17
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
        )
    );
}
예제 #18
-1
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;
}