IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenCV Discussion :

cvLoadImage depuis un tampon


Sujet :

OpenCV

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2007
    Messages : 8
    Par défaut cvLoadImage depuis un tampon
    Bonjour,

    Je cherche désespérément le moyen de charger une image (au format JPEG) depuis un buffer plutôt que depuis un fichier.

    J'ai d'abords pensé à la librairie libjpeg, mais le manque de tutoriels et de documentation ma légèrement refroidi... De plus, je n'ai trouvé aucune fonction pour charger une image autrement que depuis un fichier.

    Je ne cherche pas une solution toute faite mais si quelqu'un aurait une quelconque piste, je suis preneur !

    Merci d'avance,

    Sam

  2. #2
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    50
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 50
    Par défaut
    Qu'entends tu par charger une image au format JPEG a partir d'un buffer ?

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2007
    Messages : 8
    Par défaut
    J'utilise la librairie cURL pour charger une image au format JPEG depuis un serveur web. Une fois l'image chargée, j'ai un buffer contenant cette image.

    Le but serait donc de transformer ces informations brutes en IplImage afin de pouvoir les traiter avec OpenCV.

  4. #4
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    50
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 50
    Par défaut
    Tu crées une IplImage* img; et ensuite tu charges ton buffer (char*) dans le champ imageData de ta structure IplImage*

    img->imageData = buffer;

    C'est bien ce que tu cherches a faire ?

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2007
    Messages : 8
    Par défaut
    Oui, mais ce n'est pas possible directement comme cela, imageData contient un tableau de pixel (ou plus avec les channels). Or, mon buffer contient une image JPEG encore compressée.

    La fonction cvLoadImage se charge de parser un fichier pour déterminer son format (JPEG, PNG, ...) et toutes les composantes de l'image (Taille, channels, ...) et finalement de charger le tableau imageData avec les valeurs des pixels pour chaque channel.

    C'est ce que je cherche à faire, mais pas depuis un fichier. Evidemment je pourrais d'abords enregistrer mon image sur le disque dur et la relire ensuite, mais cela n'est pas propre et cela pose un sérieux problème de performances.

    Sam

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2007
    Messages : 8
    Par défaut
    J'ai trouvé une solution intermédiaire avec la librairie FreeImage (C++). Les méthodes utilisés sont les suivantes :

    FreeImage_OpenMemory
    FreeImage_GetFileTypeFromMemory
    FreeImage_LoadFromMemory

    A partir de là, on peut demander toutes les informations utiles de l'image (Largeur, hauteur, ...). Pour terminer, il faut parcourir pixel par pixel et inscrire la nouvelle valeur dans une structure IplImage.

    Sam

  7. #7
    Invité de passage
    Inscrit en
    Avril 2009
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 1
    Par défaut
    slt serious
    je suis en train de chercher une methode pour charger une image a partir de buffer, pouver vous me'xpliquer les methodes que vous avez utilisez , c mon projet de pfe et je rouve bcp des problémes pour realiser cette taches
    merci

  8. #8
    AR
    AR est déconnecté
    Futur Membre du Club
    Inscrit en
    Mai 2002
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 5
    Par défaut
    Bonjour,

    je cherche moi aussi la réponse a cette question.

    en fait j´ai actuellement une image au format Bayer_8 dont je connais toutes les caracteristiques : taille, channels, ... et le pointeur vers le buffer qui contient les donnees de l´image (en unsigned char *).

    si j´essaye de rentrer n´importe laquelle de ces donnees dans mon image IplImage* img, (avec "img->imageData = buffer;" ou "img->height=height;" par exemple), j´ai l´erreur suivante :
    "Unhandled exception at 0x00451d5d in AutoMode.exe: 0xC0000005: Access violation writing location 0x0000002c."

    j´ai alors essayé de faire lire directement ma camera a OpenCV ("CvCapture* img = cvCaptureFromCAM(-1);"), mais j´ai alors systematiquement une erreur dès le lancement du programme qui me dit : "The application failed to initialize properly (0xc0150002). Click OK to terminate the application"
    alors que je n´ai rajouté que cette ligne à mon programme...

    Ca fait plus d´une semaine que je suis coincé la dessus et je ne vois vraiment plus de solution à essayer, j´ai regardé tout les forum que j´ai pu et rien... si vous aviez une solution pour moi, vous m´aideriez ennormement !

    Merci

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2007
    Messages : 8
    Par défaut
    Bonjour,

    en fait j´ai actuellement une image au format Bayer_8 dont je connais toutes les caracteristiques : taille, channels, ... et le pointeur vers le buffer qui contient les donnees de l´image (en unsigned char *).

    si j´essaye de rentrer n´importe laquelle de ces donnees dans mon image IplImage* img, (avec "img->imageData = buffer;" ou "img->height=height;" par exemple), j´ai l´erreur suivante :
    "Unhandled exception at 0x00451d5d in AutoMode.exe: 0xC0000005: Access violation writing location 0x0000002c."
    Pour commencer, il est nécessaire de créer l'image avec la fonction « cvCreateImage ». Ensuite il récupérer le pointeur des données (pixels) avec « cvGetRawData » et inscrire manuellement la valeur des pixels.

    La documentation OpenCV est disponible ici avec une aide à la recherche des fonctions : http://www.cs.indiana.edu/cgi-pub/ol...te/OpenCVHelp/

    Un petit exemple de conversion depuis une image au format YUYV (avec l'attribut data initialisé avec « cvGetRawData ») :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    uchar *ptr, *ipl, y1, y2, u, v;
     
    // Initialize loop data pointers
    ipl = data;
    ptr = (uchar*) buffers[_index].start;
     
    // Loop over all image pixels
    while(ptr < (uchar*) buffers[_index].start + buffers[_index].length)
    {
    	// Retrieve YUYV values
    	y1 = *(ptr++);
    	u  = *(ptr++);
    	y2 = *(ptr++);
    	v  = *(ptr++);
     
    	// Write first BGR pixel value
    	*(ipl++) = y1 + 1.77200 * (u - 128);
    	*(ipl++) = y1 - 0.34414 * (u - 128) - 0.71414 * (v - 128);
    	*(ipl++) = y1 				        + 1.40200 * (v - 128);
     
    	// Write second BGR pixel value
    	*(ipl++) = y2 + 1.77200 * (u - 128);
    	*(ipl++) = y2 - 0.34414 * (u - 128) - 0.71414 * (v - 128);
    	*(ipl++) = y2 				        + 1.40200 * (v - 128);
    }
    j´ai alors essayé de faire lire directement ma camera a OpenCV ("CvCapture* img = cvCaptureFromCAM(-1);"), mais j´ai alors systematiquement une erreur dès le lancement du programme qui me dit : "The application failed to initialize properly (0xc0150002). Click OK to terminate the application"
    alors que je n´ai rajouté que cette ligne à mon programme...
    Quelle genre de caméra utilisez-vous ?

    Sam

  10. #10
    AR
    AR est déconnecté
    Futur Membre du Club
    Inscrit en
    Mai 2002
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 5
    Par défaut
    Merci beaucoup pour cette réponse très complète,

    j'utilise cette camera : http://www.vrmagic.com/no_cache/en/vrmc_4_pro/

    il se trouve que j'ai l'erreur : The application failed to initialize properly (0xc0150002). Click OK to terminate the application
    à chaque fois que j'essaye d'utiliser une fonction d'openCV, même cvCreateImage.
    J'ai peut être mal initialisé quelque chose, ou oublié une bibliothèque ?

    j'utilise Visual Studio 2008...

  11. #11
    AR
    AR est déconnecté
    Futur Membre du Club
    Inscrit en
    Mai 2002
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 5
    Par défaut
    hier, sur mon ordi perso (jusqu´à present je travaillais dans le labo de l´université), j´ai fait le programme expliqué là : http://www.site.uottawa.ca/~laganier...ow/cvision.htm

    chez moi ca marche tres bien, je peux ouvrir l´image, l´afficher et meme la modifier et l´afficher encore...

    ce matin je vais au labo avec mon programme d´hier : j´ai l´erreur :
    "The application failed to initialize properly (0xc0150002). Click OK to terminate the application"

    j´ai changé de PC dans le meme labo, tout installé et reconfiguré : pareil...

    la seule chose en commun sur ces deux PC c´est le driver de ma camera... es-ce qu´un driver de camera peut faire ce genre de probleme ?

    tant que je n´ai pas resolu ca, je ne peut pas tester cvCreateImage et cvGetRawData... (car bien sur je ne peux pas installer la camera du labo chez moi...........)

    merci pour votre aide et je vous tiens au courant !

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2007
    Messages : 8
    Par défaut
    J'ai peut être mal initialisé quelque chose, ou oublié une bibliothèque ?

    j'utilise Visual Studio 2008...
    Malheureusement, je suis très peu familier avec les séries « Visual Studio ». Cependant il est nécessaire que les DLL soit dans le chemin d'exécution. Essayez peut-être de les copier dans le même répertoire que l'exécutable et de lancer le programme depuis une invite de commande.

    la seule chose en commun sur ces deux PC c´est le driver de ma camera... es-ce qu´un driver de camera peut faire ce genre de probleme ?
    C'est effectivement peut-être une question de driver. On trouve cette phrase dans la documentation officielle : "Currently two camera interfaces can be used on Windows: Video for Windows (VFW) and Matrox Imaging Library (MIL)". Assurez vous que votre caméra est disponible via une des deux interfaces.

    Sinon l'autre chose qui me viendrait à l'esprit est l'architecture de votre système d'exploitation (32 ou 64bit).

  13. #13
    AR
    AR est déconnecté
    Futur Membre du Club
    Inscrit en
    Mai 2002
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 5
    Par défaut
    réponse à la question : l'application n'a pas pu n'initialiser correctement, ici :

    http://www.developpez.net/forums/d68...-correctement/

    (réponse, utiliser openCV1.0 au lieu du 1.1...)

    j'ai pas encore essayé, mais c'est un post "résolu", donc ça doit marcher !

    edit --> ca marche !!!

  14. #14
    AR
    AR est déconnecté
    Futur Membre du Club
    Inscrit en
    Mai 2002
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 5
    Par défaut
    sans grand espoir, j'ai directement contacté la société qui commercialise ma camera et ils m'ont donnés une réponse parfaite pour mon problème (en moins de 2h ! vive les petites boites !!!). C'est assez spécifique à ma camera, mais la méthode pour remplir le buffer doit pouvoir s'appliquer à d'autres cas, donc voilà la communication :

    question de ma part :
    "I am actually doing a project with one of your camera, (VRmC-4Pro), and because I need to do image processing with it, I would like to know if this camera is compatible with the computer vision librairie OpenCV ?
    Apparently, it´s not, but if it is, can you please let me know if there is something special to do to grab the frame directly from OpenCV ?

    Thank you for your help."

    réponse de leur part :

    "There are two possibilities to combine the openCV with our cameras.

    1) Without our API:
    Install and start CAMLAB, select DirectShow as renderer in the Preferences Menu. Save the settings to the camera and close CAMLAB.
    In your code that uses openCV the camera will then be found and recognized like an arbitrary webcam by creating a cvcapture.

    ...
    CvCapture* capture = cvCaptureFromCAM(0);
    IplImage* frame = cvRetrieveFrame(capture);
    ...
    This gets you the image, but without full access to all features of our image format and of the camera. In particular you have to start CAMLAB again to change camera parameters. If you just need picture and no further interaction with the camera, this works fine.


    2) Using our API:

    You can also convert from our image format VRmImage to the IplImage format by creating an IplImageHeader and setting the appropriate values and pointers.

    After grabbing the VRmImage* p_source_img with VRmUsbCamLockNextImage do the following:

    ...
    IplImage* p_dstIplImage=cvCreateImageHeader( cvSize(p_source_img->m_image_format.m_width,p_source_img->m_image_format.m_height) ,IPL_DEPTH_8U,1);
    p_dstIplImage->imageData = (char*) p_source_img->mp_buffer;
    p_dstIplImage->widthStep = p_source_img->m_pitch;
    ...

    The depth and the number of channels depends on the VRmImageFormat, the above is for single channel, 8bit gray images, adapt to three channels if necessary.

    Best regards"

    mon problème est donc résolu !

    merci s3RIoUs pour l'aide !

  15. #15
    Membre confirmé
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par défaut
    Dans la future version de openCV (celle dans le SVN) il y a une nouvelle function
    cvDecodeImage() qui permete de faire ca. le seul probleme c'est que je bosse en equipe et la migration vers openCV est prevu apres la realease de juin.

    ----

    Pour charger les image JPEG je en veux pas utiliser ta librarie car elle est trop grande, j'aimerais savoir si tu as testé avec libjpeg??? car moi j'ai un probleme pour l'instant!

  16. #16
    Membre confirmé
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par défaut
    pour charger avec libjpeg voici le code qu'il faut:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
     
    #include <jpeglib.h>
    #include <jerror.h>
     
     
    using namespace std;
     
    /*
     * Initialize source --- called by jpeg_read_header
     * before any data is actually read.
     */
     
    METHODDEF(void)
    init_source (j_decompress_ptr cinfo)
    {
    }
     
    /*
     * Fill the input buffer --- called whenever buffer is emptied.
     *
     * If this procedure gets called, we have a buffer overrun condition -
     * there is not enough data in the buffer to satisfy the decoder.
     * The procedure just generates a warning and feeds the decoder a fake
     * JPEG_EOI marker.
     */
     
    METHODDEF(boolean)
    fill_input_buffer (j_decompress_ptr cinfo)
    {
      struct jpeg_source_mgr * src = cinfo->src;
      static JOCTET FakeEOI[] = { 0xFF, JPEG_EOI };
     
      /* Generate warning */
      WARNMS(cinfo, JWRN_JPEG_EOF);
     
      /* Insert a fake EOI marker */
      src->next_input_byte = FakeEOI;
      src->bytes_in_buffer = 2;
     
      return TRUE;
    }
     
     
    METHODDEF(void)
    skip_input_data (j_decompress_ptr cinfo, long num_bytes)
    {
      struct jpeg_source_mgr * src = cinfo->src;
     
      if(num_bytes >= (long)src->bytes_in_buffer)
      {
        fill_input_buffer(cinfo);
        return;
      }
     
      src->bytes_in_buffer -= num_bytes;
      src->next_input_byte += num_bytes;
    }
     
     
    /*
     * Terminate source --- called by jpeg_finish_decompress
     * after all data has been read.  Often a no-op.
     *
     * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
     * application must deal with any cleanup that should happen even
     * for error exit.
     */
     
    METHODDEF(void)
    term_source (j_decompress_ptr cinfo)
    {
      /* no work necessary here */
    }
     
     
    int cvCvtJPEGToBGR(X7sNetFrame *netframe, IplImage *im) {
     
    	//Declare JPEG structure
    	struct jpeg_source_mgr jsrc;
    	struct jpeg_decompress_struct cinfo;
    	struct jpeg_error_mgr jerr;
     
     
    	if(im==NULL) {
    		printf("IplImage is NULL");
    		return -1;
    	}
     
    	//Initialize JPEG source
    	jsrc.bytes_in_buffer=netframe->data->length;
    	jsrc.next_input_byte=netframe->data->data;
     
    	//Setup function pointer
    	jsrc.init_source=init_source;
    	jsrc.fill_input_buffer = fill_input_buffer;
    	jsrc.skip_input_data = skip_input_data;
    	jsrc.resync_to_restart = jpeg_resync_to_restart; /* use default method */
    	jsrc.term_source = term_source;
     
     
     
    	//Initialize JPEG structure.
    	cinfo.err = jpeg_std_error(&jerr);
    	jpeg_create_decompress(&cinfo);
     
    	//Setup JPEG
    	cinfo.src=&jsrc;
     
    	//read the source datastream header markers
    	jpeg_read_header(&cinfo, TRUE);
    	jpeg_start_decompress(&cinfo);
     
     
    	if(im->width != (int)cinfo.output_width ||
    		im->height != (int)cinfo.output_height ||
    		im->nChannels != cinfo.num_components) {
    		cout << "Size changed" << endl;
    		return -1;
    	}
    	uint8_t* line = (uint8_t*)im->imageData;
     
    	//For each row
    	for(int r=0;r<im->height;r++) {
    		line+=im->widthStep;
    		jpeg_read_scanlines(&cinfo,(JSAMPARRAY)&line,1);
    	}
     
    	/* wrap up decompression, destroy objects, free pointers and close open files */
    	jpeg_finish_decompress( &cinfo );
    	jpeg_destroy_decompress( &cinfo );
     
           //Finally, convert the image to BGR
           cvConvertImage(im,im,CV_CVTIMG_SWAP_RB);
     
     
    	return 1;
    }

  17. #17
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2007
    Messages : 8
    Par défaut
    Citation Envoyé par elraton Voir le message
    Pour charger les image JPEG je en veux pas utiliser ta librarie car elle est trop grande, j'aimerais savoir si tu as testé avec libjpeg??? car moi j'ai un probleme pour l'instant!
    Non, j'utilise la librairie FreeImage. Voici un exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    unsigned width, height, pixel;
    	char *ptr;
    	BYTE *bits;
    	FIMEMORY *memory;
    	FREE_IMAGE_FORMAT fif;
    	FIBITMAP *check;
     
    	// FreeImage memory handle initialization from incoming buffer
    	memory = FreeImage_OpenMemory((BYTE*)(inputBuffer.data()), inputBuffer.size());
     
    	// Reading and parsing image header
    	fif = FreeImage_GetFileTypeFromMemory(memory, 0);
     
    	// Loading image from memory
    	check = FreeImage_LoadFromMemory(fif, memory, 0);
     
    	// Get the loaded image size
    	width = FreeImage_GetWidth(check);
    	height = FreeImage_GetHeight(check);
     
    	// Create image to copy content (in gray mode)
    	if(current == NULL)
    		current = cvCreateImage(cvSize(width, height), 8, 1);
     
    	// Get data pointer for searching pixel value
    	bits = (BYTE *)FreeImage_GetBits(check);
     
    	// Get data pointer for applying pixel value
    	ptr = current->imageData;
     
    	while(ptr < current->imageData + current->imageSize)
    	{
    		// Sum of pixels values in channels RGB
    		pixel  = *(bits++);
    		pixel += *(bits++);
    		pixel += *(bits++);
     
    		// Average of this sum is the gray value of current pixel
    		*(ptr++) = pixel / 3;
    	}
     
    	// Release memory allocation
    	FreeImage_Unload(check);
    	FreeImage_CloseMemory(memory);
     
    	// Erase incoming buffer
    	inputBuffer.clear();
    Sam

Discussions similaires

  1. [CR][VB6] Impression d'un état depuis VB
    Par sda dans le forum SDK
    Réponses: 3
    Dernier message: 06/02/2007, 17h27
  2. [TP]vider le tampon clavier
    Par kael kael dans le forum Turbo Pascal
    Réponses: 5
    Dernier message: 11/01/2003, 22h19
  3. [VB6] Savoir depuis VB, si un document Excel est ouvert
    Par Argonz dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 12/11/2002, 08h16
  4. Réponses: 1
    Dernier message: 22/08/2002, 17h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo