c ++ opencv网络摄像头流到html

Sku*_*lly 2 c++ streaming webcam opencv visual-c++

我目前正在为我的学习开发一个项目,我必须获取网络摄像头流,检测一些对象并在此流上添加一些其他信息.这一切都在服务器端完成.

现在我还必须向客户端提供流的修改图像.客户端只需打开包含以下内容的HTML文件:

<html>
    <head>
        <title></title>
    </head>
    <body>
        <h1>It works!</h1>
        <video width="320" height="240" src="http://127.0.0.1:4711/videostream" type="video/quicktime" autoplay controls>
            Your browser does not support the video tag.
        </video>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

这将导致服务器上的/ videostream发出HTTP请求.要在服务器端处理此请求,我将使用Boost 1.56.

目前,我的网络摄像头流的每个帧都是IplImage类型.我是否必须将IplImage转换为视频MIME类型特定格式?

我试图弄清楚自己,整个事情是如何运作的,但我无法理解.我使用Wireshark来分析通信,但它没有意义.出于测试目的,我已将视频上传到我的网站空间并在本地打开上述文件.视频的src是我的网络服务器的地址.首先是TCP握手的东西,然后是这条消息:

HTTP    765 GET /MOV_4198.MOV HTTP/1.1 
Run Code Online (Sandbox Code Playgroud)

遵循以下消息(它包含连接:HTTP部分中的Keep-Alive):

HTTP    279 HTTP/1.1 304 Not Modified 
Run Code Online (Sandbox Code Playgroud)

之后只有TCP ACK和SYN,但没有数据.见下图: 见图

视频的实际数据在何处以及如何发送?我错过了什么?

如果你能提供一些有关浏览器(视频标签)和C++套接字连接之间连接的信息,那将会很棒.

谢谢Stefan

Sku*_*lly 5

我想分享我的经验 - 也许它也会帮助别人.为了从网络摄像头获取我的流,我使用了OpenCV 2.4.9,作为协议,我使用了mjpeg流协议(另请参阅HTTP上的MJPEG) - 感谢@berak - 他在我的问题帖子中提到了MJPEG.

以下代码只是给出了一个概述 - 我没有进入线程细节.由于这是一个学生项目,我们正在使用GitHub,你可以在GitHub上找到完整的源代码- 我想在这里提到的项目Swank Rats,我不是C++,OpenCV或Boost大师.这个项目是我第一次使用这三个项目.

让您从网络摄像头流式传输

做这样的事情(带有线程的完整代码,因此在repo中搜索WebcamService)

cv::VideoCapture capture();
cv::Mat frame;
while (1) {
    if (!capture.isOpened()) {
        break; //do some logging here or something else - webcam not available
    }

    //Create image frames from capture
    capture >> frame;

    if (!frame.empty()) {
        //do something with your image (e.g. provide it)
        lastImage = frame.clone();
    }
}
Run Code Online (Sandbox Code Playgroud)

通过HTTP提供您的图像

那么我不详细介绍如何使用C++创建HTTP服务器.Boost for C++ 11提供了一个很好的例子.我复制了这段代码并根据我的需要进行了调整.您可以在上面提到的repo中找到我的实现的源代码.该代码目前位于基础设施/网络/视频流.

没有必要使用FFMPEG,GStreamer或类似的东西.您可以像这样使用OpenCV创建内存中的JPEG(请参阅StreamResponseHandler的代码):

cv::Mat image = webcamService->GetLastImage();
// encode mat to jpg and copy it to content
std::vector<uchar> buf;
cv::imencode(".jpg", image, buf, std::vector<int>());

std::string content(buf.begin(), buf.end()); //this must be sent to the client
Run Code Online (Sandbox Code Playgroud)

感谢@codeDr在这里帖子.

content变量表示以字节为单位的图像,它将被发送到客户端.你必须遵循MJPEG协议.

使用HTML连接到服务器

这样的东西就足够了(如这里提到的)

<html>  
    <body>  
        <h1> Test for simple Webcam Live streaming </h1>  
        <img src="http://127.0.0.1:4711/videostream">
    </body>  
</html> 
Run Code Online (Sandbox Code Playgroud)

您必须将IP,端口等更改为您的服务器连接.

我希望这有帮助.