使用BlackMagic SDK获取左右框架并将其转换为opencv mat

时间:2017-01-04 14:18:43

标签: c++ opencv

我目前正在尝试在Linux上使用带有DeckLink 4K pro卡的Stero相机使用BlackMagic SDK。 我已经将它用于单眼镜头并成功获取图像并将其转换为opencv :: mat但无论我尝试使用哪一个,我只有空左边的矩阵对应左边和右边的帧。我怀疑我使用的模式和/或标志存在问题,但我无法弄明白......当我尝试使用mediaExpress查看帧时,我得到了令人满意的结果,所以我猜这不是硬件问题。

我尝试做一些看起来像SDK给出的不同样本的东西,然后我在opencv mat中转换最终帧以查看结果。什么时候!isStereo,eveything顺利进行,我得到了左右帧的融合,但是如果它是真的,我的左右帧都有空矩阵。

这是我的代码的相应部分(评论的内容是我尝试过的东西:最后,我几乎可以肯定它是与我在g_deckLinkInput->中使用的标志链接的东西; EnableVideoInput(...) ):

...

void VideoInputFromBlackMagic::runInput(){

this->running=true;

int m_deckLinkIndex;
int idx;

//Check result
HRESULT result;

IDeckLink* deckLink = NULL;
IDeckLinkInput* g_deckLinkInput = NULL;
IDeckLinkAttributes* deckLinkAttributes = NULL;
IDeckLinkIterator* deckLinkIterator = CreateDeckLinkIteratorInstance();
IDeckLinkInputCallback* callBack;
IDeckLinkDisplayModeIterator* displayModeIterator = NULL;
IDeckLinkDisplayMode* displayMode = NULL;

char* displayModeName = NULL;
BMDDisplayModeSupport displayModeSupported;
bool formatDetectionSupported;

if (!deckLinkIterator)
{
  fprintf(stderr, "This application requires the DeckLink drivers installed.\n");
  return;
} 

//Get the DeckLink Inputs
result = deckLinkIterator->Next(&deckLink);
result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&g_deckLinkInput);

if(result != S_OK){
  fprintf(stdout, "Cannot get the Input : DeckLink Error\n");
  return;
} 

//Get the DeckLink attributes (that may not correctly work: format detection does not properly work)
result = deckLink->QueryInterface(IID_IDeckLinkAttributes, (void**)&deckLinkAttributes);

if (!(result == S_OK)){
  fprintf(stdout, "Cannot get the DeckLink attributes : DeckLink Error\n");
  return;
}

//Format detection
result = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &formatDetectionSupported);
if (result != S_OK || !formatDetectionSupported){
  fprintf(stdout,"Cannot get the format input: DeckLink Error\n");
  return;
} 

//Index for the different inputs
idx = 0;

//Get all the displayModes
result = g_deckLinkInput->GetDisplayModeIterator(&displayModeIterator);

if (result != S_OK){
  fprintf(stdout,"Cannot set an iterator on the different display modes: DeckLink Error\n");
}

//Set idx
while ((result = displayModeIterator->Next(&displayMode)) == S_OK)
{

  if (idx == 0)
     break;
  --idx;   
  displayMode->Release();

}

if (result != S_OK || displayMode == NULL){

  fprintf(stdout,"Cannot get the main display mode: DeckLink Error\n");
  return;

} 

//Get Mode name: useless
result = displayMode->GetName((const char**)&displayModeName);

// Check display mode is supported with given options
if(this->isStereo){
  //result = g_deckLinkInput->DoesSupportVideoMode(bmdModeHD1080p30, bmdFormat8BitYUV, bmdDisplayModeSupports3D | bmdDisplayModeColorspaceRec709, &displayModeSupported, NULL);
  //result = g_deckLinkInput->DoesSupportVideoMode(bmdModeHD1080p30, bmdFormat8BitYUV, bmdDisplayModeColorspaceRec709 & bmdDisplayModeSupports3D, &displayModeSupported, NULL);
  result = g_deckLinkInput->DoesSupportVideoMode(bmdModeHD1080p30, bmdFormat8BitYUV, bmdVideoInputDualStream3D, &displayModeSupported, NULL);
  //result = g_deckLinkInput->DoesSupportVideoMode(bmdModeHD1080p30, bmdFormat8BitYUV, bmdDisplayModeColorspaceRec709 | bmdVideoInputDualStream3D, &displayModeSupported, NULL);
} else {
  result = g_deckLinkInput->DoesSupportVideoMode(bmdModeHD1080p30, bmdFormat8BitYUV, bmdDisplayModeColorspaceRec709, &displayModeSupported, NULL);
}

if (result != S_OK){
  fprintf(stdout,"Video Mode not supported : aborted\n");
  return;
} 


if (displayModeSupported == bmdDisplayModeNotSupported)
{
  fprintf(stdout, "The display mode %s is not supported with the selected pixel format\n", displayModeName);
  return;

} 

//Set the callback on this ( will defined callback on VideoInputFrameArrived and others functions when images arrives or when other events happens
g_deckLinkInput->SetCallback(this);

//Enable the video input with the selected format
if(this->isStereo){
  //result = g_deckLinkInput->EnableVideoInput(bmdModeHD1080p30, bmdFormat8BitYUV, bmdDisplayModeSupports3D | bmdDisplayModeColorspaceRec709);
  //result = g_deckLinkInput->EnableVideoInput(bmdModeHD1080p30, bmdFormat8BitYUV, bmdDisplayModeColorspaceRec709 & bmdDisplayModeSupports3D);
  result = g_deckLinkInput->EnableVideoInput(bmdModeHD1080p30, bmdFormat8BitYUV, bmdVideoInputDualStream3D);
  //result = g_deckLinkInput->EnableVideoInput(bmdModeHD1080p30, bmdFormat8BitYUV, bmdDisplayModeColorspaceRec709 | bmdVideoInputDualStream3D);
  //result = g_deckLinkInput->EnableVideoInput(bmdModeHD1080p30, bmdFormat8BitYUV, bmd3DPreviewFormatRightOnly);
} else {
  result = g_deckLinkInput->EnableVideoInput(bmdModeHD1080p30, bmdFormat8BitYUV, bmdDisplayModeColorspaceRec709);
}

if (result != S_OK)
{
  fprintf(stderr, "Failed to enable video input. Maybe another application is using the card.\n");
  return;

} 

//Disable the audio
result = g_deckLinkInput->DisableAudioInput();

//Start the stream
result = g_deckLinkInput->StartStreams();
if (result != S_OK){
  fprintf(stdout,"Error while starting the streaming : aborted\n");
}

while(this->running){
}

}

...

HRESULT VideoInputFromBlackMagic::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioFrame){


if (!videoFrame){

  fprintf(stdout,"Update: No video frame\n");
  return S_FALSE;

} 

void* data;
void* dataRight;
IDeckLinkVideoFrame3DExtensions* threeDExtensions = NULL;
IDeckLinkVideoFrame* rightEyeFrame = NULL;

if (FAILED(videoFrame->GetBytes(&data))){
  fprintf(stdout,"Fail obtaining the data from videoFrame\n");
  return S_FALSE;
}

if( this->isStereo ){
  if ((videoFrame->QueryInterface(IID_IDeckLinkVideoFrame3DExtensions, (void **) &threeDExtensions) != S_OK) || (threeDExtensions->GetFrameForRightEye(&rightEyeFrame) != S_OK)){
     fprintf(stdout,"Fail obtaining right eye frame\n");
     return S_FALSE;
  }

  if (FAILED(rightEyeFrame->GetBytes(&dataRight))){
     fprintf(stdout,"Fail obtaining the data from videoFrame\n");
     return S_FALSE;
  }

}

cv::Mat loadedImage;
cv::Mat mat = cv::Mat(videoFrame->GetHeight(), videoFrame->GetWidth(), CV_8UC2, data, videoFrame->GetRowBytes());
cv::cvtColor(mat, loadedImage, CV_YUV2BGR_UYVY);

//Right eye
cv::Mat loadedImageRight;
cv::Mat matRight;
if(this->isStereo){
  matRight = cv::Mat(rightEyeFrame->GetHeight(), rightEyeFrame->GetWidth(), CV_8UC2, dataRight, rightEyeFrame->GetRowBytes());
  if (rightEyeFrame){
     rightEyeFrame->Release();
  }
  cv::cvtColor(matRight, loadedImageRight, CV_YUV2BGR_UYVY);
}

if (!loadedImage.data){
  fprintf(stdout,"No frame loaded from the video : mainImage will not be updated\n");
} else {
  this->currentImage = loadedImage;
  //this->currentImage = loadedImageRight;
  if(this->isStereo){
     //this->currentImageRight = loadedImageRight;
     this->currentImageRight = loadedImage;
  }
  this->initialized = true;
  if(this->debugMode){
     if(this->isStereo){
        cv::imshow("DEBUG : right eye", this->currentImageRight);
        cv::imshow("DEBUG : left eye", this->currentImage);
     } else {
        cv::imshow("DEBUG", this->currentImage);
     }
  }  

  if(this->debugMode){
     int kp = cv::waitKey(1);
     if(kp == 1048603){
        //Remove debugMode and remove the window
        this->setDebugMode(false);
     }
  }

}

return S_OK;

}

...

有什么想法吗?

0 个答案:

没有答案