begin process at 2012 05 29 05:39:38
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C++ & C++ .NET

 > 

Divers

 > 

Divers

 > 

Extraction morceau image et création fichier bmp


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Extraction morceau image et création fichier bmp

dimanche 2 mai 2010 à 22:08:03 | Extraction morceau image et création fichier bmp

Oelth

Bonjour,
dans le cadre de mon projet de fin d'année de BTS, je dois entre autres à partir d'une photo de véhicule, reconnaitre la position de la plaque d'immatriculation de ce dernier, extraire cette plaque et recréer un fichier bmp avec uniquement la plaque d'immatriculation à l'intérieur.
Les étapes que j'ai actuellement effectué se décomposent de la manière suivante :

Partie 1 :
-Stockage de l'image en mémoire dans un tableau.
-Parcours du tableau pour reconnaitre la position de la plaque au moyen des pixels bleus présents sur la ligne (on considère que toutes les plaques ont ce rectangle bleu sur la gauche).

Partie 2 :
-Stockage de toutes les lignes contenant ces pixels bleus dans un autre tableau.
-Création d'une en tête bmp et création d'un fichier bmp dans lequel j'insère l'en-tête puis l'image. (jusque là tout va bien)

Partie 3 :
-Détection du début du bleu sur la plaque afin de supprimer le côté gauche de l'image.
-Récupération de la plaque sans le coté gauche de l'image dans un tableau.
-Création d'une en tête bmp et création d'un fichier bmp dans lequel j'insère l'en-tête puis l'image.

La partie 1 et 2 marchent parfaitement, j'ai extrait le morceau d'image et recréé un fichier bmp contenant celle ci, et tout marche à merveille.

En revanche je ne peux pas en dire autant pour la partie 3, une fois les étapes terminées, j'ai bien un fichier bmp créé, avec la taille du fichier correspondante affichée, mais l'image ne se trouve pas dans le fichier. Et le gros soucis c'est que j'ai beau avoir tenté de retourner dans tous les sens le problème, je ne vois pas ce qui cloche.

Pour info, j'utilise builder C++ 6, je ne sais pas si cela peut aider, mais sait on jamais ^^".
Si une âme charitable arrivait à repérer l'erreur que j'ai commis, je lui en serais fortement reconnaissant, car là je n'en vois pas le bout.
Voilà donc mon code :

Code C/C++ :
//------------------------------------------------------------------------------

#pragma hdrstop

#include <stdlib.h>
#include <conio.h>
#include <iostream>
#include <windows.h>


using namespace std;

//------------------------------------------------------------------------------

#pragma pack(push,1)


typedef struct {
    WORD bftype;
    DWORD bfsize;
    WORD bfreserved1;
    WORD bfreserved2;
    DWORD bfoffbits;
} FILEHEADER;

typedef struct {
    DWORD bisize;
    DWORD biwidth;
    DWORD biheight;
    WORD biplanes;
    WORD bibitcount;
    DWORD bicompression;
    DWORD bisizeimage;
    DWORD bixpelspermeter;
    DWORD biypelspermeter;
    DWORD biclrused;
    DWORD biclrimportant;
} INFOHEADER;

typedef struct {
    FILEHEADER Fileheader;
    INFOHEADER Infoheader;
} Entete_BMP;

typedef struct {
    unsigned char Bleu;
    unsigned char Vert;
    unsigned char Rouge;
} T_PIXEL;

#pragma pack(pop)


//------------------------------------------------------------------------------


#pragma argsused
int main(int argc, char* argv[])
{
        Entete_BMP Mon_Entete;
        HANDLE Descripteur;
        HANDLE Descripteur_Redimensionnement_Hauteur;
        HANDLE Descripteur_Suppression_Cote_Gauche;
        char Nom_Fichier[50];
        unsigned char *Tableau;//Tableau contenant l'image originale
        unsigned char *Tableau_Hauteur_Redimensionnee;//Tableau contenant uniquement les lignes où se trouve la plaque
        unsigned char *Tableau_Sans_Cote_Gauche;//Tableau contenant la plaque avec seulement le cote droit de la voiture
        DWORD Octets_Lus;
        DWORD Octets_Ecrits;
        unsigned int Index_Colonne;
        unsigned int Index_Ligne;
        unsigned int Compteur_Pixels_Bleus = 0;
        unsigned int Compteur_Lignes_Bleus = 0;
        unsigned int Hauteur;
        unsigned int Largeur;
        unsigned int Compteur_Ligne = 0;
        unsigned int Nombre_Colonnes_Conservees = 0;
        unsigned int Nombre_Colonnes_Conservees_Final = 0;
        unsigned int Compteur_Position = 0;
        unsigned int Numero_Derniere_Ligne_Plaque;
        unsigned int Numero_Premiere_Ligne_Plaque;
        unsigned int Position_Derniere_Colonne;
        unsigned int *Tableau_Position_Plaque;
        bool Premiere_Ligne_Plaque = false;

        T_PIXEL Pixel_Bleu_Clair = {139, 89, 28}; //Issu d'une recherche de nuances sous paint
        T_PIXEL Pixel_Bleu_Fonce = {117, 63, 0};  //Issu d'une recherche de nuances sous paint
        T_PIXEL Mon_Pixel;//Variable qui recupère les 3 valeurs correspondantes aux couleurs qui composent chaque pixel

//PARTIE 1
        //-----------------Ouverture de l'image originale-----------------------

        cout<<"Taper le nom du fichier a ouvrir"<<endl;
        cin>>Nom_Fichier;

        Descripteur = CreateFile(Nom_Fichier, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        ReadFile(Descripteur, &Mon_Entete, sizeof(Entete_BMP), &Octets_Lus, NULL);


        //----------Creation et sauvegarde de l'image dans le tableau-----------

        Tableau = new unsigned char[Mon_Entete.Infoheader.bisizeimage];
        SetFilePointer(Descripteur, Mon_Entete.Fileheader.bfoffbits, NULL, FILE_BEGIN);
        ReadFile(Descripteur, Tableau, Mon_Entete.Infoheader.bisizeimage, &Octets_Lus, NULL);

        //-------------------------Detection Plaque-----------------------------


        Hauteur =   Mon_Entete.Infoheader.biheight ;
        Largeur =  Mon_Entete.Infoheader.biwidth*3  ;

        for(Index_Ligne = 0; Index_Ligne < Hauteur; Index_Ligne++){
                for(Index_Colonne = 0; Index_Colonne < Largeur; Index_Colonne++){

                        Mon_Pixel.Bleu = Tableau[(Index_Ligne * Largeur) + Index_Colonne];
                        Index_Colonne++;
                        Mon_Pixel.Vert = Tableau[(Index_Ligne * Largeur) + Index_Colonne];
                        Index_Colonne++;
                        Mon_Pixel.Rouge = Tableau[(Index_Ligne * Largeur) + Index_Colonne];

                      if((Mon_Pixel.Bleu >= Pixel_Bleu_Fonce.Bleu)&& (Mon_Pixel.Bleu <= Pixel_Bleu_Clair.Bleu)
                      &&(Mon_Pixel.Vert >= Pixel_Bleu_Fonce.Vert)&&(Mon_Pixel.Vert <= Pixel_Bleu_Clair.Vert)
                      &&(Mon_Pixel.Rouge >= Pixel_Bleu_Fonce.Rouge)&&(Mon_Pixel.Rouge <= Pixel_Bleu_Clair.Rouge))
                        {Compteur_Pixels_Bleus++;
                        }
                }//Fin boucle Index_Colonne

                 if((Compteur_Pixels_Bleus > 15)&&(Compteur_Pixels_Bleus < 45)){
                   Compteur_Lignes_Bleus++;
                        if(Premiere_Ligne_Plaque == false){
                                Premiere_Ligne_Plaque = true;
                                Numero_Premiere_Ligne_Plaque = Index_Ligne;
                        }
                   }
                  Compteur_Pixels_Bleus = 0;
        }//Fin boucle Index_Ligne

         //cout<<"Lignes a Conserver : "<<Compteur_Lignes_Bleus<<endl;

//PARTIE 2
        //-------------------Redimenssionnement Hauteur-------------------------

        Numero_Derniere_Ligne_Plaque = Numero_Premiere_Ligne_Plaque + Compteur_Lignes_Bleus;
        Tableau_Hauteur_Redimensionnee = new unsigned char[Compteur_Lignes_Bleus * Largeur];

        for(Index_Ligne = Numero_Premiere_Ligne_Plaque; Index_Ligne < Numero_Derniere_Ligne_Plaque; Index_Ligne++){
                for(Index_Colonne = 0; Index_Colonne < Largeur; Index_Colonne++){

                        Tableau_Hauteur_Redimensionnee[(Compteur_Ligne * Largeur) + Index_Colonne] = Tableau[(Index_Ligne * Largeur) + Index_Colonne];
                        Index_Colonne++;
                        Tableau_Hauteur_Redimensionnee[(Compteur_Ligne * Largeur) + Index_Colonne] = Tableau[(Index_Ligne * Largeur) + Index_Colonne];
                        Index_Colonne++;
                        Tableau_Hauteur_Redimensionnee[(Compteur_Ligne * Largeur) + Index_Colonne] = Tableau[(Index_Ligne * Largeur) + Index_Colonne];

                }//Fin boucle Index_Colonne
                Compteur_Ligne++;
        }//Fin boucle Index_Ligne

        delete(Tableau);
        CloseHandle(Descripteur);

        //------------Initialisation En-Tête BMP et création fichier------------

        Mon_Entete.Fileheader.bfsize = 54 + (Largeur * Compteur_Lignes_Bleus);//Taille totale du fichier en octet
        Mon_Entete.Infoheader.biheight = Compteur_Lignes_Bleus;//Hauteur de l'image en pixel
        Mon_Entete.Infoheader.bisizeimage = Largeur * Compteur_Lignes_Bleus;//Taille de l'image en octet

        cout<<"Specifier un chemin et un nom d'enregistrement pour la plaque sans le haut et le bas : ";
        cin>>Nom_Fichier;
        Descripteur_Redimensionnement_Hauteur = CreateFile(Nom_Fichier,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);
        WriteFile(Descripteur_Redimensionnement_Hauteur, &Mon_Entete.Fileheader, (sizeof(BITMAPFILEHEADER) - 2), &Octets_Ecrits, NULL);
                //La soustraction par 2 est necessaire
                //à cause d'un problème lié à Borland 6, qui indique un valeur
                //erronée de 2 par rapport à la taille originale
        WriteFile(Descripteur_Redimensionnement_Hauteur, &Mon_Entete.Infoheader, sizeof(BITMAPINFOHEADER), &Octets_Ecrits, NULL);
        WriteFile(Descripteur_Redimensionnement_Hauteur, Tableau_Hauteur_Redimensionnee, Compteur_Lignes_Bleus * Largeur, &Octets_Ecrits, NULL);

        CloseHandle(Descripteur_Redimensionnement_Hauteur);

//PARTIE 3
        //----------------------Detection début plaque--------------------------

        Compteur_Pixels_Bleus = 0;
        Tableau_Position_Plaque = new unsigned int[Mon_Entete.Infoheader.biheight];

        for(Index_Ligne = 0; Index_Ligne < Mon_Entete.Infoheader.biheight; Index_Ligne++){
                for(Index_Colonne = 0; Index_Colonne < Largeur; Index_Colonne++){

                Mon_Pixel.Bleu = Tableau_Hauteur_Redimensionnee[(Index_Ligne * Largeur) + Index_Colonne];
                Index_Colonne++;
                Mon_Pixel.Vert = Tableau_Hauteur_Redimensionnee[(Index_Ligne * Largeur) + Index_Colonne];
                Index_Colonne++;
                Mon_Pixel.Rouge = Tableau_Hauteur_Redimensionnee[(Index_Ligne * Largeur) + Index_Colonne];

                if((Mon_Pixel.Bleu >= Pixel_Bleu_Fonce.Bleu)&& (Mon_Pixel.Bleu <= Pixel_Bleu_Clair.Bleu)
                      &&(Mon_Pixel.Vert >= Pixel_Bleu_Fonce.Vert)&&(Mon_Pixel.Vert <= Pixel_Bleu_Clair.Vert)
                      &&(Mon_Pixel.Rouge >= Pixel_Bleu_Fonce.Rouge)&&(Mon_Pixel.Rouge <= Pixel_Bleu_Clair.Rouge))
                        {Compteur_Pixels_Bleus++;
                        }

                if(Compteur_Pixels_Bleus > 15){
                        Nombre_Colonnes_Conservees++;
                }
                if(Compteur_Pixels_Bleus <= 15){
                        Compteur_Position++;
                }

                }//Fin boucle Index_Colonne

                Compteur_Position = (Compteur_Position - 15) * 3;//Memorise la position du debut de la plaque sur la ligne
                Tableau_Position_Plaque[Index_Ligne] = Compteur_Position;//On memorise la position dans un tableau
                Compteur_Position = 0;//Remise à 0 du compteur pour la prochaine ligne

                Compteur_Pixels_Bleus = 0;//Remise à 0 du nombre de bleu pour la prochaine ligne
                if(Index_Ligne == 0){
                        Nombre_Colonnes_Conservees_Final = Nombre_Colonnes_Conservees;}
                if(Nombre_Colonnes_Conservees_Final > Nombre_Colonnes_Conservees){
                        Nombre_Colonnes_Conservees_Final = Nombre_Colonnes_Conservees;}

                Nombre_Colonnes_Conservees = 0;

        }//Fin boucle Index_Ligne


        //------------------Suppression côté gauche plaque----------------------

                Nombre_Colonnes_Conservees_Final = (Nombre_Colonnes_Conservees_Final + 15) * 3;//Car on veut prendre en compte le bleu de la plaque donc 15 pixels de 3 octets chacuns
                Tableau_Sans_Cote_Gauche = new unsigned char[Mon_Entete.Infoheader.biheight * Nombre_Colonnes_Conservees_Final];

                int Tampon_Position;//Memorise les positions des premiers pixels qui sont conservées dans Tableau_Position_Plaque

                for(Index_Ligne = 0; Index_Ligne < Mon_Entete.Infoheader.biheight; Index_Ligne++){

                        Tampon_Position = Tableau_Position_Plaque[Index_Ligne];

                        for(Index_Colonne = 0; Index_Colonne < Nombre_Colonnes_Conservees_Final; Index_Colonne++){

                                Tableau_Sans_Cote_Gauche[(Index_Ligne * Nombre_Colonnes_Conservees_Final) + Index_Colonne] = Tableau_Hauteur_Redimensionnee[(Index_Ligne * Largeur) + Index_Colonne + Tampon_Position];
                                Index_Colonne++;
                                Tableau_Sans_Cote_Gauche[(Index_Ligne * Nombre_Colonnes_Conservees_Final) + Index_Colonne] = Tableau_Hauteur_Redimensionnee[(Index_Ligne * Largeur) + Index_Colonne + Tampon_Position];
                                Index_Colonne++;
                                Tableau_Sans_Cote_Gauche[(Index_Ligne * Nombre_Colonnes_Conservees_Final) + Index_Colonne] = Tableau_Hauteur_Redimensionnee[(Index_Ligne * Largeur) + Index_Colonne + Tampon_Position];
                        }//Fin boucle Index_Colonne

                }//Fin boucle Index_Ligne


        delete(Tableau_Hauteur_Redimensionnee);
        delete(Tableau_Position_Plaque);

        //------------Initialisation En-Tête BMP et création fichier------------

        Largeur = Nombre_Colonnes_Conservees_Final/3;

        Mon_Entete.Fileheader.bfsize = 54 + (Mon_Entete.Infoheader.biheight * Nombre_Colonnes_Conservees_Final);//Taille totale du fichier en octet
        Mon_Entete.Infoheader.biwidth = Largeur;//Largeur de l'image en pixel
        Mon_Entete.Infoheader.bisizeimage = Mon_Entete.Infoheader.biheight * Nombre_Colonnes_Conservees_Final;//Taille de l'image en octet


        cout<<"Specifier un chemin et un nom d'enregistrement pour la plaque sans cote gauche : ";
        cin>>Nom_Fichier;
        Descripteur_Suppression_Cote_Gauche = CreateFile(Nom_Fichier,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);
        WriteFile(Descripteur_Suppression_Cote_Gauche, &Mon_Entete.Fileheader, sizeof(BITMAPFILEHEADER) - 2, &Octets_Ecrits, NULL);
                //La soustraction par 2 est necessaire
                //à cause d'un problème lié à Borland 6, qui indique un valeur
                //erronée de 2 par rapport à la taille originale d'un fileheader
        WriteFile(Descripteur_Suppression_Cote_Gauche, &Mon_Entete.Infoheader, sizeof(BITMAPINFOHEADER), &Octets_Ecrits, NULL);
        WriteFile(Descripteur_Suppression_Cote_Gauche, Tableau_Sans_Cote_Gauche, Mon_Entete.Infoheader.biheight * Nombre_Colonnes_Conservees_Final, &Octets_Ecrits, NULL);

        CloseHandle(Descripteur_Suppression_Cote_Gauche);
        

        //----------------------------------------------------------------------

        getch();

        return 0;
}
        //----------------------------------------------------------------------


Merci d'avance =)


Cette discussion est classée dans : int, tableau, pixel, unsigned, plaque


Répondre à ce message

Sujets en rapport avec ce message

comment afficher un pixel en VGA ? [ par LedPaL ] Slt,je programme ac dev-cpp et j'arrive pas a afficher de pixels a l'écran !!! de l'aide plz !!voici un bout de ma source:unsigned char * ecran = (uns Tableau d'int à partir d'une CString [ par julien20vt ] Bonjour,J'utilise les MFC, et j'aimerais pouvoir remplir un tableau d'int à partir d'une variable de type CString formatée de la manière suivante :CSt Problème d'entrée (cin >>) dans un tableau de float [ par Oeil_de_taupe ] Hello tout le monde,désolé de vous importuné. Mais j'ai fait une toute petite source pour apprendre à allouer de la mémoire pour une variable puis de Création de 2 tableaux dynamik à 2D [ par flopflopp ] Bonjour, je voudrais soumettre un petit problème en C++, j'ai une simple fonction qui crée un tableau dynamique à 2 dimensions, le rempli avec des 1 e Retourner tableau 2d [ par ZogStriP ] J'ai une fonction qui retoure un tableau 2 dimension mais ça ne marche pas :int MultiMatrice(int Matrice1[2][2], int Matrice2[2][2]){ int MatriceRe comment affecter un tableau à un pointeur d'une classe? [ par cesdejong ] Bonjour,je débute un peu en C++ et je suis confronté à un problème pour lequel je ne trouve pas de solution élégante :class truc{...int* abscisse;int* problème Win32 Api [ par Toadstool ] J'ai Visual C++ 6 Introductory Edition et j'ai programmé une classe censée représenter une fenetre mais quand dans le constructeur de la classe j'ecri Allocation dynamique dans une fonction [ par Veovis ] Salut,Toujours dans mon projet de TP, j'ai un petit soucis avec l'allocation dynamique dans une fonction. Ce que je voudrais faire c'est quand le tabl alimenter un tableau d'entiers a partir d'une liste chainée [ par azkab ] bonjour a ts,j'ai une liste chainée qui contient les coordonées x,y d'un polygone. et je desire alimenter un tableau d'entiers a partir de ces données Comment forcer le RTS pour une liaison RS232 [ par ancat ] Bonjourje viens de faire un petit prog (grandement inspire de sources du site) mais je ne saisis pas trop le controle du RTS.Celui ci est-il traite pa


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,468 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales