Commits

zoolonly  committed 3b60055

Init and raw files added.

  • Participants

Comments (0)

Files changed (6)

File sources/CMakeLists-etudiant.txt

+cmake_minimum_required(VERSION 2.8)
+
+project(NomDuProjet)
+
+FILE(GLOB folder_source src/*)
+
+#Comment chercher OpenCV ?
+
+# create the project
+ADD_EXECUTABLE(mon_exe ${folder_source})
+   
+# link opencv libraries 
+TARGET_LINK_LIBRARIES(mon_exe ....)

File sources/data/doc.png

Added
New image

File sources/data/docOld.png

Added
New image

File sources/src/main.cpp

+#include <cv.h>
+#include <highgui.h>
+#include <iostream>
+
+cv::Mat faireOtsu();
+cv::Mat faireGlobale (int thd);
+void faireAdaptive();
+
+int main ()
+{
+    cv::Mat image = cv::imread("../data/doc.png");
+
+    cv::namedWindow("My Image");
+
+    cv::imshow("My Image", image);
+
+    cv::waitKey(5000);
+    
+
+    faireAdaptive();
+    faireGlobale(50);
+    faireOtsu();
+
+   /// extraction des charactère :
+    // [Q4]
+    
+    cv::Mat g_gray = faireOtsu();
+    cv::imwrite("resBin.png",g_gray);
+        
+    std::vector<cv::Vec4i> hierarchy;
+    
+    std::vector<std::vector < cv::Point > > contours;
+
+    
+    //// Les contours (suite de points)
+    cv::findContours(g_gray, contours, hierarchy,
+                     CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE );
+    
+    //// Les convex hulls (suite de points)    
+    std::vector< std::vector <cv::Point> >hull( contours.size() );
+    for( int i = 0; i < contours.size(); i++ )
+    {  cv::convexHull( cv::Mat(contours[i]), hull[i], false ); }
+    
+    //// Les Boite Englobantes    
+    std::vector< std::vector <cv::Point> >bboxes;
+    for( int i = 0; i < contours.size(); i++ )
+    {  
+        std::vector <cv::Point> bbox;
+        cv::Rect r = cv::boundingRect(cv::Mat(contours[i]));
+        
+        cv::Point p (r.x, r.y);
+        bbox.push_back(p);
+        
+        cv::Point p2 (r.x+r.width, r.y);
+        bbox.push_back(p2);
+        
+        cv::Point p3 (r.x+r.width, r.y+r.height);
+        bbox.push_back(p3);
+        
+        cv::Point p4 (r.x, r.y+r.height);
+        bbox.push_back(p4);
+        
+        bboxes.push_back(bbox);
+    }
+    ///[fin Q4]
+
+    
+    /******
+     AFFICHAGE
+     */
+    cv::Mat dst = cv::Mat::zeros(image.rows, image.cols, CV_8UC3);
+    
+    cv::Mat_<cv::Vec3b>::const_iterator it=  image.begin<cv::Vec3b>();
+    cv::Mat_<cv::Vec3b>::const_iterator itend= image.end<cv::Vec3b>();
+    cv::Mat_<cv::Vec3b>::iterator itout=
+    dst.begin<cv::Vec3b>();
+    // for each pixel
+    for ( ; it!= itend; ++it, ++itout) {
+        // process each pixel ---------------------
+        cv::Vec3b &out = *itout;
+        out[0]= 255;
+        out[1]= 255;
+        out[2]= 255;
+        // end of pixel processing ----------------
+    }
+
+    
+    for( int idx = 0; idx < contours.size(); idx++ )
+    {
+        cv::Scalar color = cv::Scalar( 0, 0, 0);
+        
+        /// Text 
+        if(hierarchy[idx][0] > 0 || hierarchy[idx][1] > 0 ) {
+            color = cv::Scalar( 0, 0, 0);
+            
+        }
+                
+        /// (nested contour = holes on ne les dessine pas en noir)
+        if(hierarchy[idx][3] > 0) {
+           // color = cv::Scalar( 0, 0, 255);
+             color = cv::Scalar( 255, 255, 255);
+        }
+        
+        cv::drawContours( dst, contours, idx, color, CV_FILLED, 8, hierarchy);
+//        cv::drawContours( dst, bboxes, idx, color, CV_FILLED, 8, hierarchy);
+//        cv::drawContours( dst, hull, idx, color, CV_FILLED, 8, hierarchy);
+    }
+    
+    cv::namedWindow( "Chars", 1 );
+    cv::imshow( "Chars", dst );
+    cv::waitKey();
+    
+    cv::imwrite("dst2.png",dst);
+
+    
+    return 0;
+}
+
+
+
+cv::Mat faireOtsu() {
+
+    cv::Mat image = cv::imread("../data/doc.png");
+    
+    cv::Mat g_gray = cv::Mat::zeros(image.rows, image.cols, CV_8UC1);
+    
+    cv::cvtColor( image, g_gray, CV_BGR2GRAY );
+    
+    cv::threshold( g_gray, g_gray, 0, 255, CV_THRESH_OTSU | CV_THRESH_BINARY_INV );
+    
+    cv::imshow("Resultat Otsu", g_gray);
+    
+    cv::waitKey(5000);
+    return g_gray;
+}
+
+
+cv::Mat faireGlobale (int thd)
+{
+    cv::Mat image = cv::imread("../data/doc.png");
+    
+    cv::Mat g_gray = cv::Mat::zeros(image.rows, image.cols, CV_8UC1);
+    
+    cv::cvtColor( image, g_gray, CV_BGR2GRAY );
+    
+    cv::threshold( g_gray, g_gray, thd, 255, CV_THRESH_BINARY_INV );
+    
+    cv::imshow("Res Global", g_gray);
+    
+    cv::waitKey(5000);
+    
+    return g_gray;
+}
+
+
+void faireAdaptive() {
+    
+    cv::Mat image = cv::imread("../data/doc.png");
+    
+    cv::Mat g_gray = cv::Mat::zeros(image.rows, image.cols, CV_8UC1);
+    
+    cv::cvtColor( image, g_gray, CV_BGR2GRAY );
+    
+    
+    cv::adaptiveThreshold( g_gray, g_gray,255, CV_ADAPTIVE_THRESH_MEAN_C ,CV_THRESH_BINARY_INV, 23,  25);
+    
+    cv::imshow("Resultat Adaptative", g_gray);
+    
+    cv::waitKey(5000);
+}

File sujet/opencv-logo2.png

Added
New image

File sujet/sujet.tex

+\documentclass[11pt]{article}
+
+\usepackage[utf8]{inputenc}
+\usepackage[francais]{babel}
+\usepackage{color}
+\usepackage{listings}
+\usepackage{graphicx}
+
+\lstset{ 
+        basicstyle=\tt\footnotesize, 
+        identifierstyle=\tt\color{black},   
+        %commentstyle=\tt\color{gray}, 
+        keywordstyle=\color{blue}, 
+        stringstyle=\color{red}, 
+        language=C++
+        } 
+
+
+\begin{document}
+
+\title{Traitement d’images, C++, et le modèle de conception Strategy \\
+	\includegraphics[width=25px]{opencv-logo2.png}\\
+	\small{\textit{TM 1 : }
+	à rendre pour le 17/10/2011}
+	}
+\author{Rabeux Vincent}
+\date{}
+\maketitle
+
+
+
+\paragraph{}
+L’objectif du modèle de conception « Strategy » est d’encapsuler  un algorithme dans une classe. Ainsi, il devient facile de remplacer un algorithme par un autre dans une chaîne de traitements complexes.  Ce modèle de conception est très simple : il s’articule sur une classe mère qui doit décrire ce qu’un algorithme est capable de faire. Les différentes implémentations de l’algorithme viennent se greffer par héritage sur la classe mère.
+
+
+\begin{lstlisting} [language=C++, caption={Hierarchie de classes formant la strategy},label=stratPiloter] 
+class  Piloter {
+public :
+	virtual void  piloter()  =0 ;
+};
+
+class PiloterAvion {
+public :
+	PiloterAvion (Avion &a)
+	void  piloter() ;
+private :
+	Avion &m_a;
+};
+
+class PiloterF1 {
+public :
+	PiloterF1 (F1 &f)
+	void  piloter() ;
+private :
+	F1 &m_f1;
+};
+\end{lstlisting}
+
+\paragraph{}
+Avec une stratégie il devient possible d’injecter  à une classe \textit{Personne} la façon dont elle doit piloter un véhicule :
+
+\begin{lstlisting} [language=C++, caption={Utilisation de la strategie},label=stratPiloterUse] 
+class Personne  {
+  void rentrerMaison (Piloter *p = NULL) {
+    if(p == NULL)
+	// rentre en bus
+	else {
+	  p->piloter() ;
+	}
+    }
+};
+.....
+Avion v ;
+Piloter  * p = new  PiloterAvion(v) ;
+Personne toto ;
+toto.rentrerMaison(p) ;
+......
+F1 v ;
+Piloter  * p = new  PiloterF1 (f1) ;
+Personne toto ;
+toto.rentrerMaison(p) ;
+\end{lstlisting}
+
+
+\paragraph{}
+Dans ce TM vous devrez faire des algorithmes de binarisation de documents (mettre les pixels du fond en noir et ceux d’encre en blanc) :
+\begin{enumerate}
+	\item Avec un seuil fixé par le développer (en dur dans le code).
+	\item En utilisant la méthode Otsu.
+	\item En utilisant une méthode adaptative.
+\end{enumerate}
+
+\paragraph{}
+Ne vous inquiétez pas, on vous donne des exemples de code, pour que vous puissiez vous concentrer sur le C++ ! De plus, Pour nous aider à manipuler les images nous allons utiliser OpenCV ! 
+OpenCV est une des librairies d’images les plus utilisées. http://fr.wikipedia.org/wiki/OpenCV
+
+\paragraph{}
+Pour ce TM vous avez le choix entre \textbf{Linux}, \textbf{Windows} et \textbf{MAC OS X}. 
+(Je vous conseil de faire ce TM avec Windows \textbf{ET} Linux) !
+
+\paragraph{}
+Vous avez le droit de vous mettre seul, par binômes ou par trinômes. Il faudra faire l'exercice sur autant de plateformes que de membres présents dans votre groupe (1, 2 ou 3). 
+\paragraph{Exemple :} 
+\begin{itemize}
+	\item Binome : John et Harry ont choisit de faire le TM sur Linux et Windows.
+	\item Monome : Nick a choisit de faire le TM sur Windows.
+	\item Trinome : Tim  Steve Scott ont choisi de faire le TM sur Linux, BSD et Mac os x. 
+\end{itemize}
+
+%	\paragraph{Question 0 :}
+%	Votre travail doit être \textit{versioné}. Malheureusement (pour vous), les forges logiciel tels que google, propose vos source de fa\c con publique. Il deviens possible de copier le travail de vos camarades ce qui est très ennuyeux. Pour contourner ce problème, vous aller créer des projets privés sur la forge de l'IUT : 
+%	\subparagraph{Création du projet Redmine :}
+%	\begin{itemize}
+%		\item Aller sur le site : http://info-forge.iut.u-bordeaux1.fr/
+%		\item Connectez vous à l'aide de votre compte bordeaux1.
+%		\item Clicker sur \textit{Redmine (Gestion Projet)}
+%		\item Clicker sur \textit{Se connectez} et remplissez les champs qui vous sont demandé. Choisisser le même login / mot de passe que votre compte bordeaux1.
+%		\item Aller sur la page \textit{Projets}
+%		\item Aller sur le projet [2011]-LP\_DAWIN\_Cpp\_Init\_OpenCV.
+%		\item Dans l'onglet \textit{Apre\c cu} clicker sur \textit{Nouveau sous-projet}.
+%		\item Nom = [Année]-DAWIN-login1-CppOpencv. Exemple : 2011-DAWIN-vrabeux-CppOpencv 
+%		\item Description = 1 ou 2 phrases
+%		\item Identifiant = Année-dawin-login1-cppopencv. Exemple : 2011-dawin-vrabeux-cppopencv.
+%		\item NE PAS COCHER \textit{Public}
+%		\item Dans la partie module vérifié que \textit{Dépôt de sources} est bien coché.
+%		\item \textit{Valider}.
+%	\end{itemize}
+%	\subparagraph{Création du dépôt de source :}
+%	[Attendre 15 minute pour la création des dépôts.] Il faut maintenant télécharger une première version des sources :
+%	\begin{itemize}
+%		 \item Configurer hg : http://www.selenic.com/mercurial/hgrc.5.html
+%		 \item Cloner le dépôt :
+%		\begin{lstlisting} 
+%hg clone  http://info-forge.iut.u-bordeaux1.fr/hg/identifiant_du_projet
+%		\end{lstlisting} 
+%		Par example :
+%		\begin{lstlisting} 
+%hg clone  http://info-forge.iut.u-bordeaux1.fr/hg/2011-dawin-vrabeux-cppopencv
+%		\end{lstlisting}
+%		\item Créer un fichier README.txt, ajouter le au projet, commuter et pusher :
+%		\begin{lstlisting} 
+%echo 'Description : ... ' > README.txt
+%hg add README.txt
+%hg commit
+%hg push
+%		\end{lstlisting}
+%	\subparagraph{Ajout des membres : }
+%		Sur redmine ajouter en tant que membres (Onglet \textit{Configuration}) les membres de votre projet (qui doivent s'inscrire avant).
+%		
+%		
+%		
+%	\end{itemize}
+\paragraph{Question 0 :} Création du projet Mercurial.
+	\begin{itemize}
+		\item (Pour chaque membre du projet) \\ Installer Mercurial et configurer le : \\ http://www.selenic.com/mercurial/hgrc.5.html.
+		\item Créer un projet \textbf{PRIVÉ} sur Bitbucket :  https://bitbucket.org/. \\ Le nom du projet doit être :
+	2011-dawin-cppopencv-loginIUT1-loginIUT2.
+
+		\item	 Ajouter un fichier README.txt avec la description du projet. 
+		\item Ajouter le fichier au dépôt (hg add), commiter (hg commit), pusher, (hg push).
+		\item Envoyer moi l'url du projet.
+		\item Récupérer le projet déjà existant (avec les sources de ce pdf) : 
+		\begin{lstlisting}
+hg clone https://bitbucket.org/vrabeux/2011-dawin-cppopencv-vrabeux
+		\end{lstlisting}
+		\item Ajouter les membres de votre binôme / trinôme au projet si besoin.
+		\item Vous pouvez commencer à travailler. Répondez à la question 1 dans un fichier TXT ou LaTEX, dans le dépôt.
+	 \end{itemize}
+
+
+
+	\paragraph{Question 1 :}
+		 Comment installer OpenCV sur votre plateforme ? 
+	\paragraph{Question 2 :}
+		   Comment utiliser CMake pour  compiler un programme utilisant OpenCV ? Par exemple le programme suivant : 
+\begin{lstlisting} [language=C++, caption={Exemple programme OpenCV},label=mainEX] 
+#include <cv.h>
+#include <highgui.h>
+
+int main ()
+{
+    cv::Mat image = cv::imread("../data/doc.png");
+
+    cv::namedWindow("My Image");
+
+    cv::imshow("My Image", image);
+
+    cv::waitKey(5000);
+
+    return 0;
+}
+\end{lstlisting}
+	\paragraph{Question 3 :}
+		Réaliser la stratégie d’algorithmes avec OpenCV. Le but est donc de 'refactoriser' le code \ref{todo}. Afin d'avoir une classe pour chaque algorithme de binarisation.  Il ne doit plus rester une seule ligne dupliquée.
+		
+\begin{lstlisting} [language=C++, caption={Le programme à transformer},label=todo] 		
+#include <cv.h>
+#include <highgui.h>
+
+
+void faireOtsu();
+void faireGlobale (int thd);
+void faireAdaptive();
+
+int main ()
+{
+    cv::Mat image = cv::imread("../data/doc.png");
+
+    cv::namedWindow("My Image");
+
+    cv::imshow("My Image", image);
+
+    cv::waitKey(5000);
+    
+
+    faireAdaptive();
+    faireGlobale(50);
+    faireOtsu();
+
+
+    return 0;
+}
+
+
+
+void faireOtsu() {
+
+    cv::Mat image = cv::imread("../data/doc.png");
+    
+    cv::Mat g_gray = cv::Mat::zeros(image.rows, image.cols, CV_8UC1);
+    
+    cv::cvtColor( image, g_gray, CV_BGR2GRAY );
+    
+    cv::threshold( g_gray, g_gray, 0, 255, CV_THRESH_OTSU );
+    
+    cv::imshow("Resultat Otsu", g_gray);
+    
+    cv::waitKey(5000);
+}
+
+
+void faireGlobale (int thd)
+{
+    cv::Mat image = cv::imread("../data/doc.png");
+    
+    cv::Mat g_gray = cv::Mat::zeros(image.rows, image.cols, CV_8UC1);
+    
+    cv::cvtColor( image, g_gray, CV_BGR2GRAY );
+    
+    cv::threshold( g_gray, g_gray, thd, 255, CV_THRESH_BINARY );
+    
+    cv::imshow("Res Global", g_gray);
+    
+    cv::waitKey(5000);
+}
+
+
+void faireAdaptive() {
+    
+    cv::Mat image = cv::imread("../data/doc.png");
+    
+    cv::Mat g_gray = cv::Mat::zeros(image.rows, image.cols, CV_8UC1);
+    
+    cv::cvtColor( image, g_gray, CV_BGR2GRAY );
+    
+    
+    cv::adaptiveThreshold( g_gray, g_gray,255, CV_ADAPTIVE_THRESH_MEAN_C ,CV_THRESH_BINARY, 23,  25);
+    
+    cv::imshow("Resultat Adaptative", g_gray);
+    
+    cv::waitKey(5000);
+}
+		
+\end{lstlisting}
+		
+		
+	\paragraph{Question 4 : }
+		A partir d'une image binarisée,  il est possible d'extraire toutes les composantes (lettres noires) de l'image.  Comme vous pouvez le voir sur le code \ref{q4} il y a plusieurs fa\c con d'extraire les composantes d'une image binarisée : 
+		\begin{itemize}
+			\item Les contours : juste une suite de points.
+			\item Les Convex Hulls : http://en.wikipedia.org/wiki/Convex\_hull.
+			\item Les boites englobantes : des rectangles.
+		\end{itemize}
+		Toujours grâce au modèle de conception 'Strategy', factoriser le code \ref{q4} afin d'avoir une méthode d'extraction par classe.
+		
+		 \textbf{Attention}, une méthode d'extraction, à besoin d'une méthode de binarisation ... .
+
+\begin{lstlisting} [language=C++, caption={Extraction de composantes},label=q4] 		
+		
+    /// extraction des caracteres :
+    // [Q4]
+    
+    cv::Mat g_gray = faireOtsu();
+        
+    std::vector<cv::Vec4i> hierarchy;
+    
+    std::vector<std::vector < cv::Point > > contours;
+
+    
+    //// Les contours (suite de points)
+    cv::findContours(g_gray, contours, hierarchy,
+                     CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE );
+    
+    //// Les convex hulls (suite de points)    
+    std::vector< std::vector <cv::Point> >hull( contours.size() );
+    for( int i = 0; i < contours.size(); i++ )
+    {  cv::convexHull( cv::Mat(contours[i]), hull[i], false ); }
+    
+    //// Les Boite Englobantes    
+    std::vector< std::vector <cv::Point> >bboxes;
+    for( int i = 0; i < contours.size(); i++ )
+    {  
+        std::vector <cv::Point> bbox;
+        cv::Rect r = cv::boundingRect(cv::Mat(contours[i]));
+        
+        cv::Point p (r.x, r.y);
+        bbox.push_back(p);
+        
+        cv::Point p2 (r.x+r.width, r.y);
+        bbox.push_back(p2);
+        
+        cv::Point p3 (r.x+r.width, r.y+r.height);
+        bbox.push_back(p3);
+        
+        cv::Point p4 (r.x, r.y+r.height);
+        bbox.push_back(p4);
+        
+        bboxes.push_back(bbox);
+    }
+    ///[fin Q4]
+\end{lstlisting}
+		
+	
+		\paragraph{Question 5 : }
+			Créer une classe Affichage, pour afficher les composantes. Inspirer vous du code 
+			
+\begin{lstlisting} [language=C++, caption={Affichage des composantes},label=q5] 	
+............
+// RAPPEL :
+std::vector<cv::Vec4i> hierarchy;
+    
+    std::vector<std::vector < cv::Point > > contours;
+
+    
+    //// Les contours (suite de points)
+    cv::findContours(g_gray, contours, hierarchy,
+                     CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE );
+............
+				
+ /******
+     AFFICHAGE
+     */
+    cv::Mat dst = cv::Mat::zeros(image.rows, image.cols, CV_8UC3);
+    
+    cv::Mat_<cv::Vec3b>::const_iterator it=  image.begin<cv::Vec3b>();
+    cv::Mat_<cv::Vec3b>::const_iterator itend= image.end<cv::Vec3b>();
+    cv::Mat_<cv::Vec3b>::iterator itout=
+    dst.begin<cv::Vec3b>();
+    // for each pixel
+    for ( ; it!= itend; ++it, ++itout) {
+        // process each pixel ---------------------
+        cv::Vec3b &out = *itout;
+        out[0]= 255;
+        out[1]= 255;
+        out[2]= 255;
+        // end of pixel processing ----------------
+    }
+
+    
+    for( int idx = 0; idx < contours.size(); idx++ )
+    {
+        cv::Scalar color = cv::Scalar( 0, 0, 0);
+        
+        /// Text 
+        if(hierarchy[idx][0] > 0 || hierarchy[idx][1] > 0 ) {
+            color = cv::Scalar( 0, 0, 0);
+        }
+                
+        /// (nested contour = holes)
+        if(hierarchy[idx][3] > 0) {
+            color = cv::Scalar( 0, 0, 255);
+        }
+        
+        cv::drawContours( dst, contours, idx, color, CV_FILLED, 8, hierarchy);
+//        cv::drawContours( dst, bboxes, idx, color, CV_FILLED, 8, hierarchy);
+//        cv::drawContours( dst, hull, idx, color, CV_FILLED, 8, hierarchy);
+    }
+    
+    cv::namedWindow( "Hull demo", 1 );
+    cv::imshow( "Hull demo", dst );
+    cv::waitKey();
+    
+    cv::imwrite("dst2.png",dst);
+\end{lstlisting}
+		
+
+
+
+
+
+
+
+\end{document}