案例分享:Qt的80路显示超大屏幕拼接(十台服务器,每台八路摄像头)方案和Demo

简介: 案例分享:Qt的80路显示超大屏幕拼接(十台服务器,每台八路摄像头)方案和Demo

若该文为原创文章,转载请注明原文出处

本文章博客地址:https://blog.csdn.net/qq21497936/article/details/79577035

各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)

合作案例专栏:案例分享(体验Demo可下载,只定制)

 

需求

       有10台服务器,每台8路摄像头,8路拼接处理后单个服务器输出8*1920*1080的图片数据,每台服务器输出各自的八路,实现缩放拽拖等。

 

ReadMe

 

最终采用的方案

       步骤一:客户端获取每个服务器在本地的实际rect(每个服务器在本地的原始图片拼接范围);

       步骤二:依据缩放比例系数和鼠标的位置计算出rectVirtual(按照指定点缩小放大后的图片拼接范围);

       步骤三:每个服务器所处的rectVirtual与实际显示的窗口rect()取交集,更新的每个服务器显示的范围;

       步骤四:分别组装获取指令(一个线程负责一个块区域),

                    将获取指令(x,y,width,height,scale)发送(Json);

       步骤五:接收更新显示范围后的协议数据;

       步骤六:解析协议获取rgb888数据:总长度(包括总长度4字节)(4字节)+ 图像宽度(2字节)+ 图像原始高度(2字节)+ 显示宽度(2字节) + 显示高度(2字节) + 图像数据(n字节);

       步骤七:使用服务器获取的显示数据刷新对应的显示区域,重复步骤二。

       注意:软件模拟时间主要耗在服务器对图像的变换,使用本地硬解码或者库之后(直接调库)或者从服务器获取,其时间达到20ms左右,可达到理想效果。

 

Demo

       下载地址:https://download.csdn.net/download/qq21497936/10289809

 

演示图

 

客户端关键代码(ImageWidget控件)

imagewidget.h

#ifndef IMAGEWIDGET_H
#define IMAGEWIDGET_H
#include <QWidget>
#include <QThread>
#include <QRectF>
#include "tcpclient.h"
#include <QElapsedTimer>
/************************************************************\
 * 类名:ImageWidget
 * 描述:1-10路固定19200*1080图像拼接
 * 使用:
 *      1.构建一个ImageWidget类
 *      2.设置主机地址setHostAddreess,填入一一对应的服务器ip地址list和port端口list
 *      3.调用start
 * 函数:
 *      isRunning() - 是否在运行
 *      setHostAddreess() - 设置服务器地址,如:127.0.0.1:20001,127.0.0.1:20002,则传入QList("127.0.0.1","127.0.01"),QList(20001,20002)
 *      start() - 开启运行
 *      stop() - 停止运行
 * 作者:红模仿    QQ:21497936
 *   版本         日期             描述
 *   v1.0    2018年3月12日       已优化
\************************************************************/
namespace Ui {
class ImageWidget;
}
class ImageWidget : public QWidget
{
    Q_OBJECT
public:
    explicit ImageWidget(QWidget *parent = 0);
    ~ImageWidget();
    bool isRunning();
signals:
    void signalfinished();
public slots:
    void start();
    void stop();
    void setHostAddreess(QList<QString> listIp, QList<quint16> listPort);
    void init();
protected slots:
    void recvOneImage(int index, QByteArray& data, int fullWidth, int fullHeight, int width, int height, int time);
protected:
    void paintEvent(QPaintEvent *event) override;
    void resizeEvent(QResizeEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void wheelEvent(QWheelEvent *event) override;
private slots:
    void finished();
private:
    Ui::ImageWidget *ui;
    QList<TcpClient *> _listTcpClient;
    QList<QThread *> _listTcpClientThread;
    bool _ok;
    QPoint _pointLast;
    double _add_scale_step;
    double _dec_scale_step;
    double _scale;
    QList<QRectF> _listRectRangeFullImage;         // 图片的实际尺寸
    QList<QRectF> _listRectRangeFullImageVirtual;  // 虚拟显示框框
    QList<QRectF> _listRectRangeGetImage;          // 图像数据
    QList<QRectF> _listRectRangeImageOldShow;      // 旧区域
    QList<QRectF> _listRectRangeImageShow;         // 正常情况下的需要显示的部分
    QList<QPixmap *> _listPixmap;
    bool _initRectRangeFullImageVirtual;
    QElapsedTimer _time;
    int _serverNumber;
    QList<QString> _listIp;
    QList<quint16> _listPort;
    QElapsedTimer _timerInverval;
};
#endif // IMAGEWIDGET_H

服务器代码

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QImage>
#include <QTcpServer>
#include <QTcpSocket>
#include <QByteArray>
#define SCALE_BASE (1000)
class QPaintEvent;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
protected slots:
    void newConnection();
    void readyRead();
    void doImage(int x, int y, int width, int height, double scale);
    void doImage(int x, int y, int width, int height, int vx, int vy, int vWidth, int vHeight);
protected:
    void paintEvent(QPaintEvent *event) override;
private slots:
    void on_pushButton_clicked();
private:
    Ui::MainWindow *ui;
    QImage _image;
    QTcpServer *_pTcpServer;
    QTcpSocket * _pTcpSocket;
    QByteArray _byteArrayJpg;
};
#endif // MAINWINDOW_H

 

若该文为原创文章,转载请注明原文出处

本文章博客地址:https://blog.csdn.net/qq21497936/article/details/79577035


相关文章
|
4月前
|
网络协议
Qt中的网络编程(Tcp和Udp)运用详解以及简单示范案例
Tcp和Udp是我们学习网络编程中经常接触到的两个通讯协议,在Qt也被Qt封装成了自己的库供我们调用,对于需要进行网络交互的项目中无疑是很重要的,希望这篇文章可以帮助到大家。 是关于Qt中TCP和UDP的基本使用和特点:
627 7
|
20天前
|
存储 Unix Linux
服务器数据恢复—DELL EqualLogic PS6100系列存储简介及发生故障后的处理方案
DELL EqualLogic PS6100系列存储采用虚拟ISCSI SAN阵列,支持VMware、Solaris、Linux、Mac、HP-UX、AIX操作系统,提供全套企业级数据保护和管理功能,具有可扩展性和容错功能。
|
2月前
|
存储 运维 监控
服务器高效运维管理方案
智能运维作为保障业务连续性和提升系统性能的关键环节,其重要性日益凸显。服务器作为承载各类应用与数据的核心基础设施,其稳定性、安全性和性能直接关系到企业的业务运行效率和用户体验
69 1
|
2月前
|
存储 弹性计算 SDN
企业级 ECS 集群的构建需要综合考虑多个因素,通过不断的比较和对比不同的方案,选择最适合企业自身需求和发展的架构。
【9月更文挑战第5天】在数字化商业环境中,构建企业级ECS(弹性计算服务)集群对提升业务稳定性、扩展性和性能至关重要。本文将比较传统物理服务器与ECS架构,分析云服务商选择(如AWS和阿里云)、实例配置(CPU/内存)、网络架构(SDN vs 传统)及存储方案(本地存储 vs 云存储),帮助企业根据自身需求选出最优方案,实现高效稳定的ECS集群部署。
69 18
|
3月前
|
弹性计算 运维 搜索推荐
阿里云建站方案参考:云服务器、速成美站、企业官网区别及选择参考
随着数字化转型的浪潮不断推进,越来越多的企业和公司开始将业务迁移到云端,而搭建一个专业、高效的企业官网成为了上云的第一步。企业官网不仅是展示公司形象、产品和服务的重要窗口,更是与客户沟通、传递价值的关键渠道。随着阿里云服务器和建站产品的知名度越来越高,越来越多的用户选择阿里云的产品来搭建自己的官网。本文将深入探讨在阿里云平台上,如何选择最适合自己的建站方案:云服务器建站、云·速成美站还是云·企业官网。
199 13
阿里云建站方案参考:云服务器、速成美站、企业官网区别及选择参考
|
2月前
自己动手写QT多线程demo
本文是作者关于如何编写Qt多线程demo的教程,介绍了如何实现多线程功能,包括可暂停和继续的功能。文章提供了部分示例代码,展示了如何创建线程类、启动和管理线程,以及线程间的通信。同时,还提供了相关参考资料和免费下载链接。
|
3月前
|
存储 安全 数据安全/隐私保护
服务器数据恢复—服务器raid常见故障的数据恢复方案
磁盘阵列(raid)是一种将多块物理硬盘整合成一个虚拟存储的技术。raid模块相当于一个存储管理中间层,上层接收并执行操作系统及文件系统的数据读写指令,下层管理数据在各个物理硬盘上的存储及读写。相对于单独的物理硬盘,raid可以为用户提供更大的独立存储空间,更快的读写速度,更高的数据存储安全及更方便的统一管理模式。磁盘阵列的正常运行是保障服务器中数据正常读写的关键。
服务器数据恢复—服务器raid常见故障的数据恢复方案
|
3月前
|
微服务
【Azure Cloud Services】云服务频繁发生服务器崩溃的排查方案
【Azure Cloud Services】云服务频繁发生服务器崩溃的排查方案
|
4月前
|
编解码 监控 网络协议
采用Qt+Live555搭建RTSP服务器
Live555是一个跨平台的流媒体开发库,支持多种流媒体协议,包括RTSP、SIP、RTP等,可以帮助我们快速实现视频流的传输和处理。
330 1
采用Qt+Live555搭建RTSP服务器
|
3月前
【qt】客户端连接到服务器
【qt】客户端连接到服务器
61 0

热门文章

最新文章

推荐镜像

更多