PyQt+Qt 利用QUdpSocket进行本机通信,下位机向上位机传输QImage图像数据及int型数据

11 篇文章 1 订阅
5 篇文章 1 订阅


前言

  在涉及到多个部门之间的软件开发过程时,往往会出现在同一台设备上的多个程序进程之间的通信问题。
  下位机进行数据的采集及解算工作,将运行结果发送至上位机进行展示等。由于上位机、下位机由不同单位或部门的人编写,所使用的编程语言可能不尽相同,且也有可能涉及到保密问题,故不可能互相公开源码以进行统一的编译工作,从而需要进行程序之间的通信。
  在本项目中,下位机(数据发送端、客户端)采用python的PyQt框架进行编写,发送实时处理后的图像、图像识别状态;上位机(数据接收端、服务端)采用C++的Qt框架进行编写,接收图像、识别状态并进行展示。
  利用Qt自带的QUdpSocket模块进行通信。


效果

  实验效果如下图所示,画面左边的小框是下位机右边的大框是上位机

在这里插入图片描述
  下位机的作用是实时拍摄人脸图像,并判断当前人脸是出于什么状态,总共有4个状态如下表所示,下位机将经过处理后的实时图像以及当前判定状态向上位机进行发送。

数字含义
0图像缺失
1清醒
2疲劳
3重度疲劳

  上位机将接收到的QImage图像进行展示,并且一并展示出当前发出的状态信号,如“0”、“1”、“2”等,外加一个QLabel展示图像的状态,即“清醒”、“疲劳”或者是“图像缺失”等。


核心代码

编程思路

  通过Qt自带的QUdpSocket模块进行通信,由于是在同一台电脑上进行通信,上位机、下位机ip地址均设置为"127.0.0.1"即本机的回环地址,端口号设置为“5555”“5556”,其中“5555”用于发送图像数据、“5556”用于发送状态判断int型数值。

下位机

Widget类的初始化方法中,进行相关ip地址、端口号的绑定工作。

self.camera_thread.sendPicture[QImage].connect(self.receive)这里在Widget类中需要声明一个camera类,camera类用于处理实时接收图像等图像相关的操作,绑定camera类的sendPicture信号与Widget类中receive槽函数,令receive槽函数中进行相关的数据传输工作代码如下。

byte = QByteArray()
buff = QBuffer(byte)
buff.open(QIODevice.WriteOnly)
img.save(buff, "JPEG")
ss = qCompress(byte, 5)
self.udpSocket.writeDatagram(ss, self.dstip, self.dstport)
datagram = QByteArray(1, str(self.camera_thread.detector.noImageFlag))
self.udpSocket_2.writeDatagram(datagram, self.dstip, self.dstport_2)

下位机widget的相关代码如下所示

from UI.ui_Widget import *
from PyQt5.QtNetwork import QUdpSocket, QHostAddress
from PyQt5.QtCore import QBuffer, QByteArray, QIODevice, qCompress
from PyQt5.QtGui import QImage


class Widget(QWidget, Ui_Widget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self.setupUi(self)
        
		#此处略去与通信无关的代码
		
        # UDP通信
        # 创建两个套接字,第一个用于传输图像,第二个用于传int型变量
        self.udpSocket = QUdpSocket()
        self.udpSocket_2 = QUdpSocket()
        # 设置ip地址
        self.dstip = QHostAddress('127.0.0.1')
        # 设置目标地址的端口号
        self.dstport = 5555
        self.dstport_2 = 5556
		# 发送端可以不bind具体的端口

		# 此处略去一些与通信无关的代码
        # 连接Camera的sendPicture信号与receive函数进行展示
        self.camera_thread.sendPicture[QImage].connect(self.receive)
   
       def receive(self, img):
        img_height = self.label_2.height()
        img_width = self.label_2.width()
        # QImage.scaled若图像尺寸较大,会卡顿,暂时没有什么好方法
        new_img = img.scaled(QSize(img_width, img_height))
        self.label_2.setPixmap(QPixmap.fromImage(new_img))

        byte = QByteArray()
        buff = QBuffer(byte)
        buff.open(QIODevice.WriteOnly)
        img.save(buff, "JPEG")
        ss = qCompress(byte, 5)
        self.udpSocket.writeDatagram(ss, self.dstip, self.dstport)
        if self.camera_thread.detector.noImage == 1:
            datagram = QByteArray(1, str(self.camera_thread.detector.noImageFlag))
        else:
            datagram = QByteArray(1, str(self.camera_thread.detector.JudgeCondition.condition))
        self.udpSocket_2.writeDatagram(datagram, self.dstip, self.dstport_2)

上位机

connect(&receiver,SIGNAL(readyRead()),this,SLOT(video_receive_show()));在udp套接字接收到信号完成后会发送一个readRead()信号,该信号绑定槽函数video_receive_show()进行图像数据显示,具体代码如下所示。

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QUdpSocket>
#include<QPixmap>
#include<QImageReader>
#include<QBuffer>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

public slots:
  void video_receive_show();
  void condition_show();

private:
    Ui::Widget *ui;
    QUdpSocket receiver;
    QUdpSocket receiver_2;

};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QHostAddress>
#include <QProcess>


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QHostAddress adrr = QHostAddress("127.0.0.1");
	
	//接收端需要bind具体的ip地址及端口号
    receiver.bind(adrr, 5555);
    receiver_2.bind(adrr, 5556);
    connect(&receiver,SIGNAL(readyRead()),this,SLOT(video_receive_show()));
    connect(&receiver_2,SIGNAL(readyRead()),this,SLOT(condition_show()));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::video_receive_show()
{
    quint64 size = receiver.pendingDatagramSize();
    QByteArray buff;
    buff.resize(size);
    QHostAddress adrr ;
    quint16 port;
    receiver.readDatagram(buff.data(),buff.size(),&adrr,&port);

    buff = qUncompress(buff);
    QBuffer buffer(&buff);
    QImageReader reader(&buffer,"JPEG");
    QImage image = reader.read();
    QImage img;


    img = image.scaled(ui->label->width(), ui->label->height());
    ui->label->setPixmap(QPixmap::fromImage(img));
//    ui->label->resize(image.width(),image.height());

}

void Widget::condition_show()
{
    quint64 size = receiver_2.pendingDatagramSize();
    QByteArray buff;
    buff.resize(size);
    QHostAddress adrr ;
    quint16 port;
    receiver_2.readDatagram(buff.data(),buff.size(),&adrr,&port);
    QString msg = buff.data();

//    qDebug()<<buff;
    ui->label_3->setText(msg);

    int num = msg.toInt();

    switch(num)
    {
    case 1:
        ui->label_2->setText(QString::fromLocal8Bit("清醒"));
        ui->label_2->setStyleSheet("background-color: rgb(0, 255, 127);"
                                   "font: 22pt '微软雅黑';");
        break;

    case 2:
        ui->label_2->setText(QString::fromLocal8Bit("疲劳"));
        ui->label_2->setStyleSheet("background-color: rgb(255, 170, 0);;"
                                   "font: 22pt '微软雅黑';");
        break;

    case 3:
        ui->label_2->setText(QString::fromLocal8Bit("重度疲劳"));
        ui->label_2->setStyleSheet("background-color: rgb(255, 0, 0);;"
                                   "font: 22pt '微软雅黑';");
        break;

    case 0:
        ui->label_2->setText(QString::fromLocal8Bit("图像缺失"));
        ui->label_2->setStyleSheet("background-color: rgb(226, 226, 226);;"
                                   "font: 22pt '微软雅黑';");
        break;
    }
}

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python上位机可以通过适当的库和代码实现读取图片的功能。其中,常用的库包括Pillow和OpenCV。Pillow是一种Python图像处理库,可以用于打开,操作和保存各种图像文件格式。而OpenCV是一个功能强大的计算机视觉库,提供了各种图像处理和分析的功能。 使用Pillow库,你可以使用open()函数打开图像文件,然后使用load()函数加载图像数据。例如,你可以使用以下代码读取名为"image.jpg"的图片文件: from PIL import Image image = Image.open("image.jpg") data = image.load() 这样,你可以使用data变量来访问图像的像素数据,并进行进一步的处理。 如果你更倾向于使用OpenCV库,你可以使用cv2.imread()函数来读取图像文件。例如,你可以使用以下代码读取名为"image.jpg"的图片文件: import cv2 image = cv2.imread("image.jpg") 这样,你可以使用image变量来访问图像的像素数据,并进行进一步的处理。 需要注意的是,这些代码示例中的文件路径应该根据实际情况进行相应的更改,以便读取正确的图像文件。同时,你还可以根据具体需求对读取到的图像数据进行进一步的处理和操作。 综上所述,您可以使用Pillow或OpenCV库中的相应函数来实现Python上位机读取图片的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [python上位机开发实例-python上位机](https://blog.csdn.net/weixin_37988176/article/details/109376965)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wang_chao118

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值