2012-06-01 89 views
3

我有三个火线摄像头,可以通过硬件自动同步,我试图捕捉帧,将它们保存到我的硬盘并将它们显示在窗口中。在OpenCV的同一窗口中显示多个图像

一切工作正常,但目前,我只能在三个不同的窗口同时显示帧

我想在单个窗口中显示帧但我不知道如何做到这一点。 在这link有cvShowManyImages()函数,但你必须同时传递三帧,但我有一个for()循环,它可以一次考虑一帧。

这是我使用的代码:

for (int j = 0; j < k_numImages; j++) 
    { 
     // Display the timestamps for all cameras to show that the image 
     // capture is synchronized for each image 
     for (unsigned int i = 0; i < numCameras; i++) 
     { 
      Image image; 
      error = ppCameras[i]->RetrieveBuffer(&image); 
      if (error != PGRERROR_OK) 
      { 
       PrintError(error); 
       return -1; 
      } 
      IplImage* destImage = ConvertImageToOpenCV(&image); 
      char titolo[50]; 
      sprintf(titolo, "titolo%d", i); 
      cvShowImage(titolo, destImage); 
      waitKey(1); 
     } 
    } 

它运作良好,但同时我想显示在同一窗口所有摄像机的帧中相机会创建一个不同的窗口。

你能帮助我吗?

编辑:这是ConvertImageToOpenCV()函数。

IplImage* ConvertImageToOpenCV(Image* pImage) 
{ 
    IplImage* cvImage = NULL; 
    bool bColor = true; 
    CvSize mySize; 
    mySize.height = pImage->GetRows(); 
    mySize.width = pImage->GetCols(); 

    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; 
} 

enter image description here

回答

2

我无法测试下面的代码,原因很明显,但它说明了一个办法:

for (int j = 0; j < k_numImages; j++) 
{ 
    // Display the timestamps for all cameras to show that the image 
    // capture is synchronized for each image 

    IplImage* destImage[3]; // A-ha moment 

    for (unsigned int i = 0; i < numCameras; i++) 
    { 
     Image image; 
     error = ppCameras[i]->RetrieveBuffer(&image); 
     if (error != PGRERROR_OK) 
     { 
      PrintError(error); 
      return -1; 
     } 

     /* Since ConvertImageToOpenCV() doesn't copy the image data, 
     * we need to do that ourselves, because when this loop is done Image 
     * is destroyed and the data is lost. 
     */ 
     IplImage* tmp = ConvertImageToOpenCV(&image); 
     destImage[i] = cvCreateImage(cvGetSize(tmp), tmp->depth, tmp->nChannels); 
     cvCopy(tmp, destImage[i], NULL); 

     char titolo[50]; 
     sprintf(titolo, "titolo%d", i); 
    } 

    cvShowManyImages("all", 3, destImage[0], destImage[1], destImage[2]); 
    waitKey(0); 

    // when you finish using them, release the allocated resources to prevent memory leaks 
    cvReleaseImage(&destImage[0]); 
    cvReleaseImage(&destImage[1]); 
    cvReleaseImage(&destImage[2]);     
} 

的想法是创建的IplImage*阵列来存储图像由相机检索,因此在循环之后,您可以访问所有这3个图像并能够在单个窗口上显示它们。

编辑:

只是为了总结出私人聊天,问题是cvShowManyImages()需要彩色(三通道)的图像,以及他的相机返航灰度(单通道)图像。解决的办法是简单地改变cvShowManyImages()实施,从:

DispImage = cvCreateImage(cvSize(100 + size*w, 60 + size*h), 8, 3); 

要:

DispImage = cvCreateImage(cvSize(100 + size*w, 60 + size*h), 8, 1); 
+0

非常感谢您的提示! 我试过了,它编译但是当我运行它时,我得到这个错误: “OpenCV错误:声明失败

+0

可能是因为cvShowManyImages()对图像使用了不同的大小?目前,从相机捕获的图像是1200x1800 px –

+0

一个问题:'ConvertImageToOpenCV()'复制整个图像还是简单地指定数据指针'destImage [i] - > imageData'?我当前的代码假设数据的副本是由'ConvertImageToOpenCV()'执行的。 – karlphillip

相关问题