[英]Convert CMSampleBufferRef to cv::Mat
我正在嘗試將 CMSampleBufferRef(作為 iOS 中 AVCaptureVideoDataOutputSampleBufferDelegate 的一部分)轉換為 OpenCV Mat,以嘗試半實時穩定輸出。
我跑在下面的那一刻測試應用這個,但一直收到當我創建和使用墊的問題。
迅捷控制器
let wrapper : OpenCVWrapper = OpenCVWrapper()
...
func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {
self.wrapper.processBuffer(sampleBuffer, self.previewMat)
}
OpenCVWrapper
- (void)processBuffer:(CMSampleBufferRef)buffer :(UIImageView*)previewMat {
// Convert current buffer to Mat
CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(buffer);
CVPixelBufferLockBaseAddress( pixelBuffer, 0);
CGFloat bufferWidth = CVPixelBufferGetWidth(pixelBuffer);
CGFloat bufferHeight = CVPixelBufferGetHeight(pixelBuffer);
unsigned char *pixel = (unsigned char *)CVPixelBufferGetBaseAddress(pixelBuffer);
Mat tmp(bufferWidth, bufferHeight, CV_8UC4, pixel);
Mat cur = tmp.clone();
dispatch_async(dispatch_get_main_queue(), ^{
[previewMat setImage:[UIImage imageWithCVMat:cur]];
});
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
}
在Mat cur = tmp.clone()
我得到一個EXC_BAD_ACCESS
對我在這里做錯了什么有任何想法嗎?
我試過 bufferWidth 和 CGFloat 和 int,並在 Mat 的構造函數中切換它們,同樣的問題。
改進了解決“僅前 30%”問題的解決方案:
- (cv::Mat)matFromBuffer:(CMSampleBufferRef)buffer {
CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(buffer);
CVPixelBufferLockBaseAddress( pixelBuffer, 0 );
//Processing here
int bufferWidth = (int)CVPixelBufferGetWidth(pixelBuffer);
int bufferHeight = (int)CVPixelBufferGetHeight(pixelBuffer);
unsigned char *pixel = (unsigned char *)CVPixelBufferGetBaseAddress(pixelBuffer);
//put buffer in open cv, no memory copied
cv::Mat mat = cv::Mat(bufferHeight,bufferWidth,CV_8UC4,pixel,CVPixelBufferGetBytesPerRow(pixelBuffer));
//End processing
CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );
cv::Mat matGray;
cvtColor(mat, matGray, CV_BGR2GRAY);
return matGray;
}
也許這會奏效:
- (void)processBuffer:(CMSampleBufferRef)buffer :(UIImageView*)previewMat {
{
CVImageBufferRef imgBuf = CMSampleBufferGetImageBuffer(buffer);
// lock the buffer
CVPixelBufferLockBaseAddress(imgBuf, 0);
// get the address to the image data
void *imgBufAddr = CVPixelBufferGetBaseAddressOfPlane(imgBuf, 0);
// get image properties
int w = (int)CVPixelBufferGetWidth(imgBuf);
int h = (int)CVPixelBufferGetHeight(imgBuf);
// create the cv mat
cv::Mat image;
image.create(h, w, CV_8UC4);
// memcpy(image.data, imgBufAddr, w * h); copies only 25% of the image
memcpy(image.data, imgBufAddr, w * h* 4); // copies all pixels
// unlock again
CVPixelBufferUnlockBaseAddress(imgBuf, 0);
dispatch_async(dispatch_get_main_queue(), ^{
[previewMat setImage:[UIImage imageWithCVMat:image]];
});
}
圖像類型不相等,您需要嘗試執行某種操作
cvtColor(image, image_copy, CV_BGRA2BGR);
嘗試使用其他類型的 CV_BGRA2BGR
希望能幫助到你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.