树莓派与Win11通信【一对一】(二)

本文详细介绍了如何优化树莓派向Windows11发送字符串、图像数据,并提供异常处理。服务端使用Python的socket编程,客户端则通过PyQT进行数据接收和显示。

在本系列的上一篇,已经和大家分享过树莓派怎么和Win11进行简单的通信,今天给大家带来树莓派向Win11进一步发送数据并且进行一定的代码优化。

1.发送字符串和图像(服务端)

这里IP地址同样,在windos里测试时候使用本地127,具体注意点在第一篇里面有,可以打开我的主页进行查找。本次代码优化还提供了异常捕获处理

import socket
import cv2
import numpy as np

def main():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('127.0.0.1', 8084))
    server_socket.listen(1)
    print("服务器启动,等待连接...")

    while True:
        client_socket, addr = server_socket.accept()
        print(f"接受到来自 {addr} 的连接")

        cap = cv2.VideoCapture(0)

        try:
            count = 0
            while True:
                ret, frame = cap.read()
                if not ret:
                    break

                gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
                max_pixel_value = np.max(gray_frame)
                min_pixel_value = np.min(gray_frame)
                isfire = "True" if max_pixel_value > 190 else "False"
                max_min_str = f"{max_pixel_value},{min_pixel_value},{isfire},190"
                print(max_min_str)

                _, buffer = cv2.imencode('.jpg', frame)
                buffer = buffer.tobytes()

                try:
                    client_socket.sendall(len(buffer).to_bytes(4, 'big'))
                    client_socket.sendall(buffer)
                    client_socket.sendall(len(max_min_str).to_bytes(4, 'big'))
                    client_socket.sendall(max_min_str.encode())
                except socket.error as e:
                    print(f"发送数据时发生错误: {e}")
                    break

                count += 1
                print(f"已成功发送第 {count} 张图片")

        except Exception as e:
            print(f"发生异常: {e}")
        finally:
            client_socket.close()
            cap.release()

        print("等待新的连接...")

if __name__ == '__main__':
    main()

2、客户端

本次客户端的代码升级,给大家带来了一个简单的页面展示,采用的PyQT进行数据的接受,同时使用多线程接收,大家有需要的可以自己进行代码的移植

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QLineEdit
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import QThread, pyqtSignal
import socket
import numpy as np
import cv2

class ImageReceiver(QThread):
    image_signal = pyqtSignal(QPixmap)
    data_signal = pyqtSignal(str)

    def __init__(self, ip, port):
        super().__init__()
        self.ip = ip
        self.port = port
        self.running = True
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.connect((ip, port))

    def stop(self):
        self.running = False
        self.s.close()

    def receive_all(self, sock, count):
        buf = b''
        while count:
            newbuf = sock.recv(count)
            if not newbuf: return None
            buf += newbuf
            count -= len(newbuf)
        return buf

    def run(self):
        while self.running:
            try:
                length_bytes = self.receive_all(self.s, 4)
                if length_bytes is None:
                    break

                length = int.from_bytes(length_bytes, 'big')
                img_data = self.receive_all(self.s, length)
                if img_data is None:
                    break

                img_array = np.frombuffer(img_data, dtype=np.uint8)
                img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
                if img is None:
                    continue

                height, width, channel = img.shape
                bytesPerLine = 3 * width
                qImg = QImage(img.data, width, height, bytesPerLine, QImage.Format_RGB888)
                pixmap = QPixmap.fromImage(qImg)

                self.image_signal.emit(pixmap)

                max_min_length_bytes = self.receive_all(self.s, 4)
                if max_min_length_bytes is None:
                    break
                max_min_length = int.from_bytes(max_min_length_bytes, 'big')
                max_min_data = self.receive_all(self.s, max_min_length)
                if max_min_data is None:
                    break

                max_min_str = max_min_data.decode()
                self.data_signal.emit(max_min_str)

            except Exception as e:
                print(f"处理数据时发生错误: {e}")
                break

class CameraWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.image_receiver = ImageReceiver('127.0.0.1', 8084)
        self.image_receiver.image_signal.connect(self.updateImage)
        self.image_receiver.data_signal.connect(self.updateData)
        self.image_receiver.start()

    def initUI(self):
        self.imageLabel = QLabel(self)
        self.maxValueEdit = QLineEdit(self)
        self.minValueEdit = QLineEdit(self)
        self.thresholdEdit = QLineEdit(self)
        self.fireStatusEdit = QLineEdit(self)

        hbox = QHBoxLayout(self)
        vbox = QVBoxLayout()
        vbox.addWidget(self.maxValueEdit)
        vbox.addWidget(self.minValueEdit)
        vbox.addWidget(self.thresholdEdit)
        vbox.addWidget(self.fireStatusEdit)
        hbox.addWidget(self.imageLabel)
        hbox.addLayout(vbox)

        self.setLayout(hbox)
        self.setWindowTitle('Camera Viewer')
        self.show()

    def updateImage(self, pixmap):
        self.imageLabel.setPixmap(pixmap)

    def updateData(self, data):
        max_val, min_val, threshold, fire_status = data.split(',')
        self.maxValueEdit.setText(max_val)
        self.minValueEdit.setText(min_val)
        self.thresholdEdit.setText(threshold)
        self.fireStatusEdit.setText(fire_status)

    def closeEvent(self, event):
        self.image_receiver.stop()
        super().closeEvent(event)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = CameraWidget()
    sys.exit(app.exec_())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值