OpenCV VideoCapture无法解析MJPG流
OpenCV VideoCapture unable to parse MJPG stream
我正试图在OpenCV 3.1版Windows x64中使用OpenCV VideoCapture类打开视频流。在我的树莓派上,我运行了mjpg_streamer,我可以通过http://192.168.1.245:8080/?action=stream,但是当我尝试在OpenCV中打开视频流时,它无法打开流。
这是我用来调试的代码,显然对其他有连接问题的人也有效。
#include <opencv2core.hpp>
#include <opencv2videoio.hpp>
#include <string>
#include <iostream>
using namespace std;
int main()
{
cv::VideoCapture vcap;
cv::Mat raw_image;
const string videoStreamAddress = "http://192.168.1.245:8080/?action=stream";
if (!vcap.open(videoStreamAddress))
{
cout << "Error opening video stream" << endl;
system("pause");
return -1;
}
cout << "Stream opened" << endl;
system("pause");
return 0;
}
在网上,人们说OpenCV必须在链接中有视频扩展。我试着使用其他人正在使用的扩展技巧,比如http://192.168.1.245:8080/?action=stream?dummy=param.mjpg,http://192.168.1.245:8080/?action=stream&type=.mjpg,&channel=0&。jpg和&type=.mjpeg,但这不起作用。此外,我已经在cmake中启用了ffmpeg并使用它进行了构建。在这一点上,它似乎对其他人有效,而且似乎没有其他关于这个主题的内容。解决这个问题的办法是什么?
多亏了@api55的建议,我能够获取流,然后将原始jpg数据传递给opencv,然后做我想做的事情。
以下是提供的链接@api55中的解决方案的c++代码(到python解决方案的链接)。
try
{
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query("192.168.1.245", "8080");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);
std::string jpgimg = "";
std::stringstream request_;
request_ << "GET /?action=stream HTTP/1.1rn";
request_ << "Host: 192.168.1.245rn";
request_ << "Accept-Encoding: *rn";
request_ << "rn";
boost::system::error_code ignored_error;
boost::asio::write(socket, boost::asio::buffer(request_.str()), ignored_error);
for (;;)
{
char buf[1025];
buf[1024] = ' ';
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buf,1024), error);
if (error == boost::asio::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw boost::system::system_error(error); // Some other error.
jpgimg.append(buf,buf+len);
int a = jpgimg.find("xffxd8");
int b = jpgimg.find("xffxd9");
if (a != -1 && b != -1)
{
Mat rawData(1, b-a+2, CV_8UC1, (void*)(&jpgimg[a]));
Mat i = cv::imdecode(rawData, CV_LOAD_IMAGE_COLOR);
cv::imshow("i", i);
if (cv::waitKey(1) == 27)
break;
jpgimg = jpgimg.substr(b+2);
}
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
它绝不是经过优化的,纯粹是其他地方实现的基础。它与Boost ASIO 1.65.1一起工作,方法是在我的树莓pi(端口8080)上打开一个流到mjpg_streamer,向它发送一个HTTP GET请求,请求/?action=流式传输原始链接的一部分,查找jpg数据的开始和结束标志("\xff\xd8"answers"\xff#xd9"),然后通过imdecode将这些数据发送到OpenCV。
资源:
Boost ASIO客户端代码:http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/tutorial/tutdaytime1.html
关于jpg如何工作的信息:如何在C++中解析MJPEG HTTP流?
使用OpenCV中的原始jpg数据:opencv从缓冲区读取jpeg图像
希望OpenCV将来能有更好的.jpg支持。
- 将帧从python VideoCapture()传递给c ++
- 如何在 opencv 中使用 cv::VideoCapture::waitAny()
- 对'cv::VideoCapture::VideoCapture(int)的未定义引用
- OpenCV VideoCapture Partial Frame Corruption
- OpenCV VideoCapture 无法打开文件,我做错了什么?
- OPENCV VIDEOCAPTURE说视频有0帧(C 和Python)
- OpenCV VideoCapture无法解析MJPG流
- OpenCV 中 VideoCapture 对象的状态
- CvCapture 结构和 VideoCapture 结构有什么区别
- 无法使用OpenCV从辅助网络摄像头读取VideoCapture中的帧
- Qt 5.2/OpenCV 2.4.8-无法通过VideoCapture打开视频文件
- OpenCV videoCapture 为 iOS 应用程序文档目录中的文件提供了错误的属性
- C++突然阻止使用VideoCapture从IP摄像机读取帧
- 在OpenCV方法VideoCapture.open()中使用设备名称而不是ID
- OpenCV VideoCapture::set()返回false,但成功
- C++/OpenCV-从迭代器接收的字符串的VideoCapture失败
- 使用 OpenCV C++ 界面是否需要释放使用 VideoCapture 创建的相机捕获(int 设备?
- 是否可以使用 cv::VideoCapture 加载 32 位帧
- VideoCapture select timeout with OpenCV 3.0.0-rc1
- cv::VideoCapture from string 在 Mac 上的 Qt5 中给出链接器错误