<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>http://os-vps418.infomaniak.ch:1250/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fdufaure</id>
	<title>Wiki du LAMA (UMR 5127) - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="http://os-vps418.infomaniak.ch:1250/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fdufaure"/>
	<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php/Sp%C3%A9cial:Contributions/Fdufaure"/>
	<updated>2026-04-16T03:02:19Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.39.4</generator>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12468</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12468"/>
		<updated>2020-05-17T19:34:19Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque [[https://numpy.org/ Numpy]] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page, je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet ([[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images ici]]) pour bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles étaient les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bons rendus. Néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devenait problématique si on voulait faire un transfert de couleurs entre 2 images avec un grand nombre de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calcul ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisés avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce nombre est une valeur de référence suffisante pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsque l&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct.&amp;lt;br/&amp;gt;Néanmoins dès que l&#039;on va vouloir prendre des images de résolution plus importante (HD ou même 4K), le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables de faire un milliard de calculs par seconde mais &amp;lt;code&amp;gt;Python&amp;lt;/code&amp;gt; est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau).&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme, nous utilisons de nombreux tableaux afin de stocker toutes les variables dont nous avons besoin, et la bibliothèque &amp;lt;code&amp;gt;Numpy&amp;lt;/code&amp;gt; possède des tableaux bien plus compacts. De plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire une boucle pour appliquer ces calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait, on gagne énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très complète et si vous voulez plus d&#039;informations je vous conseille de vous rendre sur la page officielle [[https://numpy.org/ Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
Ces tests ont eux aussi été réalisés avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de &amp;lt;code&amp;gt;Numpy&amp;lt;/code&amp;gt; permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition pour avoir un meilleur résultat en gardant un temps d’exécution correct.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; / &#039;&#039;&#039; Nombres de tours dans le programme -&amp;gt;&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100&lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Plus on augmente la taille de l&#039;image et le nombre de tour, plus le temps d&#039;exécution devient important. En effet, les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de haute qualité, de regrouper plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrait d&#039;avoir moins de pixels à traiter sans pour autant avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nu.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet, l&#039;espace RVB est très bien mais il correspond aux écrans et non à l’œil humain, tandis que l&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L*a*b CIE 1976]] a pour but de mieux approximer la réalité.&lt;br /&gt;
Cet espace, autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage RVB -&amp;gt; Lab ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtient avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composante de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleur de la même manière que dans l&#039;espace RVB. &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage Lab -&amp;gt; RVB ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permettent d&#039;avoir dans certains cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins, on peut voir qu&#039;on à plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d’exécution du programme dans l&#039;espace CIELAB est plus long.&amp;lt;br/&amp;gt;La différence se fait durant les calculs pour les changements d&#039;espace; le programme doit en effet faire des étapes supplémentaires sur tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mis mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers paramètres ne sont pas obligatoirement au même format mais doivent tout deux être des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12467</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12467"/>
		<updated>2020-05-17T19:27:00Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque [[https://numpy.org/ Numpy]] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page, je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet ([[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images ici]]) pour bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles étaient les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bons rendus. Néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devenait problématique si on voulait faire un transfert de couleurs entre 2 images avec un grand nombre de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calcul ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisés avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce nombre est une valeur de référence suffisante pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsque l&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct.&amp;lt;br/&amp;gt;Néanmoins dès que l&#039;on va vouloir prendre des images de résolution plus importante (HD ou même 4K), le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables de faire un milliard de calculs par seconde mais &amp;lt;code&amp;gt;Python&amp;lt;/code&amp;gt; est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau).&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme, nous utilisons de nombreux tableaux afin de stocker toutes les variables dont nous avons besoin, et la bibliothèque &amp;lt;code&amp;gt;Numpy&amp;lt;/code&amp;gt; possède des tableaux bien plus compacts. De plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire une boucle pour appliquer ces calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait, on gagne énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très complète et si vous voulez plus d&#039;informations je vous conseille de vous rendre sur la page officielle [[https://numpy.org/ Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
Ces tests ont eux aussi été réalisés avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de &amp;lt;code&amp;gt;Numpy&amp;lt;/code&amp;gt; permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition pour avoir un meilleur résultat en gardant un temps d’exécution correct.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
| ||!colspan=&amp;quot;5&amp;quot;| &#039;&#039;&#039; Nombres de tours dans le programme&#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100&lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Plus on augmente la taille de l&#039;image et le nombre de tour, plus le temps d&#039;exécution devient important. En effet, les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de haute qualité, de regrouper plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrait d&#039;avoir moins de pixels à traiter sans pour autant avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nu.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet, l&#039;espace RVB est très bien mais il correspond aux écrans et non à l’œil humain, tandis que l&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L*a*b CIE 1976]] a pour but de mieux approximer la réalité.&lt;br /&gt;
Cet espace, autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage RVB -&amp;gt; Lab ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtient avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composante de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleur de la même manière que dans l&#039;espace RVB. &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage Lab -&amp;gt; RVB ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permettent d&#039;avoir dans certains cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins, on peut voir qu&#039;on à plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d’exécution du programme dans l&#039;espace CIELAB est plus long.&amp;lt;br/&amp;gt;La différence se fait durant les calculs pour les changements d&#039;espace; le programme doit en effet faire des étapes supplémentaires sur tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mis mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers paramètres ne sont pas obligatoirement au même format mais doivent tout deux être des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12466</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12466"/>
		<updated>2020-05-17T18:48:43Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque [[https://numpy.org/ Numpy]] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page, je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet ([[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images ici]]) pour bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles étaient les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bons rendus. Néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devenait problématique si on voulait faire un transfert de couleurs entre 2 images avec un grand nombre de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calcul ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisés avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce nombre est une valeur de référence suffisante pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsque l&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct.&amp;lt;br/&amp;gt;Néanmoins dès que l&#039;on va vouloir prendre des images de résolution plus importante (HD ou même 4K), le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables de faire un milliard de calculs par seconde mais &amp;lt;code&amp;gt;Python&amp;lt;/code&amp;gt; est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau).&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme, nous utilisons de nombreux tableaux afin de stocker toutes les variables dont nous avons besoin, et la bibliothèque &amp;lt;code&amp;gt;Numpy&amp;lt;/code&amp;gt; possède des tableaux bien plus compacts, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire une boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait, on gagne énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très complète et si vous voulez plus d&#039;informations je vous conseille de vous rendre sur la page officielle [[https://numpy.org/ Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus, ces tests ont été réalisés avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de &amp;lt;code&amp;gt;Numpy&amp;lt;/code&amp;gt; permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correct.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nombres de tours dans le programme&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Plus on augmente la taille de l&#039;image et le nombre de tour, plus le temps d&#039;exécution devient important. En effet, les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de haute qualité, de regrouper plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nu.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet, l&#039;espace RVB est très bien mais il correspond aux écrans et non à l’œil humain, tandis que cet espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage. &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtient avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composante de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleur de la même manière que dans l&#039;espace RVB. &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permettent d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins, on peut voir qu&#039;on à plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d’exécution du programme dans l&#039;espace CIELAB est plus long.&amp;lt;br/&amp;gt;La différence se fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mis mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers paramètres ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction.&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12454</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12454"/>
		<updated>2020-05-17T18:08:21Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque [[https://numpy.org/ Numpy]] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page, je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet ([[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images ici]]) pour bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles étaient les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bons rendus. Néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devenait problématique si on voulait faire un transfert de couleurs entre 2 images avec un grand nombre de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calcul ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisés avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce nombre est une valeur de référence suffisante pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsque l&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct.&amp;lt;br/&amp;gt;Néanmoins dès que l&#039;on va vouloir prendre des images de résolution plus importante (HD ou même 4K), le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables de faire un milliard de calculs par seconde mais &amp;lt;code&amp;gt;Python&amp;lt;/code&amp;gt; est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau).&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme, nous utilisons de nombreux tableaux afin de stocker toutes les variables dont nous avons besoin, et la bibliothèque &amp;lt;code&amp;gt;Numpy&amp;lt;/code&amp;gt; possède des tableaux bien plus compacts, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire une boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait, on gagne énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très complète et si vous voulez plus d&#039;informations je vous conseille de vous rendre sur la page officielle [[https://numpy.org/ Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus, ces tests ont été réalisés avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de &amp;lt;code&amp;gt;Numpy&amp;lt;/code&amp;gt; permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correct.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nombres de tours dans le programme&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, de regrouper plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nu.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cet espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permettent d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins on peut voir qu&#039;on à plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d’exécution du programme dans l&#039;espace CIELAB est plus long.&amp;lt;br/&amp;gt;La différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mis mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers fichiers ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12453</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12453"/>
		<updated>2020-05-17T18:05:30Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque [[https://numpy.org/ Numpy]] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page, je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet ([[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images ici]]) pour bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles étaient les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bons rendus. Néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devenait problématique si on voulait faire un transfert de couleurs entre 2 images avec un grand nombre de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calcul ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisés avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce nombre est une valeur de référence suffisante pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsque l&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct.&amp;lt;br/&amp;gt;Néanmoins dès que l&#039;on va vouloir prendre des images de résolution plus importante (HD ou même 4K), le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables de faire un milliard de calculs par seconde mais &amp;lt;code&amp;gt;Python&amp;lt;/code&amp;gt; est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau).&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme, nous utilisons de nombreux tableaux afin de stocker toutes les variables dont nous avons besoin, et la bibliothèque &amp;lt;code&amp;gt;Numpy&amp;lt;/code&amp;gt; possède des tableaux bien plus compacts, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire une boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait, on gagne énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très complète et si vous voulez plus d&#039;informations je vous conseille de vous rendre sur la page officielle [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nombres de tours dans le programme&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, de regrouper plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nu.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cet espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permettent d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins on peut voir qu&#039;on à plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d’exécution du programme dans l&#039;espace CIELAB est plus long.&amp;lt;br/&amp;gt;La différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mis mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers fichiers ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12311</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12311"/>
		<updated>2020-05-15T09:44:09Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque [[https://numpy.org/ Numpy]] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page, je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet ([[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images ici]]) pour bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles étaient les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bons rendus. Néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devenait problématique si on voulait faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calcul de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisés avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsque l&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct.&amp;lt;br/&amp;gt;Néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K), le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables de faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compacts, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire une boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait, on gagne énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseille de vous rendre sur la page officielle [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nombres de tours dans le programme&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, de regrouper plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nu.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cet espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permettent d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins on peut voir qu&#039;on à plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d’exécution du programme dans l&#039;espace CIELAB est plus long.&amp;lt;br/&amp;gt;La différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mis mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers fichiers ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12309</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12309"/>
		<updated>2020-05-15T09:06:11Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque [[https://numpy.org/ Numpy]] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet ([[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images ici]]) pour bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles étaient les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bons rendus. Néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devenait problématique si on voulait faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calcul de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisés avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsque l&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct.&amp;lt;br/&amp;gt;Néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K), le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables de faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compacts, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire une boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait, on gagne énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseille de vous rendre sur la page officielle [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nombres de tours dans le programme&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, de regrouper plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nu.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cet espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permettent d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins on peut voir qu&#039;on à plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d’exécution du programme dans l&#039;espace CIELAB est plus long.&amp;lt;br/&amp;gt;La différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mis mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers fichiers ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12308</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12308"/>
		<updated>2020-05-15T08:58:24Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque [[https://numpy.org/ Numpy]] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet ([[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images ici]]) pour bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles étaient les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calcul de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsqu&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct, néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nombres de tours dans le programme&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins on peut voir qu&#039;on a plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d&#039;execution du programme dans l&#039;espace CIELAB est plus long, la différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur le tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mit mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers fichiers ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12307</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12307"/>
		<updated>2020-05-15T08:57:52Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque [[https://numpy.org/ Numpy]] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet ([[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images ici]]) pour bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles étaient les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsqu&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct, néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nombres de tours dans le programme&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins on peut voir qu&#039;on a plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d&#039;execution du programme dans l&#039;espace CIELAB est plus long, la différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur le tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mit mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers fichiers ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12306</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12306"/>
		<updated>2020-05-15T08:57:26Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque [[https://numpy.org/ Numpy]] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet ([[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images ici]]) pour bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsqu&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct, néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nombres de tours dans le programme&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins on peut voir qu&#039;on a plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d&#039;execution du programme dans l&#039;espace CIELAB est plus long, la différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur le tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mit mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers fichiers ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12305</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12305"/>
		<updated>2020-05-15T08:56:29Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque [[https://numpy.org/ Numpy]] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsqu&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct, néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nombres de tours dans le programme&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins on peut voir qu&#039;on a plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d&#039;execution du programme dans l&#039;espace CIELAB est plus long, la différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur le tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mit mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers fichiers ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12303</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12303"/>
		<updated>2020-05-14T17:23:37Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque https://numpy.org/ Numpy] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsqu&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct, néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nombres de tours dans le programme&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins on peut voir qu&#039;on a plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d&#039;execution du programme dans l&#039;espace CIELAB est plus long, la différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur le tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mit mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers fichiers ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12302</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12302"/>
		<updated>2020-05-14T17:23:22Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque https://numpy.org/ Numpy] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsqu&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct, néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nombres tours dans le programme&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins on peut voir qu&#039;on a plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d&#039;execution du programme dans l&#039;espace CIELAB est plus long, la différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur le tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mit mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers fichiers ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12272</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12272"/>
		<updated>2020-05-13T13:55:50Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque https://numpy.org/ Numpy] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsqu&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct, néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&amp;lt;br/&amp;gt;&lt;br /&gt;
Néanmoins on peut voir qu&#039;on a plus de mal a distinguer le relief sur la seconde image.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d&#039;execution du programme dans l&#039;espace CIELAB est plus long, la différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur le tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mit mes 2 programmes sur GitHub [https://github.com/FloowD/VISI201_transfert_couleurs ici]&amp;lt;br/&amp;gt;&lt;br /&gt;
Pour utiliser le programme il faut lancer la fonction suivante :&lt;br /&gt;
&amp;lt;code&amp;gt;main_numpy(&amp;quot;image1.jpg&amp;quot;,&amp;quot;image2.jpg&amp;quot;,&amp;quot;image3.jpg&amp;quot;)&amp;lt;/code&amp;gt; &amp;lt;br/&amp;gt;&lt;br /&gt;
A noter que les 2 premiers fichiers ne sont pas obligatoirement au même format mais doivent tout deux rester des images.&amp;lt;br/&amp;gt;&lt;br /&gt;
Penser à bien indiquer le format de l&#039;image 3 dans la fonction&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12271</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12271"/>
		<updated>2020-05-13T13:35:22Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque https://numpy.org/ Numpy] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&#039;&#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffres que lorsqu&#039;on transfert des images de petite résolution, le temps de transfert reste tout à fait correct, néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace RGB &#039;&#039;&#039; ||~6sec || ~13sec|| ~30sec || ~2min&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme dans l&#039;espace CIELAB &#039;&#039;&#039; ||~37sec  ||~1min20  ||~3min  || ~12min30&lt;br /&gt;
|}&lt;br /&gt;
On remarque que le temps d&#039;execution du programme dans l&#039;espace CIELAB est plus long, la différence ce fait durant les calculs pour les changements d&#039;espace, le programme doit en effet faire des étapes supplémentaires sur le tous les pixels au début et à la fin.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code ==&lt;br /&gt;
J&#039;ai mit mes 2 programmes sur GitHub [http://www.example.com ici] &lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12261</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12261"/>
		<updated>2020-05-12T16:36:25Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque https://numpy.org/ Numpy] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs.&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12259</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12259"/>
		<updated>2020-05-12T16:24:51Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposée par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalités. La plus importante étant la bibliothèque https://numpy.org/ Numpy] afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionnait très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs&lt;br /&gt;
&lt;br /&gt;
===Temps d’exécution ===&lt;br /&gt;
On peut comparer la vitesse du nouveau programme avec celui réalisé avec numpy&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12258</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12258"/>
		<updated>2020-05-12T16:09:40Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
On peut voir que dans la version avec l&#039;espace CIELAB, les couleurs sont plus harmonieuses, et restent dans la même intensité de couleurs&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12257</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12257"/>
		<updated>2020-05-12T16:05:45Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg|600px]] || [[Fichier:canyon_vert_Lab.jpg|600px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12256</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12256"/>
		<updated>2020-05-12T16:05:16Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&amp;lt;br/&amp;gt;&lt;br /&gt;
[[Fichier:Grand_canyon.jpg|600px]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regardons maintenant le résultat avec les 2 programmes : &amp;lt;br/&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Rendu avec le programme classique&#039;&#039;&#039; || &#039;&#039;&#039;Rendu avec l&#039;espace CIELAB &#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|    [[Fichier:canyon_vert_numpy.jpg]] || [[Fichier:canyon_vert_Lab.jpg]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Canyon_vert_Lab.jpg&amp;diff=12255</id>
		<title>Fichier:Canyon vert Lab.jpg</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Canyon_vert_Lab.jpg&amp;diff=12255"/>
		<updated>2020-05-12T16:04:50Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Canyon_vert_numpy.jpg&amp;diff=12254</id>
		<title>Fichier:Canyon vert numpy.jpg</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Canyon_vert_numpy.jpg&amp;diff=12254"/>
		<updated>2020-05-12T16:04:18Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12251</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12251"/>
		<updated>2020-05-12T15:58:23Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous permette d&#039;avoir dans certain cas un meilleur rendu.&amp;lt;br/&amp;gt;&lt;br /&gt;
Prenons l&#039;exemple de ces 2 images&lt;br /&gt;
[[Fichier:Grand_canyon.jpg]]&lt;br /&gt;
[[Fichier:degrade_vert.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Degrade_vert.jpg&amp;diff=12250</id>
		<title>Fichier:Degrade vert.jpg</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Degrade_vert.jpg&amp;diff=12250"/>
		<updated>2020-05-12T15:58:16Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Grand_canyon.jpg&amp;diff=12249</id>
		<title>Fichier:Grand canyon.jpg</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Fichier:Grand_canyon.jpg&amp;diff=12249"/>
		<updated>2020-05-12T15:57:59Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12232</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12232"/>
		<updated>2020-05-12T14:59:52Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous donne un meilleur rendu sur certaine image&lt;br /&gt;
[[Fichier:Exemple.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12230</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12230"/>
		<updated>2020-05-12T14:42:10Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RVB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
==== Passage Lab RVB ====&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
On passe ensuite de l&#039;espace XYZ à l&#039;espace CIELAB grâce aux formules suivantes :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{| &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  L^* &amp;amp;= 116 f(Y/Y_n) - 16\\&lt;br /&gt;
  a^* &amp;amp;= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\&lt;br /&gt;
  b^* &amp;amp;= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right]&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f(t) = \begin{cases} &lt;br /&gt;
  t^{1/3} &amp;amp; \mbox{si } t &amp;gt; (\frac{6}{29})^3 \\&lt;br /&gt;
  \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Ici &#039;&#039;&amp;lt;math&amp;gt;X_n&amp;lt;/math&amp;gt;&#039;&#039;, &#039;&#039;&amp;lt;math&amp;gt;Y_n&amp;lt;/math&amp;gt;&#039;&#039; et &#039;&#039;&amp;lt;math&amp;gt;Z_n&amp;lt;/math&amp;gt;&#039;&#039; sont les composantes du blanc de référence, ce sont des constantes valant 255, on les obtiens avec RVB =(255,255,255).&lt;br /&gt;
&lt;br /&gt;
On récupère ainsi les valeurs de chaque composantes de l&#039;espace CIELAB et on peut ensuite calculer l&#039;écart de couleurs de la même manière que dans l&#039;espace RVB : &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\Delta E = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2 }&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
==== Passage RVB Lab ====&lt;br /&gt;
De la même manière on doit d&#039;abord repasser dans l&#039;espace XYZ avant de revenir dans l&#039;espace RGB&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
:{|&lt;br /&gt;
|-&lt;br /&gt;
||&amp;lt;math&amp;gt;Y = Y_n \cdot f^{-1}\left(\frac{L^*+16}{116}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|rowspan=3|&amp;lt;math&amp;gt;\qquad \mathrm o \mathrm \grave{u}~f^{-1}(t) = \begin{cases} &lt;br /&gt;
  t^3 &amp;amp; \mbox{si } t &amp;gt; \tfrac{6}{29} \\&lt;br /&gt;
3\left(\tfrac{6}{29}\right)^2\left(t - \tfrac{4}{29}\right) &amp;amp; \mbox{sinon}&lt;br /&gt;
\end{cases}&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;X =  X_n \cdot f^{-1}\left(\frac{L^*+16}{116} + \frac{a^*}{500}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;Z =  Z_n \cdot f^{-1}\left(\frac{L^*+16}{116} - \frac{b^*}{200}\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
On repasse ensuite dans l&#039;espace RVB avec de nouveau une matrice de passage &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1.876 &amp;amp; -0.533 &amp;amp; -0.343 \\&lt;br /&gt;
-0.967 &amp;amp; 1.998 &amp;amp; -0.031 \\&lt;br /&gt;
0.057 &amp;amp; -0.118 &amp;amp; 1.061 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rendu des images ===&lt;br /&gt;
Les images dans l&#039;espace CIELAB nous donne un meilleur rendu sur certaine image&lt;br /&gt;
&lt;br /&gt;
== Sources ==&lt;br /&gt;
[https://numpy.org/ Numpy] &amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.geeksforgeeks.org/numpy-mathematical-function/ Fonction numpy]&lt;br /&gt;
[http://www.tsi.enst.fr/pages/enseignement/ressources/beti/correl_couleur/lab.html Espace CIELAB]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12229</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12229"/>
		<updated>2020-05-12T14:24:41Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;br /&gt;
&lt;br /&gt;
== Changement d&#039;espace chromatique ==&lt;br /&gt;
Maintenant que l’algorithme fonctionne plus vite, on peut penser à modifier l&#039;espace de couleurs afin d&#039;obtenir un meilleur rendu.&lt;br /&gt;
&lt;br /&gt;
=== L&#039;espace chromatique L*a*b CIE 1976 ===&lt;br /&gt;
En effet l&#039;espace RGB est très bien mais il correspond aux écrans et non à l&#039;oeil humain, tandis que cette espace a pour but de mieux approximer la réalité.&lt;br /&gt;
L&#039;espace [[https://fr.wikipedia.org/wiki/L*a*b*_CIE_1976 L&#039;espace chromatique L*a*b CIE 1976]], autrement appelé : CIELAB est un espace reposant sur 3 composantes : la clarté L* et l&#039;écart de la couleur par rapport à celle d&#039;une surface grise de même clarté pour a* et b*.&amp;lt;br/&amp;gt;&lt;br /&gt;
La première étape consiste à passer les composantes RVB dans l&#039;espace XYZ. On utilise pour cela une matrice de passage &lt;br /&gt;
&lt;br /&gt;
=== Calcul nécessaire ===&lt;br /&gt;
Afin de passer dans l&#039;espace CIELAB nous devons d&#039;abord passer dans l&#039;espace [[https://fr.wikipedia.org/wiki/CIE_XYZ CIE XYZ]] car il est défini par ce dernier.&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\begin{pmatrix}&lt;br /&gt;
X \\&lt;br /&gt;
Y \\&lt;br /&gt;
Z \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
=&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
0.618 &amp;amp; 0.177 &amp;amp; 0.205 \\&lt;br /&gt;
0.299 &amp;amp; 0.587 &amp;amp; 0.205 \\&lt;br /&gt;
0 &amp;amp; 0.056 &amp;amp; 0.944 \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
R \\&lt;br /&gt;
V \\&lt;br /&gt;
B \\&lt;br /&gt;
\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12186</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12186"/>
		<updated>2020-05-05T16:13:39Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
=== Comparaison première version avec la version numpy ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;6&amp;quot;|Temps d’exécution du programme&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039;/&#039;&#039;&#039; Nb tours&#039;&#039;&#039; || 20 || 40 || 50 || 75 || 100 &lt;br /&gt;
|-&lt;br /&gt;
|   720x576 || 6sec || 10sec || 13sec || 18sec || 24sec&lt;br /&gt;
|-&lt;br /&gt;
|   1280x720 || 13sec || 25sec || 30sec || 48sec || 1min&lt;br /&gt;
|-&lt;br /&gt;
|   1920x1080 || 30sec || 54sec || 1min10 || 1min40 || 2min&lt;br /&gt;
|-&lt;br /&gt;
|   3840x2160 || 2min || 3min50 || 5min || 7min15 || 9min30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On remarque ainsi que la taille de l&#039;image augmente, et le nombre de répétitions aussi, plus le temps d’exécution devient important, surtout pour les très grandes images (comme celle de 3840x2160 pixels). En effet les tailles deviennent exponentielles avec l&#039;augmentation de la qualité ce qui demande énormément de pixels à traiter.&amp;lt;br/&amp;gt;&lt;br /&gt;
On pourrait ainsi imaginer, pour les images de hautes qualités, a regroupé plusieurs pixels en &#039;paquets&#039; et les traiter ainsi.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cela permettrai d&#039;avoir moins de pixels à traiter et de plus cela ne devrait pas avoir un énorme impact sur la qualité de l&#039;image, on ne devrait pas voir une grande différence à l’œil nue.&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12185</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12185"/>
		<updated>2020-05-05T15:03:08Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution avec numpy &#039;&#039;&#039; || ~6sec || ~13sec || ~30sec || ~2min&lt;br /&gt;
|}&lt;br /&gt;
De plus ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme&amp;lt;br/&amp;gt;&lt;br /&gt;
On voit ainsi que l&#039;utilisation de numpy permet de rendre le programme environ 10 fois plus rapide.&lt;br /&gt;
Ainsi on peut donc penser maintenant à augmenter le nombre de répétition avant d&#039;avoir un meilleur résultat en gardant un temps d’exécution correcte.&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12184</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12184"/>
		<updated>2020-05-05T13:45:17Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;br /&gt;
&lt;br /&gt;
== Nouvelle version avec numpy ==&lt;br /&gt;
&lt;br /&gt;
=== Pourquoi numpy ===&lt;br /&gt;
&lt;br /&gt;
Dans ce programme nous utilisons de nombreux tableaux afin de stocker toute les variables dont nous avons besoin, et la bibliothèque numpy possède des tableaux bien plus compactes, et de plus, l&#039;avantage majeur est que l&#039;on peut appliquer des calculs directement sur l&#039;ensemble du tableau au lieu de faire un boucle pour appliquer les calculs sur chaque variable. &amp;lt;br/&amp;gt;&lt;br /&gt;
De ce fait cela nous permet de gagner énormément de temps de calcul en évitant de nombreuses boucles.&amp;lt;br/&amp;gt;&lt;br /&gt;
Cette bibliothèque est très compléte et si vous voulez plus d&#039;informations je vous conseil de vous rendre sur la page officiel [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Numpy]]&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12183</id>
		<title>Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images_avec_numpy&amp;diff=12183"/>
		<updated>2020-05-05T13:35:09Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : Page créée avec « == Modification de Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy ==  Le but de ce projet est une amélioration de la version proposé par... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Modification de Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy ==&lt;br /&gt;
&lt;br /&gt;
Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Discussion_utilisateur:Fdufaure&amp;diff=12182</id>
		<title>Discussion utilisateur:Fdufaure</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Discussion_utilisateur:Fdufaure&amp;diff=12182"/>
		<updated>2020-05-05T13:34:51Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : Page blanchie&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Discussion_utilisateur:Fdufaure&amp;diff=12135</id>
		<title>Discussion utilisateur:Fdufaure</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Discussion_utilisateur:Fdufaure&amp;diff=12135"/>
		<updated>2020-05-03T10:02:14Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Modification de Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy ==&lt;br /&gt;
&lt;br /&gt;
Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
Afin de comprendre correctement cette page je vous invite tout d&#039;abord à vous rendre sur la page de la première version de ce sujet (le lien précédant) et bien comprendre le fonctionnement du programme et son but.&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
	<entry>
		<id>http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Discussion_utilisateur:Fdufaure&amp;diff=12134</id>
		<title>Discussion utilisateur:Fdufaure</title>
		<link rel="alternate" type="text/html" href="http://os-vps418.infomaniak.ch:1250/mediawiki/index.php?title=Discussion_utilisateur:Fdufaure&amp;diff=12134"/>
		<updated>2020-05-03T10:00:27Z</updated>

		<summary type="html">&lt;p&gt;Fdufaure : /* Modification de Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy */ nouvelle section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Modification de Transport optimal par coupe 1D et transfert de couleurs entre images avec numpy ==&lt;br /&gt;
&lt;br /&gt;
Le but de ce projet est une amélioration de la version proposé par [[https://www.lama.univ-savoie.fr/mediawiki/index.php/Transport_optimal_par_coupe_1D_et_transfert_de_couleurs_entre_images Lucas Chardonnet]] en ajoutant des fonctionnalitées. La plus importante étant la bibliothèque numpy afin d&#039;accélérer la vitesse d&#039;exécution du programme&lt;br /&gt;
&lt;br /&gt;
== Quelles était les limites de l&#039;ancien programme ==&lt;br /&gt;
&lt;br /&gt;
Le programme précédant fonctionner très bien et donnait de bon rendu, néanmoins il mettait un temps relativement long pour effectuer les calculs, ce qui devient problématique si on veut faire un transfert de couleurs entre 2 images avec un grand nombres de pixels.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quelques statistiques sur les temps de calculs de l&#039;ancien programme ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|  &#039;&#039;&#039; Taille de l&#039;image &#039;&#039;&#039; &amp;lt;br/&amp;gt;(en pixel) || 720x576 || 1280x720 || 1920x1080 || 3840x2160 &lt;br /&gt;
|-&lt;br /&gt;
|   &#039;&#039;&#039; Temps d’exécution du programme &#039;&#039;&#039; || ~48sec || ~2min25 || ~5min30 || ~20min25&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A noter que ces tests ont été réalisé avec un nombre de répétition de 20 dans le programme.&amp;lt;br/&amp;gt;&lt;br /&gt;
C&#039;est une bonne valeur de référence pour avoir assez de tests pour trouver un bon vecteur pour le transfert de couleur&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
On remarque par ces chiffre que lorsqu&#039;on transfert des images de petites résolution, le temps de transfert reste tout à fait correct, ,néanmoins dès que l&#039;on va vouloir prendre des images des résolution plus importante (HD ou même 4K) le temps d&#039;exécution devient bien plus important.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En effet l&#039;ancien programme comporte bon nombre de boucle &#039;&#039; for &#039;&#039;, la machine doit donc faire quelques centaines de milliers de boucle. Cela semble très simple pour nos processeurs qui sont capables d&#039;en faire un milliard de calculs par seconde mais python est un langage interprété, ce qui rajoute un temps de calcul non négligeable (comme on peut le voir par les valeurs dans le tableau)&lt;/div&gt;</summary>
		<author><name>Fdufaure</name></author>
	</entry>
</feed>