我想处理和显示从树莓派相机创建的网络rtsp流。我有以下代码:
#include <iostream>
#include <functional>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
int main(int argc, char** argv) {
cv::VideoCapture * stream = new cv::VideoCapture("rtsp://192.168.55.151:8554/");
if (!stream->isOpened()) return -1;
cv::namedWindow("rtsp_stream", CV_WINDOW_AUTOSIZE);
cv::Mat frame;
while (true) {
if (!stream->read(frame)) return -1;
cv::imshow("rtsp_stream", frame);
cv::waitKey(15);
}
return 1;
}
Run Code Online (Sandbox Code Playgroud)
当流不存在时,执行此操作将导致:
[tcp @ 0xa12480] Connection to tcp://192.168.55.151:8554?timeout=0 failed: Connection refused
Run Code Online (Sandbox Code Playgroud)
这意味着流尝试与tcp连接。流直播时,执行结果为:
[rtsp @ 0xb07960] method SETUP failed: 461 Client error
Run Code Online (Sandbox Code Playgroud)
从互联网研究中,我发现问题可能在于流使用udp。如果我将URL更改为:
"udp://192.168.55.151:8554/"
Run Code Online (Sandbox Code Playgroud)
然后执行冻结 cv::VideoCapture("udp://192.168.55.151:8554/");
VLC能够打开rtsp流。据我所知,ffmpeg用于通过opencv解码流。当我跑步时:
ffmpeg -rtsp_transport udp -i rtsp://192.168.55.151:8554/ -t 5 test.mp4
Run Code Online (Sandbox Code Playgroud)
流解码和保存成功。那么我如何在opencv代码中指定要作为udp的较低级别协议呢?还有另一种方法可以用opencv吗?
编辑:如果我更改ffmpeg命令以使用tcp,即:
ffmpeg -rtsp_transport …Run Code Online (Sandbox Code Playgroud) 我想在执行之前将某些线程映射到某些处理器,就像我们通过传递pthread_attr_t对象pthread_create一样std::thread。我已经尝试过以下方法:
std::vector<std::thread> threads;
for (int i = 0; i<num_threads; i++) {
threads.push_back(std::thread(&some_struct::run, some_structs_vector.at(i)));
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(i, &cpuset);
int rc = pthread_setaffinity_np(threads.at(i).native_handle(), sizeof(cpu_set_t), &cpuset);
assert(rc == 0);
}
Run Code Online (Sandbox Code Playgroud)
尽管此代码完成了这项工作,但它在线程执行的未指定时刻设置了关联性,导致处理器可能必须在执行期间将线程移动到另一个处理器。
如果我将亲和力设置为线程代码中的第一件事,通过传递零
int rc = pthread_setaffinity_np(0, sizeof(cpu_set_t), &cpuset);
Run Code Online (Sandbox Code Playgroud)
我遇到分段错误。如果我通过pthread_self()而不是零,我会得到 EINVAL 作为返回。
int rc = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
Run Code Online (Sandbox Code Playgroud)
但是,在执行开始后更改线程的关联性也可能导致线程被移动。
那么,在执行开始之前,如何使用现代 std::thread 对象设置线程关联性?
编辑:我不关心优先级,只关心映射到某些核心。
这是带有opencv的测试程序。它不应该做任何事情。
#include <opencv2/opencv.hpp>
int main (){
cv::Mat src;
Mat dst; // <---- compile error (Mat not declared, suggested alternatives cv::)
cvNamedWindow("A", CV_WINDOW_AUTOSIZE);
cv::namedWindow("B", CV_WINDOW_AUTOSIZE);
medianBlur(src,dst,3);
imshow("A",src);
cv::imshow("B", src);
}
Run Code Online (Sandbox Code Playgroud)
我用cmake编译并制作
cmake_minimum_required(VERSION 2.8)
project( opencvtest )
find_package( OpenCV REQUIRED )
add_executable( opencvtest main.cpp )
target_link_libraries( opencvtest ${OpenCV_LIBS} )
Run Code Online (Sandbox Code Playgroud)
Cmake可以正确运行。从代码中可以看到,该程序无需Mat dst声明即可正常运行。现在,它cvNamedWindow是一个C函数,因此不需要名称空间。imshow另一方面是C ++函数,因此它确实需要名称空间声明。http://docs.opencv.org/2.4/modules/highgui/doc/user_interface.html#imshow
那么为什么imshow没有命名空间声明会通过编译。同样的原因medianBlur甚至没有交流等效功能
http://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=medianblur#medianblur
我在3.1.0 opencv版本和ubuntu 16.04上运行