5

我正在尝试使用 openCv 框架进行 ios 视频处理的教程。

我已经成功地将 ios openCv 框架加载到我的项目中 -我的框架与教程中介绍的框架之间似乎不匹配,我希望有人能帮助我。

OpenCv 使用cv::Mat类型来表示图像。当使用 AVfoundation 委托处理来自相机的图像时 - 我需要将所有的转换CMSampleBufferRef为该类型。

似乎教程中介绍的 openCV 框架提供了一个名为 using 的库

#import <opencv2/highgui/cap_ios.h>

使用新的委托命令:

谁能指出我在哪里可以找到这个框架或可能在CMSampleBufferRef和之间快速转换cv::Mat

编辑

opencv框架中有很多分割(至少对于ios来说)。我已经通过各种“官方”网站下载了它,并且还使用他们的说明使用了 fink 和 brew 等工具。我什至比较了安装到 /usr/local/include/opencv/ 的头文件。他们每次都不一样。下载 openCV 项目时 - 同一个项目中有各种 cmake 文件和相互冲突的自述文件。<opencv2/highgui/cap_ios.h>我认为我成功地通过此链接为 IOS 构建了一个良好的版本,其中 avcapture 功能内置于框架中(带有此标头) ,然后使用 ios 目录中的 python 脚本构建库 - 使用命令python opencv/ios/build_framework.py ios。我会尝试更新

4

2 回答 2

13

这是我使用的转换。您锁定像素缓冲区,创建 cv::Mat,使用 cv::Mat 进行处理,然后解锁像素缓冲区。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

CVPixelBufferLockBaseAddress( pixelBuffer, 0 );

int bufferWidth = CVPixelBufferGetWidth(pixelBuffer);
int bufferHeight = CVPixelBufferGetHeight(pixelBuffer);
int bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer);
unsigned char *pixel = (unsigned char *)CVPixelBufferGetBaseAddress(pixelBuffer);
cv::Mat image = cv::Mat(bufferHeight,bufferWidth,CV_8UC4,pixel, bytesPerRow); //put buffer in open cv, no memory copied
//Processing here

//End processing
CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );
}

上述方法不会复制任何内存,因此您不拥有内存,pixelBuffer 将为您释放它。如果您想要自己的缓冲区副本,只需执行

cv::Mat copied_image = image.clone();
于 2012-09-10T16:21:23.567 回答
7

这是之前接受的答案中代码的更新版本,应该适用于任何 iOS 设备。

由于至少在 iPhone 6 和 iPhone 6+ 上bufferWidth不等于,我们需要指定每行中的字节数作为 cv::Mat 构造函数的最后一个参数。bytePerRow

CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

CVPixelBufferLockBaseAddress(pixelBuffer, 0);

int bufferWidth = CVPixelBufferGetWidth(pixelBuffer);
int bufferHeight = CVPixelBufferGetHeight(pixelBuffer);
int bytePerRow = CVPixelBufferGetBytesPerRow(pixelBuffer);
unsigned char *pixel = (unsigned char *) CVPixelBufferGetBaseAddress(pixelBuffer);
cv::Mat image = cv::Mat(bufferHeight, bufferWidth, CV_8UC4, pixel, bytePerRow); 

// Process you cv::Mat here

CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);

该代码已在我运行 iOS 10 的 iPhone5、iPhone6 和 iPhone6+ 上进行了测试。

于 2017-04-20T15:11:42.567 回答