spacer.png, 0 kB

Torna indietro   Roboitalia.com - Il primo portale in Italia sulla robotica amatoriale > Robotica Avanzata > Informatica avanzata > OpenCV

Rispondi
 
Strumenti discussione Modalità  visualizzazioe
  #1  
Vecchio 09-06-2011, 09.20.46
MrSebastian MrSebastian non è collegato
Nuovo robottaro
 
Data registrazione: 09-06-2011
Residenza: Italia
Messaggi: 13
Potenza reputazione: 0
MrSebastian E' per ora ancora un mistero
Predefinito Errore con calibrazione a singola telecamera

Buongiorno a tutti,

ho un problema con una procedura di calibrazione a singola telecamera. La funzione è la seguente:

Codice:
static int singleChannelCalibration(CvCapture* cap, string l_r)
{

    CvCapture* capture = cap;

    int n_boards = 10; // number of boards necessary to calibrate
    int board_dt = 90; // Wait 90 frames per chessboard view
    int board_w = 9; // number of horizontal corners of the board
    int board_h = 6; // number of vertical corners of the board
    int number_of_points  = board_w * board_h; // total number of the corners

    CvSize board_sz = cvSize(board_w, board_h);

    if(!capture)
    {
        printf("\nCouldn't open the camera\n");
        return -1;
    }

    if(l_r == "L")
    {
        printf("Calibrazione telecamera left...\n");
        cvNamedWindow("Calibration Left");
        cvNamedWindow("Raw Video Left");
    }
    else
    {
        printf("Calibrazione telecamera right...\n");
        cvNamedWindow("Calibration Right");
        cvNamedWindow("Raw Video Right");
    }
    //ALLOCATE STORAGE
    CvMat* image_points       = cvCreateMat(n_boards*number_of_points,2,CV_32FC1);
    CvMat* object_points      = cvCreateMat(n_boards*number_of_points,3,CV_32FC1);
    CvMat* point_counts       = cvCreateMat(n_boards,1,CV_32SC1);
    CvMat* intrinsic_matrix   = cvCreateMat(3,3,CV_32FC1);
    CvMat* distortion_coeffs  = cvCreateMat(4,1,CV_32FC1);

    int corner_count;
    CvPoint2D32f* corners = new CvPoint2D32f[number_of_points];

    int successes = 0;
    int step, frame = 0;

    IplImage* image = cvQueryFrame(capture);
    IplImage* gray_image = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1);//subpixel

    // CAPTURE CORNER VIEWS LOOP UNTIL WE’VE GOT n_boards
    // SUCCESSFUL CAPTURES (ALL CORNERS ON THE BOARD ARE FOUND)

    while(successes < n_boards)
    {
        //Skip every board_dt frames to allow user to move chessboard
        if((frame++ % board_dt) == 0)
        {
            //Find chessboard corners:
            int found_left = cvFindChessboardCorners(image, board_sz, corners,
                    &corner_count, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);

            //Get Subpixel accuracy on those corners
            cvCvtColor(image, gray_image, CV_BGR2GRAY);

            cvFindCornerSubPix(gray_image, corners, corner_count, cvSize(11,11),cvSize(-1,-1),
                    cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 30, 0.1 ));

            //Draw it
            // cvDrawChessboardCorners(image_left, board_sz, corners_left, corner_count_left, found_left);
            cvDrawChessboardCorners(image, board_sz, corners, corner_count, found_left);

            // If we got a good board, add it to our data
            if( corner_count == number_of_points)
            {

                if(l_r == "L") cvShowImage( "Calibration Left", image);
                else cvShowImage( "Calibration Right", image);

                step = successes*number_of_points;
                for(int i=step, j=0; j<number_of_points; ++i,++j)
                {
                    // Left:
                    CV_MAT_ELEM(*image_points, float,i,0) = corners[j].x;
                    CV_MAT_ELEM(*image_points, float,i,1) = corners[j].y;
                    CV_MAT_ELEM(*object_points,float,i,0) = j/board_w;
                    CV_MAT_ELEM(*object_points,float,i,1) = j%board_w;
                    CV_MAT_ELEM(*object_points,float,i,2) = 0.0f;
                }
                CV_MAT_ELEM(*point_counts, int, successes,0) = number_of_points;
                successes++;
                printf("Collected our %d of %d needed chessboard images\n", successes, n_boards);
            }
            else
            {
                if(l_r == "L") cvShowImage( "Calibration Left", gray_image);
                else cvShowImage( "Calibration Right", gray_image);
            }
        } //end skip board_dt between chessboard capture

        //Handle pause/unpause and ESC
        int c = cvWaitKey(15);
        if(c == 'p')
        {
            c = 0;
            while(c != 'p' && c != 27)
            {
                c = cvWaitKey(250);
            }
        }
        if(c == 27)
        {
            return 0;
        }

        image = cvQueryFrame(capture); //Get next image
        // cvShowImage("Raw Video Left", image);
        if(l_r == "L") cvShowImage( "Raw Video Left", image);
        else cvShowImage( "Raw Video Right", image);

    } //END COLLECTION WHILE LOOP.

    printf("Esco dal ciclo while\n");

    cvDestroyWindow("Calibration");
    if(l_r == "L") cvDestroyWindow("Calibration Left");
    else cvDestroyWindow("Calibration Right");

    printf("\n\n*** CALIBRATING THE CAMERA...");
    //ALLOCATE MATRICES ACCORDING TO HOW MANY CHESSBOARDS FOUND
    CvMat* object_points2   = cvCreateMat(successes*number_of_points,3,CV_32FC1);
    CvMat* image_points2    = cvCreateMat(successes*number_of_points,2,CV_32FC1);
    CvMat* point_counts2    = cvCreateMat(successes,1,CV_32SC1);

    //TRANSFER THE POINTS INTO THE CORRECT SIZE MATRICES
    for(int i = 0; i<successes*number_of_points; ++i)
    {
        CV_MAT_ELEM( *image_points2, float, i, 0) =
                CV_MAT_ELEM( *image_points, float, i, 0);
        CV_MAT_ELEM( *image_points2, float,i,1) =
                CV_MAT_ELEM( *image_points, float, i, 1);
        CV_MAT_ELEM(*object_points2, float, i, 0) =
                CV_MAT_ELEM( *object_points, float, i, 0);
        CV_MAT_ELEM( *object_points2, float, i, 1) =
                CV_MAT_ELEM( *object_points, float, i, 1);
        CV_MAT_ELEM( *object_points2, float, i, 2) =
                CV_MAT_ELEM( *object_points, float, i, 2);
    }
    for(int i=0; i<successes; ++i)
    {
        // These are all the same number
        CV_MAT_ELEM( *point_counts2, int, i, 0) =
                CV_MAT_ELEM( *point_counts, int, i, 0);

    }

    cvReleaseMat(&object_points);
    cvReleaseMat(&image_points);
    cvReleaseMat(&point_counts);

    // At this point we have all of the chessboard corners we need.
    // Initialize the intrinsic matrix such that the two focal
    // lengths have a ratio of 1.0

    CV_MAT_ELEM(*intrinsic_matrix, float, 0, 0) = 1.0f;
    CV_MAT_ELEM(*intrinsic_matrix, float, 1, 1) = 1.0f;

    //CALIBRATE THE CAMERA!
    cvCalibrateCamera2(object_points2, image_points2, point_counts2,
            cvGetSize(image), intrinsic_matrix, distortion_coeffs, NULL,
            NULL,0  /*CV_CALIB_FIX_ASPECT_RATIO*/);


    // SAVE THE INTRINSICS AND DISTORTIONS
    printf(" *** DONE!\n\nStoring Intrinsics XML and Distortions XML files\n\n");

    if(l_r == "L")
    {
        cvSave("xml/IntrinsicsL.xml", intrinsic_matrix);
        cvSave("xml/DistortionL.xml", distortion_coeffs);
        cvDestroyWindow("Calibration Left");
        cvDestroyWindow("Raw Video Left");
    }
    else
    {
        cvSave("xml/IntrinsicsR.xml", intrinsic_matrix);
        cvSave("xml/DistortionR.xml", distortion_coeffs);
        cvDestroyWindow("Calibration Right");
        cvDestroyWindow("Raw Video Right");
    }

    cvReleaseMat(&intrinsic_matrix);
    cvReleaseMat(&distortion_coeffs);

    return 0;
}
In particolare, lancio la funzione singleChannelCalibration nel main della mia applicazione, prima per la camera destra, poi per quella sinistra.
Quindi:

Codice:
int res2 = singleChannelCalibration(capture_right, "R");
int res1 = singleChannelCalibration(capture_left, "L");
Per la prima chiamata tutto ok, per la seconda Eclipse lancia la seguente eccezione:

Codice:
Calibrazione telecamera left...
OpenCV ERROR: Null pointer (NULL array pointer is passed)
    in function cvGetMat, cxarray.cpp(2780)
Terminating the application...
    called from cvUnregisterType, cxpersistence.cpp(4933)
Terminating the application...
    called from cvUnregisterType, cxpersistence.cpp(4933)
Terminating the application...
    called from cvUnregisterType, cxpersistence.cpp(4933)
Terminating the application...
    called from cvUnregisterType, cxpersistence.cpp(4933)
Terminating the application...
    called from cvUnregisterType, cxpersistence.cpp(4933)
Terminating the application...
    called from cvUnregisterType, cxpersistence.cpp(4933)
Terminating the application...
    called from cvUnregisterType, cxpersistence.cpp(4933)
Terminating the application...
    called from cvUnregisterType, cxpersistence.cpp(4933)
Terminating the application...
    called from cvUnregisterType, cxpersistence.cpp(4933)
Terminating the application...
Idee? Suggerimenti? Ci sto sbattendo la testa da qualche giorno
Rispondi citando
  #2  
Vecchio 09-06-2011, 09.45.25
L'avatar di sergio_camici
sergio_camici sergio_camici non è collegato
Administrator
 
Data registrazione: 24-05-2002
Residenza: Binasco (MI)
Età : 58
Messaggi: 2,665
Potenza reputazione: 315
sergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua fama
Predefinito

Invertendo l'ordine delle due chiamate, l'errore segue la camera L o segue la posizione del codice?
__________________
ciao
Sergio
---
Hai deciso di costruire un robot? Bene...
Cominciamo dalle brutte notizie: non e' facile...
Rispondi citando
  #3  
Vecchio 09-06-2011, 09.47.47
MrSebastian MrSebastian non è collegato
Nuovo robottaro
 
Data registrazione: 09-06-2011
Residenza: Italia
Messaggi: 13
Potenza reputazione: 0
MrSebastian E' per ora ancora un mistero
Predefinito

Segue la posizione del codice, quindi invertendo l'ordine, lancia comunque l'eccezione sulla prima delle due chiamate...
Rispondi citando
  #4  
Vecchio 09-06-2011, 10.01.22
L'avatar di sergio_camici
sergio_camici sergio_camici non è collegato
Administrator
 
Data registrazione: 24-05-2002
Residenza: Binasco (MI)
Età : 58
Messaggi: 2,665
Potenza reputazione: 315
sergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua famasergio_camici La sua reputazione è oltre la sua fama
Predefinito

Allora il problema è in un If che gestisce male la L.
Non puoi seguirlo passo passo?
__________________
ciao
Sergio
---
Hai deciso di costruire un robot? Bene...
Cominciamo dalle brutte notizie: non e' facile...
Rispondi citando
  #5  
Vecchio 09-06-2011, 10.21.13
MrSebastian MrSebastian non è collegato
Nuovo robottaro
 
Data registrazione: 09-06-2011
Residenza: Italia
Messaggi: 13
Potenza reputazione: 0
MrSebastian E' per ora ancora un mistero
Predefinito

Si . Ho fatto il debug e probabilmente la chiamata che va in crash è questa:

Codice:
int found = cvFindChessboardCorners(image, board_sz, corners, &corner_count, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
Idee?
Rispondi citando
  #6  
Vecchio 09-06-2011, 10.31.58
MrSebastian MrSebastian non è collegato
Nuovo robottaro
 
Data registrazione: 09-06-2011
Residenza: Italia
Messaggi: 13
Potenza reputazione: 0
MrSebastian E' per ora ancora un mistero
Predefinito

... tra l'altro, spulciando il codice di cxarray.cpp alla riga 2780 (cioè il file al punto al quale si riferisce l'eccezione) trovo questo (riga in grassetto):

Codice:
// convert array (CvMat or IplImage) to IplImage
CV_IMPL IplImage*
cvGetImage( const CvArr* array, IplImage* img )
{
    IplImage* result = 0;
    const IplImage* src = (const IplImage*)array;
    int depth;
    if( !img )
        CV_Error( CV_StsNullPtr, "" );
    if( !CV_IS_IMAGE_HDR(src) )
    {
        const CvMat* mat = (const CvMat*)src;
        if( !CV_IS_MAT_HDR(mat))
            CV_Error( CV_StsBadFlag, "" );
        if( mat->data.ptr == 0 )
            CV_Error( CV_StsNullPtr, "" );
        depth = cvIplDepth(mat->type);
        cvInitImageHeader( img, cvSize(mat->cols, mat->rows),
                           depth, CV_MAT_CN(mat->type) );
        cvSetData( img, mat->data.ptr, mat->step );
        result = img;
    }
    else
    {
        result = (IplImage*)src;
    }
    return result;
}
Rispondi citando
  #7  
Vecchio 13-06-2011, 11.28.04
MrSebastian MrSebastian non è collegato
Nuovo robottaro
 
Data registrazione: 09-06-2011
Residenza: Italia
Messaggi: 13
Potenza reputazione: 0
MrSebastian E' per ora ancora un mistero
Wink

RISOLTO!

Il problema stava sulla variabile cap passata al metodo, che alla prima chiamata risultava aggiornata, mentre alla seconda chiamata conservava tuttii dati (quindi il video) catturato durante il tempo di elaborazione della prima chiamata.

Ho risolto modificando la procedura di calibrazione, non passando più cap come parametro, ma entrambi gli stream, quindi:

Codice:
static int singleChannelCalibration(CvCapture* cap_left, CvCapture* cap_right)
A questo punto, nella funzione, ho lasciato

Codice:
CvCapture* capture = cap_left;
per il canale sinistro, mentre per il trattamento del canale destro ho utilizzato

Codice:
CvCapture* capture_right = cvCreateFileCapture("http://nomeUtente:passwordUtente@IndirizzoIP/path_disco/video.mjpg");
in modo da iniziare la cattura soltanto dopo il trattamento del flusso del canale sinistro.

Per chiarimenti contattatemi!
Rispondi citando
Rispondi


Utenti attualmente attivi che stanno leggendo questa discussione: 1 (0 utenti e 1 ospiti)
 
Strumenti discussione
Modalità  visualizzazioe

Regole di scrittura
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code è Attivato
Le smilies sono Attivato
[IMG] è Attivato
Il codice HTML è Disattivato

Vai al forum

Discussioni simili
Discussione Autore discussione Forum Risposte Ultimo messaggio
calibrazione gino07 OpenCV 0 19-12-2011 14.27.44
Calibrazione Oscilloscopio I8080 Elettronica 0 16-05-2010 19.27.42
Calibrazione steroscopia lesto01 OpenCV 2 07-04-2010 23.26.16
calibrazione telecamera opecv marco79 OpenCV 6 14-11-2007 14.15.05
Calibrazione Bromografo saveriop Elettronica 18 05-11-2005 23.33.00


Tutti gli orari sono GMT. Adesso sono le: 14.09.56.


Basato su: vBulletin Versione 3.8.8
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
Realizzazione siti web Cobaltica Foligno
spacer.png, 0 kB