2016-08-22 108 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