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

待完善。

相关推荐
粉红色回忆2 小时前
用链表实现了简单版本的malloc/free函数
数据结构·c++
写代码的小球3 小时前
C++计算器(学生版)
c++·算法
k***92163 小时前
【C++】继承和多态扩展学习
java·c++·学习
序属秋秋秋4 小时前
《Linux系统编程之进程控制》【进程等待】
linux·c语言·c++·进程·系统编程·进程控制·进程等待
专业开发者4 小时前
2020 年国际消费电子展上,蓝牙 ® 音频迎来重磅升级
音视频
l木本I4 小时前
Reinforcement Learning for VLA(强化学习+VLA)
c++·人工智能·python·机器学习·机器人
strive programming5 小时前
Effective C++_异常(解剖挖掘)
c++
专业开发者5 小时前
蓝牙低功耗音频(Bluetooth LE Audio)最具颠覆性的新功能,当属广播音频
音视频
wregjru5 小时前
【读书笔记】Effective C++ 条款1~2 核心编程准则
java·开发语言·c++
青岛少儿编程-王老师6 小时前
CCF编程能力等级认证GESP—C++1级—20251227
java·c++·算法