2012-06-01 68 views
3

我用三個ptgrey攝像機獲取圖像,並將它們保存到我的硬盤。 我使用的MultiCameraWriteToDiskEx例子,它的偉大工程,但我還想在採集過程來顯示圖像,所以我想FlyCapture圖像轉換爲readeable OpenCV的格式,以便與cvShowImage()或imshow向他們展示()功能。轉換無符號字符*到FlyCapture2圖片爲cvShowImage OpenCV的

我有一個函數IplImage* ConvertImageToOpenCV(Image* pImage)可以Flycapture2圖片*轉換爲OpenCV的IplImage結構*,但我不知道如何正確地轉換成無符號字符*到FlyCapture2 ::圖片*在doGrabLoop()函數從相機捕獲幀。

你能幫助我嗎?我不太瞭解C/C++ :( 特別是,我不知道如何轉換g_arImageplus [uiCamera] .image.pData以將其傳遞給ConvertImageToOpenCV()。 (是否正確使用g_arImageplus [uiCamera] .image.pData)

IplImage* ConvertImageToOpenCV(Image* pImage) 
{ 
    IplImage* cvImage = NULL; 
    bool bColor = true; 
    CvSize mySize; 
    mySize.height = pImage->GetRows(); 
    mySize.width = pImage->GetCols(); 
    printf("ciao %d\n", pImage->GetPixelFormat()); 
    switch (pImage->GetPixelFormat()) 
    { 
     case PIXEL_FORMAT_MONO8:  cvImage = cvCreateImageHeader(mySize, 8, 1); 
            cvImage->depth = IPL_DEPTH_8U; 
            cvImage->nChannels = 1; 
            bColor = false; 
            break; 
     case PIXEL_FORMAT_411YUV8: cvImage = cvCreateImageHeader(mySize, 8, 3); 
            cvImage->depth = IPL_DEPTH_8U; 
            cvImage->nChannels = 3; 
            break; 
     case PIXEL_FORMAT_422YUV8: cvImage = cvCreateImageHeader(mySize, 8, 3); 
            cvImage->depth = IPL_DEPTH_8U; 
            cvImage->nChannels = 3; 
            break; 
     case PIXEL_FORMAT_444YUV8: cvImage = cvCreateImageHeader(mySize, 8, 3); 
            cvImage->depth = IPL_DEPTH_8U; 
            cvImage->nChannels = 3; 
            break; 
     case PIXEL_FORMAT_RGB8:  cvImage = cvCreateImageHeader(mySize, 8, 3); 
            cvImage->depth = IPL_DEPTH_8U; 
            cvImage->nChannels = 3; 
            break; 
     case PIXEL_FORMAT_MONO16: cvImage = cvCreateImageHeader(mySize, 16, 1); 
            cvImage->depth = IPL_DEPTH_16U; 
            cvImage->nChannels = 1; 
            bColor = false; 
            break; 
     case PIXEL_FORMAT_RGB16:  cvImage = cvCreateImageHeader(mySize, 16, 3); 
            cvImage->depth = IPL_DEPTH_16U; 
            cvImage->nChannels = 3; 
            break; 
     case PIXEL_FORMAT_S_MONO16: cvImage = cvCreateImageHeader(mySize, 16, 1); 
            cvImage->depth = IPL_DEPTH_16U; 
            cvImage->nChannels = 1; 
            bColor = false; 
            break; 
     case PIXEL_FORMAT_S_RGB16: cvImage = cvCreateImageHeader(mySize, 16, 3); 
            cvImage->depth = IPL_DEPTH_16U; 
            cvImage->nChannels = 3; 
            break; 
     case PIXEL_FORMAT_RAW8:  cvImage = cvCreateImageHeader(mySize, 8, 3); 
            cvImage->depth = IPL_DEPTH_8U; 
            cvImage->nChannels = 3; 
            break; 
     case PIXEL_FORMAT_RAW16:  cvImage = cvCreateImageHeader(mySize, 8, 3); 
            cvImage->depth = IPL_DEPTH_8U; 
            cvImage->nChannels = 3; 
            break; 
     case PIXEL_FORMAT_MONO12: printf("Not supported by OpenCV"); 
            bColor = false; 
            break; 
     case PIXEL_FORMAT_RAW12:  printf("Not supported by OpenCV"); 
            break; 
     case PIXEL_FORMAT_BGR:  cvImage = cvCreateImageHeader(mySize, 8, 3); 
            cvImage->depth = IPL_DEPTH_8U; 
            cvImage->nChannels = 3; 
            break; 
     case PIXEL_FORMAT_BGRU:  cvImage = cvCreateImageHeader(mySize, 8, 4); 
            cvImage->depth = IPL_DEPTH_8U; 
            cvImage->nChannels = 4; 
            break; 
     case PIXEL_FORMAT_RGBU:  cvImage = cvCreateImageHeader(mySize, 8, 4); 
            cvImage->depth = IPL_DEPTH_8U; 
            cvImage->nChannels = 4; 
            break; 
     default: printf("Some error occured...\n"); 
       return NULL; 
    } 

    if(bColor) { 
     if(!bInitialized) 
     { 
      colorImage.SetData(new unsigned char[pImage->GetCols() * pImage->GetRows()*3], pImage->GetCols() * pImage->GetRows()*3); 
      bInitialized = true; 
     } 

     pImage->Convert(PIXEL_FORMAT_BGR, &colorImage); //needs to be as BGR to be saved 

     cvImage->width = colorImage.GetCols(); 
     cvImage->height = colorImage.GetRows(); 
     cvImage->widthStep = colorImage.GetStride(); 

     cvImage->origin = 0; //interleaved color channels 

     cvImage->imageDataOrigin = (char*)colorImage.GetData(); //DataOrigin and Data same pointer, no ROI 
     cvImage->imageData   = (char*)(colorImage.GetData()); 
     cvImage->widthStep  = colorImage.GetStride(); 
     cvImage->nSize = sizeof (IplImage); 
     cvImage->imageSize = cvImage->height * cvImage->widthStep; 
    } 
    else 
    { 
     cvImage->imageDataOrigin = (char*)(pImage->GetData()); 
     cvImage->imageData   = (char*)(pImage->GetData()); 
     cvImage->widthStep   = pImage->GetStride(); 
     cvImage->nSize    = sizeof (IplImage); 
     cvImage->imageSize   = cvImage->height * cvImage->widthStep; 

     //at this point cvImage contains a valid IplImage 
    } 
    return cvImage; 
} 

// 
// Grab and test loop 
// 
int doGrabLoop() 
{ 
    FlyCaptureError error = FLYCAPTURE_FAILED; 
    unsigned int  aruiPrevSeqNum[ _MAX_CAMERAS ]; 
    unsigned int  aruiDelta[ _MAX_CAMERAS ]; 
    unsigned int  aruiCycles[ _MAX_CAMERAS ]; 
    HANDLE  arhFile[ _MAX_CAMERAS ]; 
    DWORD   ardwBytesWritten[ _MAX_CAMERAS ]; 
    DWORD   dwTotalKiloBytesWritten = 0; 
    bool   bMissed = false; 
    bool   bOutOfSync = false; 
    unsigned int  uiMissedImages = 0; 
    unsigned int  uiOutOfSyncImages = 0; 
    __int64  nStartTime = 0; 
    __int64  nEndTime = 0; 
    __int64  nDifference = 0; 
    __int64  nTotalTime = 0; 
    __int64  nGlobalStartTime = 0; 
    __int64  nGlobalEndTime = 0; 
    __int64  nGlobalTotalTime = 0; 
    __int64  nFrequency = 0; 

    QueryPerformanceFrequency((LARGE_INTEGER*)&nFrequency); 
    QueryPerformanceCounter((LARGE_INTEGER*)&nGlobalStartTime); 

    printf("Starting grab...\n"); 

    // Create files to write to 
    if (createFiles(arhFile) != 0) 
    { 
     printf("There was error creating the files\n"); 
     return -1; 
    } 

    BOOL bSuccess; 

    // 
    // Start grabbing the images 
    // 

    for(int iImage = 0; iImage < g_iNumImagesToGrab; iImage++) 
    { 
#ifdef _VERBOSE 
     printf("Grabbing image %u\n", iImage); 
#else 
     printf("."); 
#endif 

     unsigned int uiCamera = 0; 

     // Grab an image from each camera 
     for(uiCamera = 0; uiCamera < g_uiNumCameras; uiCamera++) 
     { 
    error = flycaptureLockNext(g_arContext[uiCamera], &g_arImageplus[uiCamera]); 
     _HANDLE_ERROR(error, "flycaptureLockNext()"); 

    // Save image dimensions & bayer info from first image for each camera 
    if(iImage == 0) 
    { 
     g_arImageTemplate[uiCamera] = g_arImageplus[uiCamera].image; 

     error = flycaptureGetColorTileFormat(g_arContext[uiCamera], &g_arBayerTile[uiCamera]); 
     _HANDLE_ERROR(error, "flycaptureGetColorTileFormat()"); 
    } 
     } 

     for(uiCamera = 0; uiCamera < g_uiNumCameras; uiCamera++) 
     {  
    // Start timer 
    QueryPerformanceCounter((LARGE_INTEGER*)&nStartTime); 

    // Calculate the size of the image to be written 
    int iImageSize = 0;  
    int iRowInc = g_arImageplus[uiCamera].image.iRowInc; 
    int iRows = g_arImageplus[uiCamera].image.iRows; 
    iImageSize = iRowInc * iRows; 
// ERROR: HOW CAN I CONVERT g_arImageplus[ uiCamera ].image.pData IN ORDER TO USE IT WITH ConvertImageToOpenCV() function? 
    IplImage* destImage = ConvertImageToOpenCV(g_arImageplus[ uiCamera ].image.pData); 

     cvShowImage("prova", destImage); 


    waitKey(1); 

    // Write to the file 
    bSuccess = WriteFile(
     arhFile[uiCamera], 
     g_arImageplus[ uiCamera ].image.pData, 
     iImageSize, 
     &ardwBytesWritten[uiCamera], 
     NULL); 

    // End timer 
    QueryPerformanceCounter((LARGE_INTEGER*)&nEndTime); 

    // Ensure that the write was successful 
    if (!bSuccess || (ardwBytesWritten[uiCamera] != (unsigned)iImageSize)) 
    { 
     printf("Error writing to file for camera %u!\n", uiCamera); 
     return -1; 
    } 

    // Update various counters 
    dwTotalKiloBytesWritten += (ardwBytesWritten[uiCamera]/1024); 
    nDifference = nEndTime - nStartTime; 
    nTotalTime += nDifference; 

    // Keep track of the difference in image sequence numbers (uiSeqNum) 
    // in order to determine if any images have been missed. A difference 
    // greater than 1 indicates that an image has been missed. 
     if(iImage == 0) 
     { 
     // This is the first image, set up the variables 
      aruiPrevSeqNum[uiCamera] = g_arImageplus[uiCamera].uiSeqNum; 
      aruiDelta[uiCamera] = 1; 
     } 
     else 
     { 
     // Get the difference in sequence numbers between the current 
     // image and the last image we received 
      aruiDelta[uiCamera] = 
       g_arImageplus[uiCamera].uiSeqNum - aruiPrevSeqNum[uiCamera]; 
     }   

     if(aruiDelta[uiCamera] != 1) 
     { 
      // We have missed an image. 
     bMissed = true; 
      uiMissedImages += aruiDelta[uiCamera] - 1; 
     } 
    else 
    { 
     bMissed = false; 
    } 

     aruiPrevSeqNum[uiCamera] = g_arImageplus[uiCamera].uiSeqNum; 

    // Calculate the cycle count for the camera 
     aruiCycles[uiCamera] = 
      g_arImageplus[uiCamera].image.timeStamp.ulCycleSeconds * 8000 + 
      g_arImageplus[uiCamera].image.timeStamp.ulCycleCount; 

    // Determine the difference of the timestamp for every image from the 
    // first camera. If the difference is greater than 1 cycle count, 
    // register the camera as being out of synchronization. 
    int iDeltaFrom0 = abs((int)(aruiCycles[uiCamera] - aruiCycles[0])); 

     if((iDeltaFrom0 % (128 * 8000 - 1)) > 1) 
     { 
     bOutOfSync = true; 
     uiOutOfSyncImages++; 
    } 
    else 
    { 
     bOutOfSync = false; 
    } 

#ifdef _VERBOSE 
    // Output is in the following order: 
    // - The index of the image being captured 
    // - The index of the camera that is currently being captured 
    // - The time taken to write the image to disk 
    // - Number of kilobytes written 
    // - Write speed (in MB/s) 
    // - Sequence number 
    // - Cycle seconds in timestamp 
    // - Cycle count in timestamp 
    // - Delta from 0th value 
    // - Missed an image? 
    // - Out of sync? 
    printf( 
     "%04d: \t%02u\t%0.5f\t%.0lf\t%.2lf\t%04u\t%03u.%04u\t%d\t%s %s\n", 
     iImage, 
     uiCamera, 
     nDifference, 
     (double)ardwBytesWritten[ uiCamera ]/1024.0, 
     (double)ardwBytesWritten[ uiCamera ]/(1024 * 1024 * nDifference), 
     g_arImageplus[ uiCamera ].uiSeqNum, 
     g_arImageplus[ uiCamera ].image.timeStamp.ulCycleSeconds, 
      g_arImageplus[ uiCamera ].image.timeStamp.ulCycleCount, 
     iDeltaFrom0, 
     bMissed ? "Y" : "N", 
     bOutOfSync ? "Y" : "N"); 
#endif 
     } 

     // Unlock image, handing the buffer back to the buffer pool. 
     for(uiCamera = 0; uiCamera < g_uiNumCameras; uiCamera++) 
     { 
     error = flycaptureUnlock( 
      g_arContext[uiCamera], g_arImageplus[uiCamera].uiBufferIndex); 
     _HANDLE_ERROR(error, "flycaptureUnlock()"); 
     } 
    } 

    // 
    // Done grabbing images 
    // 

    QueryPerformanceCounter((LARGE_INTEGER*)&nGlobalEndTime); 
    nGlobalTotalTime = nGlobalEndTime - nGlobalStartTime; 

    double dGlobalTotalTime = (double)nGlobalTotalTime/(double)nFrequency; 
    double dTotalTime = (double)nTotalTime/(double)nFrequency; 

    // Report on the results 
    // Burst time is the time that was spent writing to disk only 
    // Overall time is total time taken, including image grabs, calculations etc 
    printf( 
     "\nBurst: Wrote %.1lfMB in %0.2fs (%.2lfMB/sec)\n", 
     (double)(dwTotalKiloBytesWritten/1024), 
     dTotalTime, 
     (double)(dwTotalKiloBytesWritten/(1024 * dTotalTime))); 

    printf(
     "Overall: Wrote %.1lfMB in %0.2fs (%.2lfMB/sec)\n", 
     (double)(dwTotalKiloBytesWritten/1024), 
     dGlobalTotalTime, 
     (double)(dwTotalKiloBytesWritten/(1024 * dGlobalTotalTime))); 

    printf(g_bSyncSuccess ? "Sync success\n" : "Sync failed\n"); 
    printf("Missed images = %u.\n", uiMissedImages); 
    printf("Out of sync images = %u.\n", uiOutOfSyncImages); 

    for (unsigned int uiCamera = 0; uiCamera < g_uiNumCameras; uiCamera++) 
    { 
     // Close file handles 
     CloseHandle(arhFile[uiCamera]); 
    } 

    return 0; 
} 
+0

謝謝你的代碼:-) –

回答

1

您的轉換方法:

IplImage* ConvertImageToOpenCV(Image* pImage) 

拍攝圖像指針構造一個新的形象。如果你使用從你的數據傳遞給它Here's the doc for the Image class.。此功能,它不會守住緩衝或複製:

Image ( unsigned int rows, 
      unsigned int cols, 
      unsigned int stride, 
      unsigned char* pData, 
      unsigned int dataSize, 
      PixelFormat  format, 
      BayerTileFormat bayerFormat = NONE 
) 

所以,你的代碼看起來是這樣的:

// Pull these values from your other image structure 
Image image(rows, cols, stride, pData, dataSize, format, bayerFormat); 

// Pass the address of the temporary image to your conversion 
IplImage* opencvImage = ConvertImageToOpenCV(&image); 
相關問題