基于TCP网络传输协议和python3 的双路视频数据和单路指令传输显示系统的代码

注意:这个代码是很早之前的写的一个小代码,可能会有一些地方会出现一些小问题,但是我在局域网的情况下已经测试过了。仅仅是局域网

 服务端代码:

#!/usr/bin/env python
# -*- coding:utf-8 -*- 
# Author: K_liu
'''
这是一个服务器端程序
可以通过TCP传输协议实现两路视频传输,一路指令传输,本程序采用一个随机数来模拟指令
'''
import socket
import struct
import time
import cv2
import numpy
import random

# 设置套接字,本程序采用TCP协议,当然也可以采用UDP协议,但是要保证指令传输的正确性,所以采用了TCP协议。
addr = ("0.0.0.0", 8080)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1) #端口可复用
server_socket.bind(addr) # 绑定地址端口
server_socket.listen(True) # 进入监听状态

def Package(camera,img, img_resolution, img_param, conn_client, flag):# 注意flag是一个数据区分标志,0和1分别表示两路数据
    '本函数的主要功能是实现Opencv采集到的视频数据进行转码,同时进行数据打包传输'
    number = random.randint(1,10) # 生成一个1到10的随机数,模拟指令
    frame = cv2.resize(img, img_resolution) # 对图像数据大小进行设定
    _, frame_encode = cv2.imencode('.jpg', frame, img_param) # 进行编码,编码成可以传输的jpg格式,Opencv的数据是不能直接传输的
    numpy_frame = numpy.array(frame_encode) # 将编码的图片转成numpy的数组
    data_frame = numpy_frame.tostring() # 转成字符串,网络传输只能传输str格式
    try:
        # 按照相应的格式进行打包发送图片
        conn_client.send(struct.pack("lhh", len(numpy_frame), flag, number)
                         + data_frame)
    except:
        camera.release()
        return 0

def Send_image(conn_client):
    img_fps = 30 # 设置帧率
    img_resolution = (640, 480)
    # 初始化摄像头
    camera1 = cv2.VideoCapture(0)
    camera2 = cv2.VideoCapture(1)
    img_param = [int(cv2.IMWRITE_JPEG_QUALITY), img_fps]  # 设置传送图像格式、帧数
    while(1): # 下面的就不用注释了吧
        time.sleep(0.1)
        ret1, frame1 = camera1.read()
        ret2, frame2 = camera2.read()
        Package(camera1,frame1,img_resolution,img_param,conn_client,0)
        time.sleep(0.1)
        Package(camera1, frame2, img_resolution, img_param, conn_client, 1)

if __name__ == '__main__':
    print('Waiting the connecting ...')
    conn, addr = server_socket.accept()
    print('connected form the: {}'.format(addr))
    Send_image(conn)


 客户端代码

#!/usr/bin/env python
# -*- coding:utf-8 -*- 
# Author: K_liu
'''
这是一个客户端程序,由于需要显示两路视频画面,所以采用pygame来进行编写程序,Opencv界面可定制化没有pygame灵活
当然大家也可以采用python的其他GUI开发工具。
'''
import socket
import cv2
import struct
import numpy
import pygame
from pygame.locals import *
from sys import exit
global image1
global image2

# Configuration file
pygame.init() # 初始化pygame
window_size = (1280, 480) # 设置显示界面大小
screen = pygame.display.set_mode(window_size, 0, 32) # pygame显示设置
pygame.display.set_caption('Two Camera Show') # 设置显示标题
pygame.display.flip()
clock = pygame.time.Clock()

def Get_image():
    info = struct.unpack("lhh", client_socket.recv(8)) # 进行数据包解包操作
    flag = info[1] # flag是为了辨别是那一路信号,采用0和1进行区分,详情请见服务器段程序
    print('模拟指令:{}'.format(info[2]))
    buf_size = info[0]  # 获取读的图片总长度
    if buf_size:
        try:
            buf = b""  # 代表bytes类型
            temp_buf = buf
            while (buf_size):  # 读取每一张图片的长度
                temp_buf = client_socket.recv(buf_size)
                buf_size -= len(temp_buf)
                buf += temp_buf  # 获取图片
                data = numpy.fromstring(buf, dtype='uint8')  # 按uint8转换为图像矩阵
                image = cv2.imdecode(data, 1)  # 图像解码
                return image, flag
        except:
            pass

def ShowImage():
    while (1):
        for event in pygame.event.get():
            if event.type == QUIT:
                exit()
        frame, flag = Get_image()
        if flag == 0:
            image1 = frame
            flag1 = flag
            frame1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)#将图片转换成RGB格式,Opencv采用的是BGR
            frame1 = numpy.rot90(frame1)
            frame1 = cv2.flip(frame1, 0, dst= None)
            frame1 = pygame.surfarray.make_surface(frame1) # 转换成pygame的背景格式
            screen.blit(frame1, (0, 0)) # 进行背景渲染

        elif flag == 1:
            image2 = frame
            flag2 = flag
            frame2 = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB)
            frame2 = numpy.rot90(frame2)
            frame2 = pygame.surfarray.make_surface(frame2)
            screen.blit(frame2, (640,0))
        pygame.display.update() # 刷新背景



if __name__ == '__main__':
    addr_port = ('127.0.0.1', 8080)
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 端口可复用
    client_socket.connect(addr_port)
    print("IP is %s:%d" % (addr_port[0], addr_port[1]))
    ShowImage()


 

你可能感兴趣的:(opencv3-0,python3,pygame)