从Socket到浏览器的C ++ / OpenCV流式摄像机 - 视频/图像(MJPEG)(Windows 8.1)

时间:2014-09-15 09:50:33

标签: c++ sockets opencv streaming mjpeg

对openCV / C ++来说还是一个新手,所以请耐心等待:)

我目前正试图找到一种好的(可能很简单的)从我的OpenCV应用程序实时(或几乎实时)流式传输相机帧的方法,以便我可以打开浏览器,键入IP并查看图像。

到目前为止,我使用winsock2完成了服务器(如果有人有一个很好的跨平台替代方案,并且可以告诉我什么不同,我会很高兴)并且可以通过输入连接到它我的浏览器中的IP。

插座/服务器的代码:

//socket
long rc;
SOCKET acceptSocket;
SOCKADDR_IN addr;
WSADATA wsa;
// initialize winsock
rc=WSAStartup(MAKEWORD(2,0),&wsa);

if(rc!=0)
{
    printf("Error: startWinsock, Errorcode: %d\n",rc);
    return 1;
}
else
{
    printf("Winsock initialized!\n");
}

// create Socket
acceptSocket=socket(AF_INET,SOCK_STREAM,0);

if(acceptSocket==INVALID_SOCKET)
{
    printf("Error: Socket-Creation failed, Errorcode: %d\n",WSAGetLastError());
    return 1;
}
else
{
    printf("Socket succesfully created!\n");
}

memset(&addr,0,sizeof(SOCKADDR_IN));
addr.sin_family=AF_INET;
addr.sin_port=htons(8080);
addr.sin_addr.s_addr=ADDR_ANY;
rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));

if(rc==SOCKET_ERROR)
{
    printf("Error: bind, Errorcode: %d\n",WSAGetLastError());
    return 1;
}
else
{
    printf("Socket bound to port 8080\n");
}
rc=listen(acceptSocket,10);

if(rc==SOCKET_ERROR)
{
    printf("Error: listen, Errorcode: %d\n",WSAGetLastError());
    return 1;
}
else
{
    printf("acceptSocket is now in listen mode...\n");
}

SOCKET connectedSocket=accept(acceptSocket,NULL,NULL);

if(connectedSocket==INVALID_SOCKET)
{
    printf("Error, Errorcode: %d\n",WSAGetLastError());
    return 1;
}
else
{
    printf("New connection accepted!\n");
}

至于发送部分,我尝试直接使用相机框架并保存为jpg +重新加载到目前为止的jpg:

        char filename[128];
        frame_count++;
        if (frame_count%50 == 0)
        {
        sprintf(filename, "frame_%06d.jpg", index);
        imwrite(filename, camera1_undist);
        Mat image = imread(filename, CV_LOAD_IMAGE_COLOR);
        send(connectedSocket, (const char *) image.data, image.total()*image.elemSize(), 0);
        frame_count = 0;
        index++;
        }

问题:

1)图像不显示为图像,但显示为数字/符号(HEX / ASCII?主要是黑色问号和内容)。 如何转换/更改发送的内容以实际显示图像?

2)我读到了MJPEG并找到了一种保存输出的方法,但我不知道如何进一步使用该输出文件。如何在没有MJPEG-Streamer的情况下使用它(因为它只是Linux)

由于

1 个答案:

答案 0 :(得分:7)

我现在自己完成了,在这里和那里犯了一些错误。

让图像显示最重要的部分是

a)获取在发送实际图片之前发送的html标题,以便我的浏览器知道将要发送的内容

b)使用imencode将图像保存在缓冲区中并发送缓冲区而不是图像本身

我也不会将画面保存在任何地方,只需从相机输入中取出即可,这样就可以缩短它。

为了完成mjpegs,我只需要添加另一个标头,告诉“客户端”将发送多个图像,由某个边界分隔:

sprintf(head, "HTTP/1.1 200 OK\r\nContent-Type: multipart/x-mixed-replace;boundary=informs\r\n\r\n");
send(socket,head,strlen(head), 0);

这有点帮助,尤其是标题部分:http://nakkaya.com/2011/03/23/streaming-opencv-video-over-the-network-using-mjpeg/ (虽然它起初让我很恼火,因为我之前从未使用过或看过clojure。

这也非常有用:http://answers.opencv.org/question/6976/display-iplimage-in-webbrowsers/