Отображение нескольких изображений в одном окне с OpenCV

У меня есть три FireWire-камеры, которые могут автоматически синхронизироваться через аппаратное обеспечение, и я пытаюсь захватывать кадры, сохранять их на моем жестком диске и отображать их в окне.

Все отлично работает, но на данный моментI'm only able to display frames in three different windows at the same time.

I'd like to display the frames in a single window но я не знаю как это сделать. В этотссылка на сайт есть функция 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);
        }
   }

Это работает хорошо, но создает разные окна для каждой камеры, в то время какI want to display all cameras frames in the same window.

Не могли бы вы мне помочь?

EDIT: this is the ConvertImageToOpenCV() function.

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

Ответы на вопрос(1)

Решение Вопроса

Я не смог протестировать приведенный ниже код по понятным причинам, но он иллюстрирует один подход:

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 изображениям и вы можете отображать их в одном окне.

EDIT:

Чтобы подвести итог приватного чата, проблема в том, чтоcvShowManyImages() снимал цветные (3-канальные) изображения, а его камера возвращала изображения в оттенках серого (одноканальные). Решение было просто изменить реализациюcvShowManyImages(), от:

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

Для того, чтобы:

DispImage = cvCreateImage( cvSize(100 + size*w, 60 + size*h), 8, 1 );
 Marcus Barnet01 июн. 2012 г., 18:40
Большое спасибо за все, Карл! Ты замечательный!
 Marcus Barnet01 июн. 2012 г., 15:37
Может быть, это потому, что cvShowManyImages () использует другой размер для изображений? На данный момент изображения, снятые с камер, имеют размер 1200x1800 пикселей.
 01 июн. 2012 г., 16:18
Я просто читаю код, и ваша функция не копирует данные, она просто копирует указатель, т. Е. Функция копирует адрес памяти, в котором находятся данные, но не сами данные. Я обновил свой код, вам лучше еще раз взглянуть на него.
 01 июн. 2012 г., 18:18
Это нормально, если они в оттенках серого. Эффект мигания решается путем размещения вызова cvWaitKey () сразу после cvShowManyImages (): это была ошибка, вызванная моим первым обновлением ответа.
 Marcus Barnet01 июн. 2012 г., 15:21
Большое спасибо за совет! Я попробовал это, он компилируется, но когда я запускаю его, я получаю эту ошибку: & quot; Ошибка OpenCV: Ошибка подтверждения & lt; src.type () == dist.type ()) в функции unkwon, файл imgproc \ src \ imgwarp.cpp строка 3234

Ваш ответ на вопрос