C ++ / OpenCV потоковая камера-видео / изображения (MJPEG) из гнезда в браузер (Windows 8.1)

Все еще довольно плохо знаком с openCV / C ++, поэтому, пожалуйста, потерпите меня 🙂

В настоящее время я пытаюсь найти хороший (и, возможно, простой) способ для потоковой передачи кадров моей камеры в реальном времени (или почти в реальном времени) из моего приложения OpenCV, чтобы я мог открыть свой браузер, ввести IP-адрес и увидеть изображение.

До сих пор я закончил работу над сервером с использованием winsock2 (если у кого-то есть хорошая кроссплатформенная альтернатива и он может сказать мне, в чем дело, я был бы очень рад) и могу подключиться к нему, введя IP-адрес в моем браузере.

Socket- / Server-код:

//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)

Спасибо

5

Решение

Я сделал это сам сейчас, делал несколько ошибок здесь и там.

Самая важная часть, чтобы получить изображение, чтобы показать было

а) получить HTML-заголовок, который отправляется перед отправкой фактического изображения, чтобы мой браузер знал, что будет отправлено

б) использовать 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/

7

Другие решения


По вопросам рекламы [email protected]