2016-08-22 77 views
0

如何将cv :: Mat数据复制回sampleBuffer?将cv :: Mat复制到CMSampleBufferRef

我的场景如下: 我从pixelBuffer创建cv :: Mat进行地标检测,并将地标添加到cv :: Mat图像数据。我想将这个cv :: Mat复制到示例缓冲区中,并与地标一起显示。

这可能吗?

我DLIB实现这一点,但需要知道如何与CV ::垫做到这一点:

char *baseBuffer = (char *)CVPixelBufferGetBaseAddress(imageBuffer); 
img.reset(); 
long position = 0; 
while (img.move_next()) { 
     dlib::bgr_pixel& pixel = img.element(); 
     long bufferLocation = position * 4; //(row * width + column) * 4; 
     char b = baseBuffer[bufferLocation]; 
     char g = baseBuffer[bufferLocation + 1]; 
     char r = baseBuffer[bufferLocation + 2]; 
     dlib::bgr_pixel newpixel(b, g, r); 
     pixel = newpixel; 

     position++; 
    } 
+0

可能是的。还有几个细节?一些代码? – Miki

+0

我按照这个[答](http://stackoverflow.com/a/12355675/3649485)将'CVImageBufferRef'转换为cv :: mat。 现在我想把这个cv :: mat放回样本缓冲区。我知道如何使用dlib将像素复制回sampleBuffer,但不知道如何使用openCV执行此操作 dlib在下一个注释中的示例代码 – mosn

+0

请将适当格式的代码发布到问题中。它在评论中不可读 – Miki

回答

3

我回答我的问题。

第一件事情,你需要访问CV ::垫图像的像素数据,我跟着这个伟大的solution

然后,你需要像素复制到从basebuffer开始缓冲。下面的代码应该可以帮助您实现这一目标:

CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
char *baseBuffer = (char *)CVPixelBufferGetBaseAddress(imageBuffer); 
long position = 0; 
uint8_t* pixelPtr = (uint8_t*)targetImage.data; 
int cn = targetImage.channels(); 
cv::Scalar_<uint8_t> rgbPixel; 
for(int i = 0; i < targetImage.rows; i++) 
{ 
    for(int j = 0; j < targetImage.cols; j++) 
    { 
     long bufferLocation = position * 4; 

     rgbPixel.val[0] = pixelPtr[i*targetImage.cols*cn + j*cn + 0]; // B 
     rgbPixel.val[1] = pixelPtr[i*targetImage.cols*cn + j*cn + 1]; // G 
     rgbPixel.val[2] = pixelPtr[i*targetImage.cols*cn + j*cn + 2]; // R 
     baseBuffer[bufferLocation] = rgbPixel.val[2]; 
     baseBuffer[bufferLocation + 1] = rgbPixel.val[1]; 
     baseBuffer[bufferLocation + 2] = rgbPixel.val[0]; 
     position++; 
    } 
} 

有些事情要采取的

  • 注意确保CVPixelBufferLockBaseAddressCVPixelBufferUnlockBaseAddress前和手术后。我
  • 正在做这个CV_8UC3,你可能想检查你的cv :: mat
    类型。
  • 我还没有做过性能分析,但我得到了平稳的输出。
+0

为什么'CV_8UC3'? 'CMSampleBuffer'本身有4个通道 – user924

+0

是的,这个方法完全吃cpu,如果在你的应用中没有很多功能,那么它会很流畅,但是如果你有很多功能你对我的CPU使用感兴趣 – user924

+0

''working 'next solution'baseBuffer [bufferLocation] = pixelPtr [i * targetImage.cols * cn + j * cn + 0]; baseBuffer [bufferLocation + 1] = pixelPtr [i * targetImage.cols * cn + j * cn + 1];我猜这是因为我使用'videoOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey作为字符串):NSNumber(value:kCVPixelFormatType_32BGRA as UInt32的)]' – user924