简体   繁体   English

如何在iOS上分析视频流?

[英]How do I analyze video stream on iOS?

For example, there are QR scanners which scan video stream in real time and get QR codes info. 例如,有QR扫描仪实时扫描视频流并获得QR码信息。 I would like to check the light source from the video, if it is on or off, it is quite powerful so it is no problem. 我想检查视频中的光源,如果它打开或关闭,它是非常强大的,所以它没有问题。

I will probably take a video stream as input, maybe make images of it and analyze images or stream in real time for presence of light source (maybe number of pixels of certain color on the image?) 我可能会将视频流作为输入,可能会制作图像并分析图像或实时流式传输光源(可能是图像上某些颜色的像素数?)

How do I approach this problem? 我该如何处理这个问题? Maybe there is some source of library? 也许有一些图书馆的来源?

It sounds like you are asking for information about several discreet steps. 这听起来像是在询问有关几个谨慎步骤的信息。 There are a multitude of ways to do each of them and if you get stuck on any individual step it would be a good idea to post a question about it individually. 有很多种方法可以做到每一种方法,如果你遇到任何一个步骤,最好单独发布一个关于它的问题。

1: Get video Frame 1:获取视频帧

Like chaitanya.varanasi said, AVFoundation Framework is the best way of getting access to an video frame on IOS. 就像chaitanya.varanasi所说,AVFoundation Framework是在IOS上访问视频帧的最佳方式。 If you want something less flexible and quicker try looking at open CV's video capture . 如果你想要一些不那么灵活和快速的东西,试着看看开放式CV的视频捕捉 The goal of this step is to get access to a pixel buffer from the camera. 此步骤的目标是从相机访问像素缓冲区。 If you have trouble with this, ask about it specifically. 如果您遇到此问题,请特别询问。

2: Put pixel buffer into OpenCV 2:将像素缓冲区放入OpenCV

This part is really easy. 这部分非常简单。 If you get it from openCV's video capture you are already done. 如果你从openCV的视频捕获中获得它,你已经完成了。 If you get it from an AVFoundation you will need to put it into openCV like this 如果从AVFoundation获得它,你需要将它放入openCV中

//Buffer is of type CVImageBufferRef, which is what AVFoundation should be giving you
//I assume it is BGRA or RGBA formatted, if it isn't, change CV_8UC4 to the appropriate format

CVPixelBufferLockBaseAddress( Buffer, 0 );

int bufferWidth = CVPixelBufferGetWidth(Buffer);
int bufferHeight = CVPixelBufferGetHeight(Buffer);

unsigned char *pixel = (unsigned char *)CVPixelBufferGetBaseAddress(Buffer);
cv::Mat image = cv::Mat(bufferHeight,bufferWidth,CV_8UC4,pixel); //put buffer in open cv, no memory copied

//Process image Here

//End processing
CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );

note I am assuming you plan to do this in OpenCV since you used its tag. 注意我假设您计划在OpenCV中执行此操作,因为您使用了它的标记。 Also I assume you can get the OpenCV framework to link to your project. 另外我假设您可以将OpenCV框架链接到您的项目。 If that is an issue, ask a specific question about it. 如果这是一个问题,请询问有关它的具体问题。

3: Process Image 3:过程图像

This part is by far the most open ended. 这部分是迄今为止最开放的部分。 All you have said about your problem is that you are trying to detect a strong light source. 你所说的关于你的问题的一切都是你试图检测一个强大的光源。 One very quick and easy way of doing that would be to detect the mean pixel value in a greyscale image. 一种非常快速简便的方法是检测灰度图像中的平均像素值。 If you get the image in colour you can convert with cvtColor . 如果您获得彩色图像,可以使用cvtColor进行转换。 Then just call Avg on it to get the mean value. 然后只需在其上调用Avg即可获得平均值。 Hopefully you can tell if the light is on by how that value fluctuates. 希望你可以通过该值如何波动来判断灯是否亮起。

chaitanya.varanasi suggested another option, you should check it out too. chaitanya.varanasi提出了另一种选择,你也应该检查一下。

openCV is a very large library that can do a wide wide variety of things. openCV是一个非常大的库,可以做各种各样的事情。 Without knowing more about your problem I don't know what else to tell you. 在不了解您的问题的情况下,我不知道还能告诉您什么。

Look at the AVFoundation Framework from Apple. 看看Apple的AVFoundation Framework

Hope it helps! 希望能帮助到你!

You can try this method: start by getting all images to an AVCaptureVideoDataOutput . 您可以尝试此方法:首先将所有图像都添加到AVCaptureVideoDataOutput From the method: captureOutput:didOutputSampleBuffer:fromConnection ,you can sample/calculate every pixel. 从方法: captureOutput:didOutputSampleBuffer:fromConnection ,您可以采样/计算每个像素。 Source: answer 来源: 回答

Also, you can take a look at this SO question where they check if a pixel is black. 此外,你可以看看这个问题 ,他们检查像素是否是黑色。 If its such a powerful light source, you can take the inverse of the pixel and then determine using a set threshold for black. 如果它是如此强大的光源,您可以取像素的倒数,然后使用设定的黑色阈值来确定。

The above sample code only provides access to the pixel values stored in the buffer; 上面的示例代码仅提供对存储在缓冲区中的像素值的访问; you cannot run any other commands but those that change those values on a pixel-by-pixel basis: 您不能运行任何其他命令,而是那些在逐个像素的基础上更改这些值的命令:

for ( uint32_t y = 0; y < height; y++ )
{
    for ( uint32_t x = 0; x < width; x++ )
    {
        bgraImage.at<cv::Vec<uint8_t,4> >(y,x)[1] = 0;
    }
}

This—to use your example—will not work with the code you provided: 这 - 使用您的示例 - 将无法使用您提供的代码:

    cv::Mat bgraImage = cv::Mat( (int)height, (int)extendedWidth, CV_8UC4, base );
cv::Mat grey = bgraImage.clone();
cv::cvtColor(grey, grey, 44);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM