本文共 7104 字,大约阅读时间需要 23 分钟。
下载源代码可参考以下网站:
https://download.csdn.net/download/qq_43790749/11288036 Python使用opencv 和pygame实现两个相机同时实时监控。具体参考如下:1.camera.py 实现相机的调用和压缩视频数据
from threading import Thread, Lock import cv2 import timeclass VideoGrabber(Thread):
“”" A threaded video grabberAttributes: 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.1ini,py 获取address.ini 文件记录的地址:
import configparser import os , sysdef 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 = 65507if 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 = 4pygame.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 = 52000sk.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/