Projet

Général

Profil

Actions

P14AB08 Implantation d'un encodeur vidéo MJPEG sur RX64M


Projet GE2-GE3 2014
Entreprise / Client : Renesas Electronics/ Sébastien Walger
Auteurs : Clément Leyssene / Geoffrey Raynal
Responsable Projet : Michel James
Tuteur industriel : Isabelle Goi

Sommaire

1. Résumé
2. Abstract
3. Introduction
4. Présentation du Sujet

1. Renesas
2. Le projet

5. Cahier des Charges
6. Developpement

1. Problématiques
2. Faisabilité
3. Etude Théorique
4. Solutions

7. Gestion de Projet

1. W.B.S.
2. Gantt

8. Notes d'application

1. sujet 1
2. sujet 2

9. Bilan

1. Etat d'avancement
2. Analyse Critique
3. Perspectives

10. Bibliographie


Résumé

Ce projet concerne la réalisation d'un encodeur vidéo de type Motion-JPEG sur un microcontrôleur Renesas, le RX64M. Cette entreprise souhaite la réalisation d’un tel projet afin de démontrer les performances de leur nouveau microcontrôleur et pouvoir proposer au client des applications fonctionnelles.
Pour ce projet nous disposons d'une carte possédant le microcontrôleur, qui sera relié d'un côté à une caméra et de l'autre à un ordinateur.
L’objectif sera d’envoyer un flux vidéo de la caméra vers le microcontrôleur qui traitera les données et les encodera, puis ce dernier enverra ces données vers un ordinateur qui affichera la vidéo à l’écran.

Mots clés:
RX64M
MJPEG
Encodage JPEG


Abstract

This project involves the implementation of a video encoder type Motion-JPEG on a Renesas microcontroler, the RX64M. The company wants the realization of such a project to demonstrate the performance of their new microcontroller and to be able to offer the customer functional applications.
In this project we have a board with the RX64M microcontroller, which is connected on one side to a camera and a computer to the other.
The objective is to send a video stream from the camera to the microcontroller, which will process the data and encode, then it will send the data to a computer that displays the video on the screen.

Key words:
RX64M
MJPEG
JPEG Encoding


Introduction

En 1 heure, 6000h de vidéo sont postées sur le site YouTube?. Une heure de vidéo non compressée en haute définition sans son a une taille de 625 Gio, soit 78 DVD. Le problème est donc de pouvoir réaliser des vidéos qui puissent être stockées sur des supports tels que les CD, les DVD, ou plus récemment, dans nos téléphones portables. C'est dans cette problématique que les encodages vidéos sont apparus, certains sont utilisés pour que la qualité de la vidéo soit excellente et d'autres pour réduire au maximum la taille du fichier.

Dans le cadre de la formation de Génie électrique à Polytech, les étudiants ingénieurs ont l'opportunité de réaliser un projet industriel, répartie en deux phases. La première étape se déroule lors de la quatrième année pendant une durée de 48H, qui consiste en une phase d'étude avec la faisabilité, la gestion de projet et les recherches liées au projet. Par la suite, lors de la cinquième et dernière année, une phase de 250h permet de concrétiser le travail de quatrième année et de réaliser ce qui a été demandé dans le cahier des charges. Ces projets industriels permettent aux étudiants de se confronter au monde de l'entreprise à leur futur travail d'ingénieur, mais en restant encadré par des enseignants du milieu génie électrique ainsi que par des tuteurs industriels.

La société Renesas Electronics, représentée par notre client Sébastien Walger, a récemment développé un nouveau microcontrôleur, le RX64M et souhaite pouvoir présenter à ses clients des applications fonctionnelles de cette nouvelle cible, afin de démontrer les performances de leur microcontrôleur. C'est dans cette perspective que Renesas a confié à Polytech le projet de réaliser cette application. Notre objectif est d’implanter sur cette cible Renesas RX64M des algorithmes d’encodage MJPEG en utilisant un flux vidéo provenant d’une caméra, puis de l'envoyer sur un ordinateur qui décodera et affichera à l'écran le résultat.
L’enjeu de ce projet est de réussir à implanter un encodeur complexe et volumineux sur une cible beaucoup moins puissante qu’un ordinateur.

Présentation du Sujet

1. Renesas

Renesas Electronics est une entreprise japonaise basée à Tokyo créé en novembre 2002 de la fusion d’HITACHI Ltd et de MITSUBISHI ELECTRIC CORPORATION et compte près de 28500 salariés à travers le monde. Cette société est le leader mondial des fournisseurs de microcontrôleurs et est un fournisseur de solutions de semi-conducteurs avancés. Il assure également la conception, fabrication, vente et service après-vente des systèmes de semi-conducteurs pour la téléphonie mobile, l’automobile, l’électronique de puissance, les mémoires, les LCD, les circuits intégrés RF et système sur puce.

2. Le projet

Notre projet est d'utiliser le microcontrôleur fourni par Renesas, le RX64M, pour encoder le flux vidéo provenant d'une caméra en MJPEG, puis de le transférer via liaison filaire sur un ordinateur qui décompressera la vidéo pour l'afficher à l'écran

2.1 Synoptique général du sujet

2.2 Pourquoi encoder?

Nous pouvons nous poser de ce besoin d'encoder, en effet pourquoi ne pas envoyer tout simplement le flux vidéo de la caméra vers l'ordinateur ?
En regardant les spécifications de la caméra, nous nous rendons compte qu'elle a une résolution de 640*480 pixels, de trois couleurs pour chaque pixel réparti sur 8 bits avec un débit maximal de 30 images par seconde.
Nous obtenons donc un flux de 640*480*3*8*30=221184000 bits/s= 221,2 Mbit/s, ce flux sature le protocole USB.2 qui est limité à 175Mbits/s, d'où cette nécessité de réduire la taille du flux vidéo en le compressant. Nous allons par la suite présenter la méthode d'encodage que nous devons utiliser.

2.3 Définition des termes du sujet

2.2.1 Le MJPEG

Motion JPEG (M-JPEG ou MJPEG) est un format vidéo dans lequel chaque image vidéo ou une séquence vidéo numérique est compressé séparément comme une image JPEG. Initialement développé pour les applications PC multimédias, M-JPEG est maintenant utilisé par les appareils de capture vidéo, tels que des appareils photo numériques, caméras IP, et des webcams. Nous allons donc nous intéresser lors de ce projet au fonctionnement de l'encodage JPEG.

2.2.2 L'encodage JPEG

JPEG est l’acronyme de Joint Photographic Experts Group. Il a été développé par un comité d'expert qui édite des normes de compression pour l’image fixe durant les années 1978 à 1980. Le groupe JPEG a spécifié la norme en 1991. La norme officielle et définitive a été adoptée en 1992.

La compression JPEG permet de réaliser des compressions d'image avec ou sans perte: -avec pertes ou compression irréversibles. C’est le JPEG « classique ». Il permet des taux de compression de 3 à 100.
-sans pertes ou compression réversible. Il n’y a pas de pertes d’information et il est donc possible de revenir aux valeurs originales de l’image. Les gains en termes de compression sont alors plus modestes, avec un taux de compression de l’ordre de 2 à 8.
Pour les besoins du projet, nous allons utiliser la première méthode afin de réduire au maximum la taille des images et donc de la vidéo.

Voici comment s'organise le processus de compression et de décompression d'une image JPEG:

Les différentes étapes de cet algorithme seront expliquées plus en détail dans la partie étude théorique.


Cahier des Charges

- Réaliser un encodeur JPEG sur un microcontrôleur RX64M
- Récupérer le flux vidéo d’une caméra via une liaison parallèle
- Transférer le flux compressé du RX64M vers un ordinateur via liaison filaire
- Afficher la vidéo en utilisant la fonction streaming de VLC
- Si le temps le permet, remplacer la liaison filaire par un protocole Ethernet


Développement


Problématique

Le projet comporte deux aspects importants, le transport de données d’un point à un autre et l’implémentation d’un algorithme complexe dans un appareil beaucoup moins puissant qu’un microprocesseur d’ordinateur.
D’une part il s’agit de transférer une vidéo ou une suite d’image de la carte du microcontrôleur vers l’ordinateur à une vitesse suffisante pour que l’image retransmise ne soit pas saccadée.
D’autre part l’encodeur d’image JPEG est un code complexe qui existe depuis environ 30 ans et qui a été optimisé depuis pour être utilisé principalement sur les ordinateurs. Il y a donc une réelle difficulté à adapter ce code sur la cible qui nous est fournie.


Faisabilité

Après réflexion, nous avons pensé que le projet serait réalisable si le transfert de donnée par liaison filaire suffit, si ce dernier est saturé nous devrons utiliser le protocole Ethernet, il est clair que le projet ne pourrait pas être terminé si nous avons à mettre en place un tel protocole, mais il aurait des chances d'être terminé si le client nous fournit les codes permettant d'utiliser le protocole Ethernet.


Etude Théorique

Comme dit précédemment, pour réaliser l'encodage MJPEG, il faut traiter le flux vidéo comme une succession d'images JPEG.
Pour cela, il faut décomposer les différentes étapes de ce processus. Dans un premier temps, il s’agit de séparer l'image en blocs de 8x8 pixels. La caméra a une résolution de 640x480 pixel, ce qui nous donne 4800 blocs à traiter. Les parties transformations des couleurs et sous échantillonnage sont déjà réalisées par la caméra qui envoie le flux vidéo en YCbCr, le signal Y correspond à la luminance (noir et blanc), plus deux informations de chrominance : Cb (bleu moins Y) et Cr (rouge moins Y), le signal Y est composé de la somme des couleurs rouge, bleu et vert.

P14AB08_YCbCr.jpeg?

Des équations permettent de calculer les YCbCr à partir des couleurs RVB:

Y= 0,299*R + 0,587*G + 0,114*B
Cb= -0,1687*R - 0,3314*G + 0,5*B +128
Cr= 0,5*R - 0,4187*G - 0,0813*B +128

Pour la suite, nous allons utiliser la matrice 8x8 suivante qui correspond à un bloc d'une image:

La DCT

L'étape suivante est la DCT (Discrete Cosine Transform, en français, transformé en cosinus discret), qui permet de supprimer les variations d'intensité dans une image comme sur la figure 4, l’image de droite est avant la DCT, il y a sur son spectre de nombreuses variations, après la transformation DCT, les variations sur le spectre sont nettement plus atténués, sans causé de différence notable avec l’image initiale. Cette transformation numérique est appliquée à chaque bloc.

La transformée DCT s’exprime mathématiquement par :

Et N = nombre de pixel, ici N=8.

On écrit ensuite dans un nouveau tableau de la même taille que N, les amplitudes de chacun des cosinus composant le signal. Ils sont classés en faisant apparaître les hautes fréquences vers le coin inférieur droit du tableau. La DCT est une opération théoriquement sans perte d'informations, mais étant donné que nous n'utilisons pas les fonctions cosinus pour nos calculs, mais des approximations de ces valeurs, il en résulte une certaine perte d'information.

Ce qui nous permet d'obtenir en utilisant la matrice initiale:

La 1re valeur à l'indice (0,0) est le coefficient continu, elle correspond à une valeur "moyenne'' de la grandeur d'ensemble de la matrice d'entrée, en effet elle représente un nombre proportionnel à la somme de toutes les valeurs du signal. Les autres valeurs de la DCT représentent des écarts par rapport à cette moyenne. On remarque que les valeurs de la matrice à s'approcher de 0 lorsqu'on s'éloigne du coin supérieur gauche, c'est-à-dire lorsqu'on monte dans les plus hautes fréquences. Cela traduit le fait que l'information d'une image est concentrée dans les basses fréquences.
NB : Comme un pixel est un bloc de 8x8 avec 3 composantes (Y, Cb, Cr), la DCT est appliquée séparément à trois blocs de 8x8:
Le premier bloc est le bloc 8x8 qui contient la luminance.
Le second bloc 8x8 est le bloc qui contient la valeur Cb.
Et de même, le troisième bloc de 8x8 contient les valeurs Cr.

Tandis que la DCT convertit l'image dans son domaine de fréquence et élimine une certaine variation, elle produit plus d'informations qu'elle en élimine: les valeurs du domaine spatial sont de -128 à 128, les valeurs de la matrice après DCT sont de -1024 à 1024. Un second procédé de compression, la quantification, est utilisé pour éliminer l'excès de ces informations.

La quantification

Après la DCT, l'image est décrite dans le domaine fréquentiel dans les moindres détails, cependant, l’œil humain ne peut pas remarquer les différents changements très lumineux ou de couleurs très sombres. La quantification permet de diminuer la précision du stockage des entiers de la matrice DCT en supprimant les hautes fréquences, ce qui permet de réduire le nombre de bits occupés par chaque entier.
C'est l'étape où se produit le plus de perte d'information, la diminution de précision doit être plus forte dans les hautes fréquences. La perte de précision va donc être de plus en plus grande lorsqu'on s'éloigne de la position (0,0).
Une matrice de quantification est utilisée pour cette étape, soit Q cette matrice, elle sera définie, la plupart du temps par :

Q(i,j)= 1+K .(1+i+j ), avec i l'indice de ligne, j l'indice de colonne et K le facteur de qualité (choisi entre 1 et 25).

On choisit une matrice de quantification avec un facteur de qualité = 2 :

Chaque amplitude est divisée par le nombre correspondant dans le tableau. Par exemple, la valeur moyenne est divisée par 3, et l'amplitude associée à la plus haute fréquence est divisée par 31.
Les amplitudes en bas à droite vont être divisées par des coefficients beaucoup plus grands.
En utilisant la matrice DCT calculée précédemment et en la divisant par la matrice de quantification on obtient :

Lors de l'arrondi à l'entier le plus proche, les valeurs des hautes fréquences seront probablement ramenées à 0. C'est à ce moment que l'on perd en qualité, il faut veiller à choisir une matrice de qualité adéquate pour ne pas détériorer l'image :

Si la quantification est trop forte (= taux de compression trop élevé), il y aura trop peu de coefficients non nuls pour représenter fidèlement le bloc. Le problème apparaîtra lors du décodage nécessaire pour l'affichage de l'image : à l’écran, la division en blocs deviendra visible, et l'image aura un aspect « pixelisé ».

compression de Huffman

Le ZigZag

L'étape suivante est la compression de Huffman, pour cela on commence par parcourir la matrice en ZigZag? :

Cette technique a la propriété de parcourir les éléments de la matrice en commençant par les basses fréquences et de continuer sur des fréquences de plus en plus hautes. Étant donné que la matrice quantifiée contient de nombreux coefficients nuls, la séquence zigzag va engendrer une suite de 0.
Dans notre cas :

Par la suite, la norme JPEG demande de séparer la première valeur (en rouge) du reste, cette valeur sera appelée DC, et le reste des 63 valeurs AC.

Algorithme RLE

Ce résultat est par la suite traité selon un algorithme de type RLE (run-length encoding) pour compresser, cet algorithme repose sur une idée assez simple : au lieu de répéter plusieurs fois un même symbole, on indique le nombre de fois qu’on le répète, puis ce symbole :

En rouge correspond le symbole et en vert le nombre de répétition de ce dernier, la lettre 'e' est là pour signaler la fin de la chaine.

La suite est d'utilisé l'algorithme de Huffman qui est plus complexe. Au lieu de stocker la valeur réelle, la norme JPEG précise qu’il faut stocker la taille minimale en bits dans lequel nous pouvons conserver cette valeur (cela s'appelle la catégorie de cette valeur), puis une représentation binaire codée comme ci dessous:

À gauche correspond les intervalles de valeurs que peut avoir la valeur DC, et à droite dans quelle catégorie il faut la ranger, les valeurs après la catégorie 11 (ou B) ne seront jamais atteinte. Par la suite il faut faire correspondre à ces catégories un dictionnaire, comme ci dessous:

C’est une table standard pour appliquer le codage de Huffman, cette table est seulement valable pour la luminance, en effet, pour les chrominances, il sera plus adapté d’utilisé une autre table.
Les valeurs qui sont censées être les plus utilisés sont codées sur le plus petit nombre de bits, ici deux.

Pour les valeurs AC il faut tenir compte de la catégorie du nombre mais aussi du « run » c’est-à-dire le nombre de zéros qui précède cette valeur. On utilise donc de la même façon que pour les variables DC la table de Huffman ci dessous :

Il s’agit d’une table standard aussi calculée en fonction de la physiologie de l’œil et des tests menés sur plusieurs individus. Si le block contient 16 zéros d’affilés il faut l’indiquer avec une valeur particulière présente sur la table précédente.


int DCT_transform(int DCT[COTE_MAX][COTE_MAX], int value[COTE_MAX][COTE_MAX])
{
int i,j,x,y;
float calc = 0;
for(i=0; i<COTE_MAX; i++) {
for(j=0; j<COTE_MAX; j++) {
for(x=0; x<COTE_MAX; x++) {
for(y=0; y<COTE_MAX; y++) {
calc+=value[x][y]*(float)LUT[x][i]*(float)LUT[y][j];
}
}
if(i==0) {
calc=calc/Racine_2;
}
if(j==0) {
calc=calc/Racine_2;
}
calc= calc 2/(float)COTE_MAX);
DCT[i][j]= arrondi(calc); // round value, transform float to int
calc = 0;
}
}
DCT[0][0]=DCT[0][0]-1024;
return 0;
}
/
* step of quantifization, input : Q, DCT ; output : DCT **/
int Quantifization(int DCT[COTE_MAX][COTE_MAX], int Q[COTE_MAX][COTE_MAX]) {
int i,j;
for(i=0; i<COTE_MAX; i++) {
for(j=0; j<COTE_MAX; j++) {
DCT[i][j]=arrondi((float)DCT[i][j]/(float)Q[i][j]);
}
}
return 0;
}

La quantification

Après des recherches, il semble plus adéquat d’utiliser des tables de quantification standard de la norme pour la compression JPEG :


La matrice de gauche sur la figure 12 correspond à une matrice de quantification pour la luminance et celle à droite correspond à une matrice pour la chrominance.
La programmation des parties découpages en blocs de 8 pixels, DCT, Quantification, ZigZag? et RLE est codée et testée, la partie Huffman est commencée mais non terminée:

int facteur_qualite = 2;
int Quantifization(int DCT[COTE_MAX][COTE_MAX]) {
int i,j;
for(i=0; i<COTE_MAX; i++)
for(j=0; j<COTE_MAX; j++) {
DCT[i][j]=arrondi((float)DCT[i][j]/(float)Q[i][j]);
}
return 0;
}

Le ZigZag

int zig_zag(int matrice_quantifiee[COTE_MAX][COTE_MAX],int value[COTE_MAX*COTE_MAX], char index)
{
int i,j,colonne,crois;
i=0;
j=0;
colonne=0;
crois=0;
while (i < COTE_MAX && j < COTE_MAX) {
value[colonne]=matrice_quantifiee[i][j];
colonne++;
if (i 0 || i COTE_MAX-1) {
if (j == COTE_MAX-1) {
j = j - 1;
i = i + 1;
}
j = j + 1;
value[colonne]=matrice_quantifiee[i][j];
colonne++;
}
else {
if (j 0 || j COTE_MAX-1) {
if (i == COTE_MAX-1) {
i = i - 1;
j = j + 1;
}
i = i + 1;
value[colonne]=matrice_quantifiee[i][j];
colonne++;
}
}
if (i 0 || j COTE_MAX-1) {
crois = 0;
}
if (j 0 || i COTE_MAX-1) {
crois = 1;
}
if (crois==1) {
i = i - 1;
j = j + 1;
}
else {
i = i + 1;
j = j - 1;
}
}
return 0;
}

Algorithme RLE

int transformRLC(int mat_zigzag[COTE_MAX*COTE_MAX], Table_RLE table_RLE[COTE_MAX*COTE_MAX], char index)
{
int i=0;
int j=0;
char nb_occ;
char ok=0;
char pos_RLE=0;
dcvalue[index].DC= mat_zigzag[0];
while(i<(COTE_MAX*COTE_MAX)) {
nb_occ = 0;
while((mat_zigzag[i] == 0 && nb_occ&lt;16)&&i<63) {
nb_occ++;
i++;
}
if(nb_occ > 15) {
table_RLE[pos_RLE].nb_occ = 0;
table_RLE[pos_RLE].valeur = 0;
break;
}
else {
table_RLE[pos_RLE].nb_occ=nb_occ; // nb occurrence first
table_RLE[pos_RLE].valeur=mat_zigzag[i]; // value from zigzag
}
i++;
pos_RLE++;
}
table_RLE[pos_RLE].nb_occ = 0;
table_RLE[pos_RLE].valeur = 0;
return 0;
}

Gestion de Projet


W.B.S.


Gantt

Partie GE4 :

Partie GE5 :


Notes d'application
JPEG ALGORITH BASELINE ON EMBEDDED SYSTEMS

Sujet Clément Leyssene : P14AB08_JPEG_ALGORITH_BASELINE_ON_EMBEDDED_SYSTEMS.pdf

Using numeric camera on RX64M

Sujet Geoffrey Raynal : P14AB08_USING_A_NUMERIC_CAMERA_ON_RX64M.pdf


Bilan

Le projet a été mené en décidant de réaliser l'algorithme de compression sans utiliser la libjpeg, cette tâche s'est avéré plus complexe que prévu, il a fallu faire face à de nombreux problèmes lors de la réalisation de l'encodeur, principalement à cause de la norme JPEG dont les explications sont très souvent floues et mal organisée. Un seul problème dans le programme suffit à rendre la compression de l'image complètement fausse.
Au final l'encodeur fonctionne dans la plupart des cas mais démontre des problèmes sur l'image finale pour des images d'entrée avec des variations de couleurs trop brusque.


Etat d'avancement

Le projet n'a pas pu être terminé par manque de temps, il restait à corriger des problèmes sur l'encodeur, de plus la communication entre la caméra et le microcontrôleur présentait des erreurs lors de la récupération des données.
Une vingtaine d'heures supplémentaires auraient été nécessaire à la finalisation de l'encodeur car les erreurs sont très complexes à repérer dans le flux de donnée pour chaque image et une trentaine d'heures pour finaliser la récupération de l'image de la caméra sur le RX64M, faire marcher correctement l'encodeur sur ce dernier et terminer le programme pour afficher les photos à l'écran de l'ordinateur.


Analyser Critique

Le projet n'a pas pu être terminé par manque de temps et présente encore des erreurs dans le code. L'autre solution qui était de partir de la libjpeg et de supprimer toute les parties inutiles auraient pu être permis de pouvoir clôturer l'encodeur dans les temps. De plus, il aurait surement fallu passer plus de temps à essayer de comprendre la norme JPEG dès le début, à décomposer chaque partie qui aurait pu être utile pour l'encodeur plutôt qu'essayer de coder en suivant des instructions peu claires de la norme.


Perspectives

De nombreux moyens sont possibles pour améliorer ce projet:
- Corriger la fin du programme pour rendre l'encodeur fonctionnel
- Mettre en place une liaison USB ou Ethernet pour transférer les images compressées du RX vers l'ordinateur plus rapidement.
- Réaliser un programme qui permet de réaliser l'encodage en direct en stockant le minimum de donnée dans la mémoire du RX et ainsi pouvoir encoder des images de grandes tailles.


Bibliographie

Wikipédia, le 6 Mars 2014 (consulté le 28 Mars 2014), JPEG, http://fr.wikipedia.org/wiki/JPEG

Clément Masson, lehollandaisvolant.net, L’algorithme JPEG, http://lehollandaisvolant.net/science/jpg/

T.I.P.E. Terre et Espace, chireux.fr, Avril 1999, Compression d'images fixes http://www.chireux.fr/mp/cours/Compression%20JPEG.pdf

Catherine Holloway, milankie.huffmancoding, April 2008, JPEG Image compression: Transformation, Quantization and Encoding http://milankie.huffmancoding.com/chollowayjpegimagecompression.pdf

Cristi Cuturicu, opennet.ru, 1999, JPEG decoding algorithm, http://www.opennet.ru/docs/formats/jpeg.txt

Calvin Hass, impulseadventure.com, 2008, JPEG Huffman Coding Tutorial, http://www.impulseadventure.com/photo/jpeg-huffman-coding.html

Mis à jour par Anonyme il y a environ 4 ans · 31 révisions