i want to do image processing on a GoPro Hero4 Black livestream using OpenCV in C++. The firmware version is 5.0.
With python it successfully works. When i implement it the same (!) way in C++ status 31 and 32 switch to 1 when opening the VideoCapture, so the livestream is started and the client is connected. However, a following cap.isOpen() returns false. I need to add that the cap.open(...) command lets the program stop for some seconds which is unplausible.
The code in python
import cv2
import numpy as np
from time import time
import socket
from goprocam import GoProCamera
from goprocam import constants
import requests
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
t=time()
url = "http://10.5.5.9/gp/gpControl/execute?p1=gpStream&a1=proto_v2&c1=restart"
payload = { }
headers = {}
res = requests.post(url, data=payload, headers=headers)
cap = cv2.VideoCapture("udp://10.5.5.9:8554")
while (cap.isOpened()):
nmat, frame = cap.read()
if nmat == True:
cv2.imshow("GoPro OpenCV", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if time() - t >= 2.5:
sock.sendto("_GPHD_:0:0:2:0.000000\n".encode(), ("10.5.5.9", 8554))
t=time()
# When everything is done, release the capture
cap.release()
cv2.destroyAllWindows()
The code in C++
#define CURL_STATICLIB
#include <curl\curl.h>
#include <boost/exception/exception.hpp>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
int main()
{
CURL* curl;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://10.5.5.9/gp/gpControl/execute?p1=gpStream&c1=start");
curl_easy_perform(curl);
curl_easy_setopt(curl, CURLOPT_URL, "http://10.5.5.9/gp/gpControl/execute?p1=gpStream&c1=restart");
curl_easy_perform(curl);
}
boost::asio::io_service ioService;
boost::asio::ip::udp::resolver resolver(ioService);
boost::asio::ip::udp::endpoint dest(boost::asio::ip::address::from_string("10.5.5.9"), 8554);
boost::asio::ip::udp::socket sock(ioService, boost::asio::ip::udp::v4());
boost::this_thread::sleep_for(boost::chrono::milliseconds(2000));
sock.send_to(boost::asio::buffer("_GPHD_:0:0:2:0.000000\n", 22), dest);
VideoCapture cap;
cap.open("udp://10.5.5.9:8554");
while (cap.isOpened() )
{
std::cout << "is open" << std::endl;
}
return 0;
}
Does anyone have an idea how to solve the issue?
I also tried different API references for VideoCapture
cap.open("udp://10.5.5.9:8554", CAP_ANY);
cap.open("udp://10.5.5.9:8554", CAP_FFMPEG);
I also tried using the @ prefix
cap.open("udp://@10.5.5.9:8554", CAP_ANY);
UPDATE: I can't test the correct execution of the VideoCapture backend since it seems like the laptop webcam cant be opened with CAP_FFMPEG in python. However, when i let the laptop webcam run by declaring index 0 and using the CAP_FFMPEG backend i get the same behaviour as when i declare the gopro udp livestream.
cap.open(0, CAP_FFMPEG);
The solution was to deactivate the windows firewall for private networks. Cant be more trivial but in case someone struggles at that point...here is the hint :)