zoukankan      html  css  js  c++  java
  • python实现opencv+scoket网络实时图传

    服务器分析:

    1. 先通过在服务器端利用OpenCV捕获到视频的每一帧图片

    2. 将这些图片进行压缩成JPEG格式,这样能减小图片大小,便于传输

    3. 按照提前协商好的分辨率和帧数进行打包编码传输

    4. 利用服务器端打开端口8880,此时客户端连接后,便可以在客户端中捕获到服务器端的视频。

    #服务端
    
    import socket
    import threading
    import struct
    import time
    import cv2
    import numpy
     
    class Carame_Accept_Object:
        def __init__(self,S_addr_port=("",8880)):
            self.resolution=(640,480)       #分辨率
            self.img_fps=15                 #每秒传输多少帧数
            self.addr_port=S_addr_port
            self.Set_Socket(self.addr_port)
     
        #设置套接字
        def Set_Socket(self,S_addr_port):
            self.server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            self.server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #端口可复用
            self.server.bind(S_addr_port)
            self.server.listen(5)
            #print("the process work in the port:%d" % S_addr_port[1])
     
     
    def check_option(object,client):
        #按格式解码,确定帧数和分辨率
        info=struct.unpack('lhh',client.recv(8))
        if info[0]>888:
            object.img_fps=int(info[0])-888          #获取帧数
            object.resolution=list(object.resolution)
            # 获取分辨率
            object.resolution[0]=info[1]
            object.resolution[1]=info[2]
            object.resolution = tuple(object.resolution)
            return 1
        else:
            return 0
     
    def RT_Image(object,client,D_addr):
        if(check_option(object,client)==0):
            return
        camera=cv2.VideoCapture(0)                                #从摄像头中获取视频
        img_param=[int(cv2.IMWRITE_JPEG_QUALITY),object.img_fps]  #设置传送图像格式、帧数
        while(1):
            time.sleep(0.1)             #推迟线程运行0.1s
            _,object.img=camera.read()  #读取视频每一帧
     
            object.img=cv2.resize(object.img,object.resolution)     #按要求调整图像大小(resolution必须为元组)
            _,img_encode=cv2.imencode('.jpg',object.img,img_param)  #按格式生成图片
            img_code=numpy.array(img_encode)                        #转换成矩阵
            object.img_data=img_code.tostring()                     #生成相应的字符串
            try:
                #按照相应的格式进行打包发送图片
                client.send(struct.pack("lhh",len(object.img_data),object.resolution[0],object.resolution[1])+object.img_data)
            except:
                camera.release()        #释放资源
                return
     
    if __name__ == '__main__':
        camera=Carame_Accept_Object()
        while(1):
            client,D_addr=camera.server.accept()
            clientThread=threading.Thread(None,target=RT_Image,args=(camera,client,D_addr,))
            clientThread.start()
    

    客户端分析:

    1. 客户端连接端口后,首先发送需要协商的分辨率和帧数,以致能够使传输“协议”一致

    2. 客户端使用线程,对图片进行收集

    3. 对收到的每一张图片进行解码,并利用OpenCV播放出来,即可实现C/S两端实时视频传输。

    
    #客户端
     
     
    import socket
    import cv2
    import threading
    import struct
    import numpy
     
    class Camera_Connect_Object:
        def __init__(self,D_addr_port=["",8880]):
            self.resolution=[640,480]
            self.addr_port=D_addr_port
            self.src=888+15                 #双方确定传输帧数,(888)为校验值
            self.interval=0                 #图片播放时间间隔
            self.img_fps=15                 #每秒传输多少帧数
     
        def Set_socket(self):
            self.client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            self.client.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
     
        def Socket_Connect(self):
            self.Set_socket()
            self.client.connect(self.addr_port)
            print("IP is %s:%d" % (self.addr_port[0],self.addr_port[1]))
     
        def RT_Image(self):
            #按照格式打包发送帧数和分辨率
            self.name=self.addr_port[0]+" Camera"
            self.client.send(struct.pack("lhh", self.src, self.resolution[0], self.resolution[1]))
            while(1):
                info=struct.unpack("lhh",self.client.recv(8))
                buf_size=info[0]                    #获取读的图片总长度
                if buf_size:
                    try:
                        self.buf=b""                #代表bytes类型
                        temp_buf=self.buf
                        while(buf_size):            #读取每一张图片的长度
                            temp_buf=self.client.recv(buf_size)
                            buf_size-=len(temp_buf)
                            self.buf+=temp_buf      #获取图片
                            data = numpy.fromstring(self.buf, dtype='uint8')    #按uint8转换为图像矩阵
                            self.image = cv2.imdecode(data, 1)                  #图像解码
                            cv2.imshow(self.name, self.image)                   #展示图片
                    except:
                        pass;
                    finally:
                        if(cv2.waitKey(10)==27):        #每10ms刷新一次图片,按‘ESC’(27)退出
                            self.client.close()
                            cv2.destroyAllWindows()
                            break
     
        def Get_Data(self,interval):
            showThread=threading.Thread(target=self.RT_Image)
            showThread.start()
     
    if __name__ == '__main__':
        camera=Camera_Connect_Object()
        camera.addr_port[0]="服务端的ip"
        camera.addr_port=tuple(camera.addr_port)
        camera.Socket_Connect()
        camera.Get_Data(camera.interval)
    
  • 相关阅读:
    HDUOJ---1863畅通工程
    HDUOJ---1879 继续畅通工程
    HDUOJ---1102Constructing Roads
    HDUOJ---1102Constructing Roads
    hdu--DFS
    poj1611---The Suspects
    nyoj-----幸运三角形
    HDUOJ --2523
    HDUOJ---1195Open the Lock
    HDUOJ----2952Counting Sheep
  • 原文地址:https://www.cnblogs.com/enumx/p/12387722.html
Copyright © 2011-2022 走看看