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

待完善。

相关推荐
艾莉丝努力练剑16 分钟前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
Once_day32 分钟前
C++之《程序员自我修养》读书总结(1)
c语言·开发语言·c++·程序员自我修养
Trouvaille ~42 分钟前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
坚果派·白晓明1 小时前
在鸿蒙设备上快速验证由lycium工具快速交叉编译的C/C++三方库
c语言·c++·harmonyos·鸿蒙·编程语言·openharmony·三方库
小镇敲码人1 小时前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann
晚霞的不甘1 小时前
CANN 编译器深度解析:TBE 自定义算子开发实战
人工智能·架构·开源·音视频
愚公搬代码1 小时前
【愚公系列】《AI短视频创作一本通》016-AI短视频的生成(AI短视频运镜方法)
人工智能·音视频
张张努力变强2 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
小镇敲码人2 小时前
探索CANN框架中TBE仓库:张量加速引擎的优化之道
c++·华为·acl·cann·ops-nn
那个村的李富贵2 小时前
CANN赋能AIGC“数字人”革命:实时视频换脸与表情驱动实战
aigc·音视频