Add report

This commit is contained in:
Mylloon 2022-05-10 12:57:25 +02:00
parent f3f61dcfba
commit e3803c59f9
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
5 changed files with 165 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

BIN
rapport/rapport.pdf Normal file

Binary file not shown.

165
rapport/rapport.tex Normal file
View file

@ -0,0 +1,165 @@
\documentclass{article}
\renewcommand{\familydefault}{\sfdefault} % police en "sans-serif"
\usepackage[T1]{fontenc} % encodage
\usepackage[french]{babel} % langue
\usepackage[hidelinks]{hyperref} % liens cliquable dans la table des matières
\usepackage{geometry} % change les dimensions de la page
\usepackage{graphicx} % images
\usepackage{subcaption} % images côtes à côtes
\geometry{ % définition taille pages
a4paper,
left=20mm,
top=20mm
}
\usepackage{minted} % intégration code
\usemintedstyle{emacs}
\title{Compression dimages avec quadtrees}
\author{\href{mailto:anri.kennel@etud.univ-paris8.fr}{Anri Kennel}\thanks{Numéro d'étudiant : 20010664}\, (L2-X)\\Algorithmique et structures de données 2 $\cdot$ Université Paris 8}
\date{Année universitaire 2021-2022}
\begin{document}
\maketitle
\tableofcontents
\clearpage
\section[Présentation]{Brève présentation}
J'ai réalisé le projet seul. Mon projet est de compresser une image avec une structure \textit{quadtree}.
\begin{figure}[!ht]
\centering
\begin{subfigure}{.49\textwidth}
\href{https://pxhere.com/en/photo/1409995}{\includegraphics[height=0.2\textheight]{images/not-compressed.png}}
\caption{Non compressé (3.6Mo)}
\end{subfigure}
\begin{subfigure}{.49\textwidth}
\centering
\includegraphics[height=0.2\textheight]{images/compressed-7.png}
\caption{Compressé / 7 (56ko)}
\end{subfigure}
\end{figure}
\subsection{Objectifs}
\begin{itemize}
\item Compiler facilement le programme
\item Réussir à compresser l'image
\item Code clair et commenté
\item Ne pas utiliser OpenCV
\end{itemize}
\section[Explications]{Explications de la réalisation}
\subsection*{Makefile}
La compilation est simple avec le \texttt{Makefile}. Il est possible de faire \texttt{make} pour compiler avec la SDL et \texttt{O3}. Il est aussi possible de faire \texttt{make dev} et ainsi compiler avec la SDL et les flags de développement :
\begin{itemize}
\item \texttt{Wall} et \texttt{Wextra} pour les warnings
\item \texttt{Wshadow} pour le nom des variables
\item \texttt{pedantic} pour la compilation
\item \texttt{g} pour Valgrind
\item \texttt{Wold-style-cast} et \texttt{Wsign-conversion} pour bien utiliser les casts
\end{itemize}
\subsection*{Libraries}
J'ai utilisé les librairies
\begin{itemize}
\item \texttt{fstream} pour vérifier empêcher d'écraser une image existante
\item \texttt{SDL\_image} pour utiliser \texttt{SDL\_Surface} de la \texttt{SDL}
\item \texttt{array} pour stocker et donner aux méthodes les 4 morceaux qui compose l'image quand divisé
\end{itemize}
\subsection*{Classe}
Ma classe \texttt{QuadTree} est déclarée dans \texttt{includes/quadtree.hpp} et définie
dans \texttt{src/quadtree.cpp}, elle contient :
\begin{itemize}
\item Une variable qui stocke la qualité de l'image (\texttt{niveau})
\item Une variable qui stocke la couleur majoritaire dans l'image (\texttt{couleur})
\item Une variable \texttt{std::pair} qui stocke les dimensions de l'image (\texttt{dimensions})
\item 4 variables représentant les enfants du noeud (\texttt{nord\_ouest}, \texttt{nord\_est}, \texttt{sud\_ouest}, \texttt{sud\_est})
\item Une variable qui définie si le noeud est final ou non (\texttt{final})
\item Une variable qui stocke le format utilisé par l'image (\texttt{format})
\newpage
\item Une méthode qui permet de calculer la couleur majoraitaire dans l'image (\texttt{calculeCouleur})
\item Une méthode qui permet savoir lors de l'exportation si elle est finie (\texttt{verificationEgalitee})
\item Une méthode qui permet de séparer en 4 l'image (\texttt{coupeEnQuatre})
\item Une méthode qui permet de rassembler 4 morceaux d'image en une seule (\texttt{colleQuatreImages})
\item Une méthode qui permet d'exporter la surface avec un certain niveau de compression (\texttt{image})
\end{itemize}
\vspace{10pt}
Cette classe permet de diviser récursivement l'image en 4 parts
et d'en extraire la couleur qui y est majoritaire dans chaque morceaux d'image.
\subsubsection*{Constructeur}
Dans le constructeur de ma classe, j'initialise \texttt{format} à \texttt{SDL\_PIXELFORMAT\_RGB888}
au lieu du format de mon image (\texttt{image->format}) car il y a un \textit{bug} dans
la méthode \texttt{colleQuatreImages} qui préserve mal les couleurs. \texttt{SDL\_PIXELFORMAT\_RGB888} rend donc l'image en noir et blanc.
\subsubsection*{Surfaces}
Je \href{https://wiki.libsdl.org/SDL_LockSurface}{verrouille et déverrouille ma surface} à chaque utilisation même si c'est probablement inutile mais ça m'évite de vérifier si \texttt{SDL\_MUSTLOCK} est égale à 0 à chaque fois.
\begin{center}\begin{minipage}{0.5\textwidth}
\begin{minted}[linenos]{cpp}
if(SDL_LockSurface(surface) == 0) {
/* ... */
SDL_UnlockSurface(surface);
}
\end{minted}
\end{minipage}\end{center}
\subsubsection*{Format des surfaces}
Toutes les surfaces que je crées ont le même format, ça m'évite d'utiliser les masks \href{https://wiki.libsdl.org/SDL_CreateRGBSurface#code_examples}{en fonction de} l'endian.
\subsubsection*{\texttt{calculeCouleur}}
Pour calculer la couleur dans \texttt{calculeCouleur} je fait une moyenne \texttt{RGBA} de tout les pixels de la surface.
\subsubsection*{\texttt{verificationEgalitee}}
Dans \texttt{verificationEgalitee} je regarde si tout les pixels \texttt{RGB} de la surface sont identiques (j'ignore le canal alpha).
\subsubsection*{\texttt{coupeEnQuatre}}
Quand je coupe en quatre mon image dans \texttt{coupeEnQuatre}, je commence par définir les coordonnées de mes 4 morceaux (ici \texttt{s} est la surface mère) :
\begin{center}\begin{minipage}{0.7\textwidth}
\begin{minted}[linenos]{cpp}
std::array<std::array<int, 4>, 4> coordonnes_quadrants;
coordonnes_quadrants[0] = {0 , 0 , s->w / 2, s->h / 2};
coordonnes_quadrants[1] = {0 , s->h / 2, s->w / 2, s->h };
coordonnes_quadrants[2] = {s->w / 2, 0 , s->w , s->h / 2};
coordonnes_quadrants[3] = {s->w / 2, s->h / 2, s->w , s->h };
\end{minted}
\end{minipage}\end{center}
Puis je créer tour à tour mes 4 surfaces qui je rajoute dans une \texttt{std::array}. Dans ses surfaces je vais
recopier pixel-par-pixel de la grande surface vers la plus petite (ici \texttt{x}/\texttt{y} varient respectivement en fonction de la largeur/longueur du morceau d'image):
\begin{center}\begin{minipage}{1\textwidth}
\begin{minted}[linenos]{cpp}
int x1 = x * nouvelle_image->format->BytesPerPixel,
y1 = y * nouvelle_image->pitch,
x2 = (coordonnes_quadrants[i][0] + x) * s->format->BytesPerPixel,
y2 = (coordonnes_quadrants[i][1] + y) * s->pitch;
*reinterpret_cast<Uint32 *>(static_cast<Uint8 *>(nouvelle_image->pixels) + y1 + x1) =
*reinterpret_cast<Uint32 *>(static_cast<Uint8 *>(s->pixels) + y2 + x2);
\end{minted}
\end{minipage}\end{center}
\subsubsection*{\texttt{colleQuatreImages}}
Quand je rassemble mon image dans \texttt{colleQuatreImages}, je commence par récupérer les dimensions de
mon image originale en regardant des morceaux en diagonale (sur l'image je compare soit 1 et 4, soit 2 et 3).
\begin{figure}[!ht]
\centering
\includegraphics[height=0.2\textheight]{images/image_coupe_en_4.png}
\end{figure}
\\Si les dimensions des 2 morceaux sont différents alors je prend la plus grande dimensions \texttt{- 1}.
Une fois les dimensions récupérer, je copie pixel-par-pixel les morceaux sur ma grande surface, comme dans la méthode \texttt{coupeEnQuatre}. Je libère les morceaux de la mémoire une fois rassemblé.
\section{Ajouts}
\begin{itemize}
\item Possibilité de préciser le niveau de compresser (0 très compressé et 10 pas compressé)
\item Utilisation de la SDL pour gérer l'image
\end{itemize}
\subsection{Piste d'amélioration}
Je n'ai malheureusement pas réussi à garder la couleur lorsque je compresse l'image, j'aimerais réussir à rendre ça fonctionnelle.
\end{document}