Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2011
    Messaggi
    8

    [C] analisi dell'immagine - openCV

    Rieccomi.
    Avevo iniziato un lavoro di analisi dell'immagine in VB, ma avendo bisogno di una certa velocità mi sono reso conto che non era il linguaggio giusto e sono passato al C.

    Spiego brevemente quello che voglio fare: acquisisco l'immagine da una camera (formato 640x480 a colori), poi analizzo i pixel dellì'immagine (non mi dovrebbe servire analizzarli tutti, so dove si trova l'oggetto da analizzare), e conto e segnalo quei pixel che non rispettano una determinata relazione (molto semplice, una comparazione con una soglia, al massimo il rapporto tra la luminosità di due componenti).

    Seguendo un po' di esempi trovati qua e là ho capito come aprire le immagini, come prelevare i pixel accedendo direttamente in memoria (più veloce), e come creare una seconda immagine con le differenze evidenziate.

    Il mio problema adesso è che prelevando l'immagine dalla cam con cvQueryFrame poi non riesco ad accedere alla memoria relativa all'immagine e il programma mi crasha, mentre non avviene se per esempio prelevo una jpg in memoria con cvLoadImage. L'immagine di test ha le stesse dimensioni della risoluzione della cam e con l'immagine l'algoritmo funziona (è anche molto veloce, pur analizzando tutti i pixel dell'immagine).

    Questo è il codice che analizza l'immagine di test, e funziona:

    codice:
    #include <highgui.h>
    #include <cxcore.h>
    #include <cv.h>
    #include <stdio.h>
    
    int main (void)
    {
             //valori pixel
             int red, green, blue;
             //contatori
             int t;
             int CounterX, CounterY;
             //immagini
             IplImage *image_src;
             IplImage *image_dst;
             //finestre di lavoro
             cvNamedWindow("window src",CV_WINDOW_AUTOSIZE);
             cvNamedWindow("window dst",CV_WINDOW_AUTOSIZE);
    
             //apertura canale webcam
             CvCapture *capture;
             capture = cvCaptureFromCAM( 0 );
             //controllo capture valida
             if( !capture ) 
             { 
                    fprintf( stderr, "ERROR: capture is NULL \n"); 
                    getchar(); 
                    return -1; 
             } 
                     
             //preparazione immagini vuote per filtraggio (USATO PER ACQUISIRE LA CAM)
    //         image_src = cvCreateImage(cvSize(640,480), IPL_DEPTH_8U, 3); 
    //         image_dst = cvCreateImage(cvSize(640,480), IPL_DEPTH_8U, 3); 
    
             //prelievo immagine (USATO PER TEST CON IMMAGINE JPG)
             image_src=cvLoadImage("lena.jpg", 1);                  //carica l'immagine a colori
             image_dst=cvCreateImage(cvSize(image_src->width, image_src->height),
                                                IPL_DEPTH_8U, 3);
    
             t = 0;
             
             do
             {
                  // cattura un frame (USATO PER ACQUISIRE LA CAM)
    //             image_src = cvQueryFrame( capture ); 
    
                  //analisi pixel 
                  for (CounterY=0; CounterY<image_src->height; CounterY++)
                  {
                      for (CounterX=0; CounterX<image_src->width; CounterX++)
                      {
                         //lettura pixel da immagine sorgente
                         red = *((unsigned char*)(image_src->imageData +
                                   image_src->widthStep*CounterY) + 3*CounterX + 2);
                         green = *((unsigned char*)(image_src->imageData +
                                   image_src->widthStep*CounterY) + 3*CounterX + 1);
                         blue = *((unsigned char*)(image_src->imageData +
                                   image_src->widthStep*CounterY) + 3*CounterX + 0);
                         //analisi pixel
                         if (red/blue < 0.9)
                         {
                            red=255;
                            green=255;
                            blue=0;
                         }
                         //trasferimento pixel su immagine destinazione
                         *((unsigned char*)(image_dst->imageData +
                         image_dst->widthStep*CounterY) + 3*CounterX + 2) = red;
                         *((unsigned char*)(image_dst->imageData +
                         image_dst->widthStep*CounterY) + 3*CounterX + 1) = green;
                         *((unsigned char*)(image_dst->imageData +
                         image_dst->widthStep*CounterY) + 3*CounterX + 0) = blue;
                     }
                 }
                 //visualizzazione immagini
                 cvShowImage("window src", image_src);
                 cvShowImage("window dst", image_dst);
    
                 //contatore immagini visualizzate
                 t = t + 1;
                 printf ("%d\n", t);
                 //visualizzazione dimensione immagine
                 printf ("%d %d\n", CounterX, CounterY);
             }
             while ( (cvWaitKey(10) &255) != 27 );
             
             cvDestroyWindow("window src");
             cvDestroyWindow("window dst");
             
             cvReleaseCapture(&capture);
             cvReleaseImage(&image_dst);
             cvReleaseImage(&image_src);
    }
    Per acquisire la cam tolgo il commento alle 3 righe evidenziate (USATO PER ACQUISIRE LA CAM) e lo metto alle 2 righe che caricano l'immagine di test (USATO PER TEST CON IMMAGINE JPG). E il programma si blocca. L'errore è sulla lettura in memoria dell'immagine della cam, poichè se tolgo le istruzioni di lettura vedo correttamente l'immagine della cam nella prima finestra (nella seconda finestra ovviamente scrivo un colore unico).

    Ho paura che sia un problema di compatibilità con l'immagine creata con cvQueryFrame e la successiva lettura in memoria, ma non saprei...

    Qualche consiglio?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,468
    Quello che mi viene in mente è che il frame catturato non abbia le caratteristiche che tu pensi che debba avere nel tuo programma (640 x 480 IPL_DEPTH_8U) ...

    Dovresti cercare di ottenere (non so con quale funzione) le caratteristiche del frame letto.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2011
    Messaggi
    8
    Ehmmm... problema trovato!

    Prima di effettuare la divisione red/blue, un controllino se blue è uguale a zero ci stava bene...

    Sono troppo abituato ai microcontrollori, quelli non crashano mai...

    Adesso funziona tutto!

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,468
    Originariamente inviato da Bit79

    Sono troppo abituato ai microcontrollori, quelli non crashano mai...
    Anche per i micro la divisione per zero è vietata quindi, anche se non noti il crash, i risultati sono imprevedibili (ed è anche peggio ...).
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2011
    Messaggi
    8
    Pausa necessaria per attendere l'arrivo di una telecamera decente, con la webcam più di qualche prova non si poteva fare.

    Adesso la telecamera è arrivata, fortunatamente viene regolarmente riconosciuta dal software, e vorrei decidere definitivamente una strategia su come impostare il lavoro.

    All'inizio avevo provato a lavorare in visual basic, perchè lo conosco già un pochino e perchè mi permette di realizzare facilmente un intefaccia utente abbastanza semplice. Risultava però eccessivamente lento (qui però forse bisognerebbe vedere se si può migliorare).

    Ho poi riscritto il programma in C++, e qui la velocità è buona. L'applicazione che ho fatto per adesso gira però in console application (la finestra nera tipo dos per intenderci... ) è mi resta difficoltoso realizzare una interfaccia utente abbastanza friendly, preferirei qualcosa tipo visual basic.

    Mantenendo le prestazioni del C++, su cosa mi potrei orientare per realizzare una buona interfaccia utente in tema windows? Visual C++ potrebbe andare bene? Perdo di prestazioni? E' simile a visual basic?

    La differenza principale che ho notato tra il visual basic è il C++ è che in VB le varie routine vengono eseguite a seguito di eventi ben precisi e non esiste (o almeno non so come farla) una routine principale che gira sempre, quindi dovevo chiamare la routine di analisi con un timer ciclico (forse se avessi un evento sincronizzato con i frame provenienti dalla telecamera... ma sono comunque lento nell'esecuzione), mentre in C++ ho un programma main che gira sempre, senza dover essere chiamato. In visual C++ è ancora così?
    Altri suggerimenti? Non vorrei mettermi a studiare un linguaggio che poi si rivela non adatto... ho già studiato il C per ora....

    Ciao e grazie a tutti!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.