예제 #1
0
int main() {
	std::vector<ContourWithData> allContoursWithData;			
	std::vector<ContourWithData> validContoursWithData;			

																
	cv::Mat matClassificationFloats;	

	cv::FileStorage fsClassifications("classifications.xml", cv::FileStorage::READ);		

	if (fsClassifications.isOpened() == false) {													
		std::cout << "error, unable to open training classifications file, exiting program\n\n";	
		return(0);																					
	}

	fsClassifications["classifications"] >> matClassificationFloats;		
	fsClassifications.release();											

																			

	cv::Mat matTrainingImages;			

	cv::FileStorage fsTrainingImages("images.xml", cv::FileStorage::READ);			

	if (fsTrainingImages.isOpened() == false) {													
		std::cout << "error, unable to open training images file, exiting program\n\n";			
		return(0);																				
	}

	fsTrainingImages["images"] >> matTrainingImages;				
	fsTrainingImages.release();										

																

	cv::Ptr<cv::ml::KNearest> kNearest = cv::ml::KNearest::create();					
	cv::Ptr<cv::ml::TrainData> trainingData = cv::ml::TrainData::create(matTrainingImages, cv::ml::SampleTypes::ROW_SAMPLE, matClassificationFloats);
	kNearest->setIsClassifier(true);
	kNearest->setAlgorithmType(cv::ml::KNearest::Types::BRUTE_FORCE);
	kNearest->setDefaultK(101);
	cv::Mat matResults(0, 0, CV_32F);
															
	kNearest->train(trainingData);		
																	

																	

	cv::Mat matTestingNumbers = cv::imread("test_numbers.png");		

	if (matTestingNumbers.empty()) {								
		std::cout << "error: image not read from file\n\n";			
		return(0);													
	}

	cv::Mat matGrayscale;			
	cv::Mat matBlurred;				
	cv::Mat matThresh;				
	cv::Mat matThreshCopy;			

	cv::cvtColor(matTestingNumbers, matGrayscale, CV_BGR2GRAY);		

																	
	threshold(matGrayscale, matThresh, 10, 255, CV_THRESH_BINARY_INV);								

	matThreshCopy = matThresh.clone();					

	std::vector<std::vector<cv::Point> > ptContours;		
	std::vector<cv::Vec4i> v4iHierarchy;					

	cv::findContours(matThreshCopy,					
		ptContours,					
		v4iHierarchy,					
		CV_RETR_EXTERNAL,				
		CV_CHAIN_APPROX_TC89_KCOS);		

	for (int i = 0; i < ptContours.size(); i++) {			
		ContourWithData contourWithData;												
		contourWithData.ptContour = ptContours[i];										
		contourWithData.boundingRect = cv::boundingRect(contourWithData.ptContour);		
		contourWithData.fltArea = cv::contourArea(contourWithData.ptContour);			
		allContoursWithData.push_back(contourWithData);									
	}

	for (int i = 0; i < allContoursWithData.size(); i++) {					
		if (allContoursWithData[i].checkIfContourIsValid()) {				
			validContoursWithData.push_back(allContoursWithData[i]);		
		}
	}
	
	std::sort(validContoursWithData.begin(), validContoursWithData.end(), ContourWithData::sortByBoundingRectXPosition);

	std::string strFinalString;			

	for (int i = 0; i < validContoursWithData.size(); i++) {			

																		
		cv::rectangle(matTestingNumbers,				
			validContoursWithData[i].boundingRect,		
			cv::Scalar(0, 255, 0),						
			2);											

		cv::Mat matROI = matThresh(validContoursWithData[i].boundingRect);		

		cv::Mat matROIResized;
		cv::resize(matROI, matROIResized, cv::Size(RESIZED_IMAGE_WIDTH, RESIZED_IMAGE_HEIGHT));		

		cv::Mat matROIFloat;
		matROIResized.convertTo(matROIFloat, CV_32FC1);				

																	
		float fltCurrentChar = kNearest->findNearest(matROIFloat.reshape(1,1), kNearest->getDefaultK(), matResults);							

		strFinalString = strFinalString + char(int(fltCurrentChar));		
	}

	cv::Mat string_box(100,500,CV_8UC3, cv::Scalar::all(0));
	int baseLine = 0;

	cv::Size string_size = cv::getTextSize(strFinalString, CV_FONT_HERSHEY_DUPLEX, 1, 2, &baseLine);
	baseLine += 2;
	cv::Point textOrg((string_box.cols - string_size.width) / 2, (string_box.rows + string_size.height) / 2);

	cv::putText(string_box, strFinalString, textOrg, CV_FONT_HERSHEY_DUPLEX, 1, cv::Scalar::all(255), 2, 8);
	cv::imshow("result", string_box);

	cv::imshow("matTestingNumbers", matTestingNumbers);		

	cv::waitKey(0);											

	return(0);
}
void PlateRecognizer::Process()
{
	knn_ = cv::Algorithm::load < cv::ml::KNearest>( "C:\\Users\\Jonathan\\Documents\\ESGI\\5A\\machine_learning\\datasets\\savedDatas"); //chargement des données entrainées
	for ( std::vector<Image>::iterator it = images_.begin(); it != images_.end(); ++it )//pour chacune des images du dossier
	{
		cv::Mat image1 = ( *it ).GetImage();//on stock dans une variable temp l'image en cours
		std::vector<Plate> tmpplates = std::vector<Plate>();
		if ( Detection( image1, tmpplates ) )//detections des plaques temporaires
		{
			( *it ).SetPlates( tmpplates );
			cv::Mat result;
			image1.copyTo( result );
			if ( showResult )//si jamais ce booleen est a true on affiche les rectangle autours des plaques détectées
			{
				for ( std::vector<Plate>::const_iterator pit = ( *it ).GetPlates().cbegin(); pit != ( *it ).GetPlates().cend(); ++pit )
				{
					cv::Point2f rect_points[4];
					( *pit ).GetRect().points( rect_points );
					for ( int j = 0; j < 4; j++ )
						line( result, rect_points[j], rect_points[( j + 1 ) % 4], cv::Scalar( 255, 100, 0 ), 5, 8 );
				}
				cv::imshow( "PlateRecognizer", result );
				cv::waitKey();
			}
			for ( std::vector<Plate>::iterator pit = ( *it ).GetPlates().begin(); pit != ( *it ).GetPlates().end(); ++pit )//pour chacunes des plaques detectées
			{
				CharactersDetection( *pit );//on detecte les caractere et on rempli le vector chars de la Plate courante
				std::cout << "number of chars detected = " << ( *pit ).GetChars().size() << std::endl;
			}
			const int size = 20; //la taille de chaque caractere (a etre redimensionné)
			const int tolerence = 60; //la tolerance : chaque pixel est entre 0 et 255 pour du nb on choisis une valeur tolerance pour dire : plus petit que la tolerance = 0 sinon 1
			for ( std::vector<Plate>::const_iterator pit = ( *it ).GetPlates().cbegin(); pit != ( *it ).GetPlates().cend(); ++pit )//pour chacune des plaques
			{
				std::vector<char> letters = std::vector<char>();
				for ( std::vector<Chars>::const_iterator cit = ( *pit ).GetChars().cbegin(); cit != ( *pit ).GetChars().cend(); ++cit )//pour chacuns des carateres de la plaque
				{
					cv::Mat resized;
					cv::resize( ( *cit ).m_char, resized, cv::Size( size, size ) );//on resize en size*size (meme valeur que pour le dataset)					
					cv::Mat matResults( 1, 20 * 20, CV_32F );
					for ( int i = 0; i < 20 * 20; ++i )
						matResults.at<float>( cv::Point( i, 0 ) ) = ( (int) ( resized.data[i] ) > tolerence ) ? 0 : 1; //on change la valeur des pixels en 0 ou 1 (comme pour le dataset)
					int f = knn_->predict( matResults );//resultat du predict avec le caractere courant
					std::cout << "result: " << chars[f] << std::endl;//affichage du caractere trouvé par le KNN
					if (f != -1)//-1 pour le bruit, pas encore geré
						letters.push_back( chars[f] );//remplissage de la chaine de caractere correspondante a la plaque
					if ( showResult )
					{
						cv::imshow( "Chars", resized );
						cv::waitKey();
					}
				}
				std::cout << "Found for this image : ";
				for ( auto it = letters.begin() ; it != letters.end() ; ++it )
					std::cout << *it;//affichage de la chaine de caractere trouvé correspondante a la plaque
				std::cout << std::endl;
			}
		}
		else
			std::cout << "No Plate found in this picture" << std::endl;
	}
}