使用socket实现客户端和服务端进行摄像头图传实时回传

实时传输视频流

  1. 客户端需要的做的是连接服务端然后读摄像头数据发送给服务端需要注意的是服务器的IP地址需要注意一下,这里用的是服务端的IP地址,(这里使用的是树莓派5在服务端)

  2. #以下是客户端程序
    import socket
    import struct
    import time
    import traceback
    
    import cv2
    import numpy
    
    
    class Client(object):
        """客户端"""
    
        def __init__(self, addr_port=('192.168.149.1', 11000)):
            # 连接的服务器的地址
            # 连接的服务器的端口
            self.addr_port = addr_port
            # 创建套接字
            self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            # 地址端口可以复用
            self.client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    
            # 分辨率
            self.resolution = (640, 480)
    
    
        def connect(self):
            """链接服务器"""
            try:
                self.client.connect(self.addr_port)
                return True
            except Exception as e:
                traceback.print_exc()  # 打印原始的异常信息
                print('连接失败')
                return False
    
        def send2server(self):
            """读摄像头数据 发送给服务器"""
            camera = cv2.VideoCapture(0)  # 摄像头对象
            print('isOpened:', camera.isOpened())
    
            while camera.isOpened():
    
                try:
                    # 获取摄像头数据
                    ret, frame = camera.read()
                    # 对每一帧图片做大小处理 和大小的压缩
                    frame = cv2.resize(frame, self.resolution)
                    # 参1图片后缀名 参2 原图片的数据 参3图片质量 0-100 越大越清晰
                    ret, img = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 100])
                    # img 是被压缩后的数据 无法正常显示
                    print(img)
                    print('-------------')
                    print(img.tostring())
    
                    # 转换为numpy格式数据
                    img_code = numpy.array(img)
    
                    # 转为二进制数据
                    img = img_code.tostring()
    
                    # 获取数据长度
                    length = len(img)
    
                    # 发送的数据  大小 宽 高 图片数据
    
                    # 数据打包变为二进制
                    # pack方法参数1 指定打包数据的数据大小  i 4字节 h代表2字节
                    all_data = struct.pack('ihh', length, self.resolution[0], self.resolution[1]) + img
    
                    self.client.send(all_data)
                    time.sleep(0.01)
                except:
                    camera.release()  # 释放摄像头
                    traceback.print_exc()
                    return
    
    
    if __name__ == '__main__':
        client = Client()
        if client.connect():
            client.send2server()
    

    服务端:在运行的时间需要先运行服务端在运行客户端

    import socket
    import struct
    import threading
    import cv2
    import numpy
    import os
    
    
    class Server:
        def __init__(self):
            # 设置tcp服务端的socket
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            # 设置重复使用
            self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
            # 绑定地址和端口
            self.server.bind(('192.168.149.1', 11000))
            # 设置被动监听
            self.server.listen(128)
    
        def run(self):
            while True:
                print('等待客户端连接')
                # 等待客户端连接
                client, addr = self.server.accept()
                ProcessClient(client).start()
    
    
    class ProcessClient(threading.Thread):
    
        def __init__(self, client):
            super().__init__()
            self.client = client
            self.i = 0  # 初始化i的值
    
            # 获取文件夹中图片序号最大的值
            path = "D:/sample"
            file_list = []
            for root, dirs, files in os.walk(path, topdown=False):
                # 确保files是当前目录下的文件列表
                for file in files:
                    if file.endswith(('.png', '.jpg', '.jpeg')):  # 只处理图片文件
                        file_number = int(file.split('.')[0])  # 假设文件名是数字和图片扩展名组成
                        file_list.append(file_number)
    
            if len(file_list) == 0:
                self.i = 0
            else:
                file_list.sort()
                self.i = file_list[-1] + 1
    
        def run(self):
            while True:
                data = self.client.recv(8)
                if not data:
                    break
                # 图片的长度 图片的宽高
                length, width, height = struct.unpack('ihh', data)
    
                imgg = b''  # 存放最终的图片数据
                while length:
                    # 接收图片
                    temp_size = self.client.recv(length)
                    length -= len(temp_size)  # 每次减去收到的数据大小
                    imgg += temp_size  # 每次收到的数据存到img里
    
                # 把二进制数据还原
                data = numpy.fromstring(imgg, dtype='uint8')
    
                # 还原成矩阵数据
                image = cv2.imdecode(data, cv2.IMREAD_UNCHANGED)
                print(image)
    
                cv2.imshow('capture', image)
                # 保存图片
                k = cv2.waitKey(1)
                if k == ord('k'):
                    cv2.imwrite(r"F:\sample\\" + str(self.i) + ".jpg", image)  # 存储路径
                    self.i = self.i + 1
                    print(self.i)
                    # time.sleep(5)
    
                if k == ord('q'):
                    break
    
    
    if __name__ == '__main__':
        server = Server()
        server.run()
    

    以下是效果:

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 Java Socket 实现客户端服务端对话的示例代码: 服务端代码: ```java import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class Server { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(8888); System.out.println("Server started."); Socket socket = serverSocket.accept(); System.out.println("Client connected."); Scanner scanner = new Scanner(System.in); while (true) { String message = scanner.nextLine(); socket.getOutputStream().write(message.getBytes()); byte[] buffer = new byte[1024]; int len = socket.getInputStream().read(buffer); System.out.println("Client: " + new String(buffer, 0, len)); } } catch (IOException e) { e.printStackTrace(); } } } ``` 客户端代码: ```java import java.io.IOException; import java.net.Socket; import java.util.Scanner; public class Client { public static void main(String[] args) { try { Socket socket = new Socket("localhost", 8888); System.out.println("Connected to server."); Scanner scanner = new Scanner(System.in); while (true) { byte[] buffer = new byte[1024]; int len = socket.getInputStream().read(buffer); System.out.println("Server: " + new String(buffer, 0, len)); String message = scanner.nextLine(); socket.getOutputStream().write(message.getBytes()); } } catch (IOException e) { e.printStackTrace(); } } } ``` 以上是一个简单的 Java Socket 实现客户端服务端对话的示例代码,仅供参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值