ZeroMq传输视频的几种方案

前言

因为项目需要,现在需要使用ZeroMq去实现摄像头视频数据的传输,尝试了不少方法,以下是一些成功的汇总,定时更新:

参考文章:

ZeroMQ+OpenCV实现视频网络传输_zmq视频传输-CSDN博客

这个代码有点问题,需要微调,具体看我的代码方法一。

因为我的开发环境是QT,以下以ubuntu20.04,QT5.12为例:

方法一:使用opencv和zeromq

原理:

使用了opencv的接收摄像头数据,以及imencode和imdecode进行jpg的编解码。

发送端:

pro文件:

复制代码
增加内容:

LIBS += /usr/local/lib/libzmqpp-static.a -lzmq

#opencv:******************************************
CONFIG      += link_pkgconfig
PKGCONFIG   += opencv4
LIBS        += -L/usr/lib/x86_64-linux-gnu/ -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs -lopencv_videoio
INCLUDEPATH += /usr/include/opencv4/opencv2
#*************************************************

main.cpp

cpp 复制代码
#include <zmq.hpp>
#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>

int main()
{
    zmq::context_t context(1);
    zmq::socket_t socket(context, zmq::socket_type::pub);
    socket.bind("tcp://*:5555");

    cv::VideoCapture cap(0);
    if (cap.isOpened())
    {
        std::cout << "摄像头已打开" << std::endl;
        std::cout << "图像宽度" << cap.get(cv::CAP_PROP_FRAME_WIDTH) << std::endl;
        std::cout << "图像高度" << cap.get(cv::CAP_PROP_FRAME_HEIGHT) << std::endl;
    }
    else
        return -1;

    cv::Mat frame;

    while (cap.read(frame))
    {
        cv::Size dstSize = cv::Size(1280,960);
        cv::Mat dstFrame;
        cv::resize(frame, dstFrame, dstSize);

        std::vector<uint8_t> imageBuffer;
        std::vector<int> compress_params;
        compress_params.push_back(cv::IMWRITE_JPEG_QUALITY);
        compress_params.push_back(40);//压缩为原图像的x%,x in [0,100]
        cv::imencode(".jpg", dstFrame, imageBuffer, compress_params);

        //send img
        zmq::message_t msg(imageBuffer.size());
        memcpy(msg.data(), imageBuffer.data(), imageBuffer.size());
        socket.send(msg, zmq::send_flags::dontwait);

        std::cout<<"send image, len:"<<imageBuffer.size() << std::endl;
        //cv::imshow("pub", dstFrame);
        cv::waitKey(1000 / cap.get(cv::CAP_PROP_FPS));
    }
    return 0;
}

接收端:

pro文件:

同发送端相同。

main.cpp

cpp 复制代码
#include <iostream>
#include <string>
#include <zmq.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
int main (int argc, char *argv [])
{

    zmq::context_t context(1);
    zmq::socket_t socket(context, zmq::socket_type::sub);
    socket.connect("tcp://localhost:5555");  // 可以替换为其他地址
    socket.setsockopt(ZMQ_SUBSCRIBE, "", 0); // 设置订阅空字符串以接收所有消息

    cv::Mat frame;
    while (true) {
        zmq::message_t msg;
        auto ok = socket.recv(msg, zmq::recv_flags::dontwait);
        if (ok) {
            std::vector<uint8_t> buffer(static_cast<uint8_t*>(msg.data()), static_cast<uint8_t*>(msg.data()) + msg.size());

            std::cout << "Received image, len: " << msg.size() << std::endl;
            // 解码图像
            frame = cv::imdecode(buffer, cv::IMREAD_COLOR);

            cv::imshow("sub", frame);
            cv::waitKey(1);
        }
    }

    return 0;
}

方法二:gstreamer和zeromq,h264

待完善。

相关推荐
大菜菜小个子5 分钟前
偏特化(Partial Specialization)理解
c++
吴可可12316 分钟前
Win7上开发CAD2004自定义实体全解析
c++·算法
noipp21 分钟前
推荐题目:洛谷 P16510 [GKS 2015 #C] gRanks
java·c语言·开发语言·c++·python·算法
程序喵大人22 分钟前
从内存/汇编角度看C与C++:指针、引用、对象的底层差异
c语言·汇编·c++·指针·引用·对象
EasyDSS25 分钟前
安全可控、全场景适配:私有化音视频系统/视频直播点播EasyDSS一站式云平台重构视频协作新模式
安全·重构·音视频
晚风吹红霞34 分钟前
C++ vector 深度剖析:从入门到模拟实现,避开所有坑
开发语言·c++
不会C语言的男孩43 分钟前
C++ Primer 第5章:语句
开发语言·c++
Swift社区1 小时前
OpenHarmony鸿蒙PC平台移植 gifsicle:CC++ 三方库适配实践(Lycium tpc_c_cplusplus)
c语言·c++·harmonyos
superantwmhsxx1 小时前
Seedance 2.0 初探:从文生视频到可控创作的 AI 视频工作流
人工智能·计算机视觉·音视频
basketball6161 小时前
C++进阶:1. 引用折叠规则
java·开发语言·c++