博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
**python使用 opencv2 和udp通信进行两路相机视频的回传,以及使用pygame同时显示两路视频**
阅读量:3951 次
发布时间:2019-05-24

本文共 7104 字,大约阅读时间需要 23 分钟。

下载源代码可参考以下网站:

https://download.csdn.net/download/qq_43790749/11288036
Python使用opencv 和pygame实现两个相机同时实时监控。具体参考如下:

发送端

1.camera.py 实现相机的调用和压缩视频数据

from threading import Thread, Lock
import cv2
import time

class VideoGrabber(Thread):

“”" A threaded video grabber

Attributes:    encode_params ():     cap (str):     attr2 (:obj:`int`, optional): Description of `attr2`.    """def __init__(self, jpeg_quality):    """Constructor.    Args:    jpeg_quality (:obj:`int`): Quality of JPEG encoding, in 0, 100.        """    Thread.__init__(self)    self.encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), jpeg_quality]    self.cap = cv2.VideoCapture(0)    self.cap1 = cv2.VideoCapture(1)    self.running = True    self.buffer = None    self.buffer1 = None    self.lock = Lock()def stop(self):    self.running = Falsedef get_buffer(self):    """Method to access the encoded buffer.    Returns:    np.ndarray: the compressed image if one has been acquired.     None otherwise.    """    if self.buffer  is not None:        self.lock.acquire()        cpy = self.buffer.copy()        self.lock.release()        return cpy   # ndarraydef get_buffer1(self):    """Method to access the encoded buffer.    Returns:    np.ndarray: the compressed image if one has been acquired.    None otherwise.    """    if self.buffer1  is not None:        self.lock.acquire()        cpy1 = self.buffer1.copy()        self.lock.release()        return cpy1   # ndarraydef run(self):    # 一直读取    while self.running:        time.sleep(0.001)        success, img = self.cap.read()        success1,img1 = self.cap1.read()        #print(success)        if not success:            continue        self.lock.acquire()        result, self.buffer = cv2.imencode('.jpg', img, self.encode_param)       # print(self.buffer)        if not success1:            continue        result1,self.buffer1 = cv2.imencode('.jpg',img1,self.encode_param)        #print(self.buffer1)        self.lock.release()

2 使用address.ini 文件存储客户端和服务端地址:

[server]
port = 12340
host = 192.168.1.4

[client]

port = 12340
host = 192.168.1.6

[client1]

port = 8080
host = 127.0.0.1

ini,py 获取address.ini 文件记录的地址:

import configparser
import os , sys

def get_address(section):

config = configparser.ConfigParser()
config.read(os.path.join(sys.path[0],r’config.ini’))
return (config.get(section=section, option=‘host’),
int(config.get(section=section, option=‘port’)))

3 send.py 调用上两个文件内的函数,进行数据发送,其中为了区分两路不同的视频信号,使用了struct.pack()函数打包了一个1和0与视频数据一起发送一区分两路不同的数据。在接收端用struct,unpack()函数进行解包,并通过解包出来的数据,判断是哪路数据。代码如下:

import socket
import sys
import time
from init import *
from camera import *
import numpy as np
import struct
jpeg_quality = 80
server_address = get_address(‘server’)
client_address = get_address(‘client’)
client_address1 = get_address(‘client1’)
buffersize = 65507

if name == ‘main’:

grabber1 = VideoGrabber(jpeg_quality)
grabber1.setDaemon(True)
grabber1.start()

running = Truesk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)sk.bind(server_address)tot_frame = 0time_sta = time.time()while(running):    time.sleep(0.001)    buffer = grabber1.get_buffer()    #print(buffer)    if buffer is None:        continue    # print(len(buffer))    buffer1 = grabber1.get_buffer1()    #print(buffer1)    if buffer1 is None:        continue    if len(buffer) > 655070:        print("The message is too large to be sent within a single UDP datagram. We do not handle splitting the message in multiple datagrams")        sk.sendto(b"FAIL",server_address)        continue    #发送第0路信号    # print(buffer1.tobytes())    sk.sendto(struct.pack("i", 0) + buffer.tobytes(), client_address1)    sk.sendto(struct.pack("i", 0) + buffer.tobytes(), client_address)    print('发送第0路信号', 'to', client_address, client_address1)    # 发送第1路信号    sk.sendto(struct.pack("i",1) + buffer1.tobytes(),client_address1)    sk.sendto(struct.pack("i",1) + buffer1.tobytes(),client_address)    print('发送第1路信号','to',client_address,client_address1)    tot_frame +=1    if tot_frame % 100 ==0 :        print("{:.2f}fps".format(tot_frame/(time.time()-time_sta)))print("Quitting..")grabber1.stop()grabber1.join()sk.close()

接收端

使用receive.py 进行接收,并使用struct.unpack()函数解包区分数据,使用pygame库进行分屏显示。其中为了原始视频数据正确,需要使用spilit()对得到的数据分割处理,将打包进来的数据切除掉后,再将其余的数据合起来,其中一点要注意spilit() 函数的用法。代码如下:

import socket
import cv2
import numpy as np
import sys
import time
from init import *
import pygame
import struct
from pygame.locals import *

sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

server_address = get_address(‘server’)
client_address = get_address(‘client1’)
buffersize = 4

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()
buffersize1 = 52000

sk.bind(client_address)

tot_frame = 0

time_sta = time.time()
ts1 = 0
ts0 = 0
a = []
a1 =b’’
data1 =b’’
flag = 2
def Get_image():

while (True):    data, addr = sk.recvfrom(buffersize)    # print(data)    info = struct.unpack("i", data)    # print(info)   # flag = data1[0]  # flag是为了辨别是那一路信号,采用0和1进行区分,详情请见服务器段程序    global data1    data1, client1 = sk.recvfrom(buffersize1)    if data1 == b"FAIL":        print("buffersize is too small or lose the packet")        continue    if ts1 >= ts0 :        if data1[0] == 1:            spilt = b'\x01\x00\x00\x00'            global a            a = data1.split(spilt)            # print(len(a))            b = b'\x01\x00\x00\x00'            global a1            a1 = a[1] + b + a[2] + b + a[3]            global ts0            ts0 = ts0 + 1            global flag            flag = 1    if ts0>= ts1:        if data1[0] == 0:            spilt = b'\x00\x00\x00\x00'            global a            a = data1.split(spilt)            # print(len(a))            b = b'\x00\x00\x00\x00'            global a1            a1 = a[1] + b + a[2] + b + a[3] + b + a[4]            global ts1            ts1 = ts1 + 1            global flag            flag = 0    print("接收到第",flag,'路信号','(',len(a),')','from',addr,'(第0路信号共',ts0,'次','第1路信号共',ts1,'次)')    array = np.frombuffer(a1, dtype=np.uint8)    img = cv2.imdecode(array, 1)  # 解码    return img, flag

while(True):

frame, flag = Get_image()

if flag == 0:    image1 = frame    #cv2.imshow("test", image1)    flag1 = flag    frame1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)  # 将图片转换成RGB格式,Opencv采用的是BGR    frame1 = np.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   # cv2.imshow("test1", image2)    flag2 = flag    frame2 = cv2.cvtColor(image2, cv2.COLOR_BGR2RGB)    frame2 = np.rot90(frame2)    frame2 = pygame.surfarray.make_surface(frame2)    screen.blit(frame2, (640, 0))pygame.display.update()  # 刷新背景tot_frame +=1if tot_frame % 100 ==0 :    print("{:.2f}fps".format(tot_frame/(time.time()-time_sta)))if cv2.waitKey(1) & 0xFF == ord('q'):    break

print("The server is quitting. ")

效果如图:

发送端
在这里插入图片描述接收端
在这里插入图片描述
下载源代码可参考以下网站:
https://download.csdn.net/download/qq_43790749/11288036

转载地址:http://gvkzi.baihongyu.com/

你可能感兴趣的文章
flash and root your Nexus10
查看>>
深入学习Make命令和Makefile(上)(2)
查看>>
深入学习Make命令和Makefile(下)(2)
查看>>
10大玄机为你揭开炒土豆丝爽脆的秘密——尖椒土豆丝
查看>>
grep与正则表达式
查看>>
git patch 使用
查看>>
如何进行Linux Kernel 开发
查看>>
技术人攻略访谈二十九:平行世界守护者
查看>>
制作initramfs/initrd镜像
查看>>
浅析busybox查找命令和调用相应命令函数的实现流程框架
查看>>
利用linux dd和tr命令生成特定的数据
查看>>
Fundamentals of battery fuel-gauging
查看>>
armlinux内核启动--内存初始化管理
查看>>
rk3188--4.android用initrd文件系统启动流程
查看>>
rk3188--3.initramfs_data.cpio的生成及使用
查看>>
小议基于Android平台的流媒体播放器的设计 转载
查看>>
linux 2.6 输入子系统 键盘驱动的实现
查看>>
Linux Input Device
查看>>
学习ARM+Linux的很好的资料
查看>>
linux spi子系统 驱动分析续
查看>>