美文网首页python视频
基于python和opencv的视频传输程序(一)

基于python和opencv的视频传输程序(一)

作者: 遗步看风景 | 来源:发表于2017-01-04 21:02 被阅读5083次

    用python通过opencv模块来做实时监控这件事情很早就想做了,但是因为本人的拖延症一直被搁置直到最近强迫自己才通过网上的现有资料进行进行更改,完成了这个基本能正常工作的版本,我们暂且叫他1.0

    首先是服务器端代码,主要功能其实就是通过opencv模块进行摄像头数据的采集,然后将每一帧数据,也就是图像,通过cv2.imencode()函数转换成jpg格式,这个步骤主要是为了将数据进行压缩,不然传输的数据量太大,我们通常外网访问基本没法承受。(假设我们不去进行任何数据压缩处理,那一个380240的图片实际上是3804203(这个3是因为是RGB图)个字节,也就是470kb,一秒就算只有10帧,那也至少需要4.7MB每秒的传输速度。那显然不靠谱。)压缩完之后,然后通过socket模块使用tcp协议将数据发送出去,服务器端程序基本面功能也就完成了。

    服务器端代码:

    客户端代码,主要使用socket模块通过tcp协议将服务器发来的数据进行解码,然后显示在自己的电脑上,由于本人极端厌恶做人机交互界面,所以这里通过配置文件的形式来改变整个监控的参数,比如每秒几帧,图像分辨率,图像质量,还有服务器ip。首次运行,系统会自动创建配置文件,txt格式,然后将配置文件里的数据改成你需要的数据再保存,再次运行程序,程序会自动读取你最新配置的配置参数。

    客户端代码:


    import socket;  
    import threading;
    import struct;
    import cv2
    import time
    import os
    import numpy
    
    class webCamera: 
        def __init__(self, resolution = (640, 480), host = ("", 7999)):      
            self.resolution = resolution;      
            self.host = host;      
            self.setSocket(self.host);    
            self.img_quality = 15
        def setImageResolution(self, resolution):      
            self.resolution = resolution;  
        def setHost(self, host):      
            self.host = host;  
        def setSocket(self, host):      
            self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM);                  
            self.socket.setsockopt(socket.SOL_SOCKET,           socket.SO_REUSEADDR,1);              
            self.socket.bind(self.host);      
            self.socket.listen(5);      
            print("Server running on port:%d" % host[1]);
        def recv_config(self,client):    
            info = struct.unpack("lhh",client.recv(8));    
            if info[0]>911:        #print(info[0])        
                self.img_quality=int(info[0])-911              
                self.resolution=list(self.resolution)        
                self.resolution[0]=info[1]        
                self.resolution[1]=info[2]        
                self.resolution=tuple(self.resolution)                
                return 1    
            else :        
                return 0
        def _processConnection(self, client,addr):     
            if(self.recv_config(client)==0):        
                return    
            camera = cv2.VideoCapture(0)    
            encode_param=[int(cv2.IMWRITE_JPEG_QUALITY),self.img_quality]             
            f = open("video_info.txt", 'a+')    
            print("Got connection from %s:%d" % (addr[0], addr[1]),file=f);    
            print("像素为:%d * %d"%(self.resolution[0],self.resolution[1]),file=f)    
            print ("打开摄像头成功",file=f)    
            print("连接开始时间:%s"%time.strftime("%Y-%m-%d %H:%M:%S", 
                    time.localtime(time.time())),file=f)    
            f.close()    
            while(1):        
                time.sleep(0.13)        
                (grabbed, self.img) = camera.read()        
                self.img  = cv2.resize(self.img,self.resolution)             
                result, imgencode = cv2.imencode('.jpg',self.img,encode_param)        
                img_code = numpy.array(imgencode)        
                self.imgdata  = img_code.tostring()                   
                try:                    
                    client.send(struct.pack("lhh",len(self.imgdata),
                            self.resolution[0],self.resolution[1])+self.imgdata); #发送图片信息(图片
                                        长度,分辨率,图片内容)                
                except:            
                    f = open("video_info.txt", 'a+')            
                    print("%s:%d disconnected!" % (addr[0], addr[1]),file=f);            
                    print("连接结束时间:%s"%time.strftime("%Y-%m-%d %H:%M:%S", 
                        time.localtime(time.time())),file=f)      
                    print("****************************************",file=f)
                    camera.release()            
                    f.close()            
                    return;
        def run(self):      
            while(1):        
                client,addr = self.socket.accept();        
                clientThread = threading.Thread(target = self._processConnection, 
                    args = (client, addr, ));  #有客户端连接时产生新的线程进行处理                      
                clientThread.start();
        def main():      
            cam = webCamera();       
            cam.run();  
    if __name__ == "__main__":      
        main();  
    
    

    客户端代码,主要使用socket模块通过tcp协议将服务器发来的数据进行解码,然后显示在自己的电脑上,由于本人极端厌恶做人机交互界面,所以这里通过配置文件的形式来改变整个监控的参数,比如每秒几帧,图像分辨率,图像质量,还有服务器ip。首次运行,系统会自动创建配置文件,txt格式,然后将配置文件里的数据改成你需要的数据再保存,再次运行程序,程序会自动读取你最新配置的配置参数。

    客户端代码:


    import socket;  
    import threading;  
    import struct;  import os;  
    import time;  import sys;
    import numpy
    import cv2import re
    class webCamConnect:      
        def __init__(self, resolution = [640,480], remoteAddress = ("115.216.215.130", 
                        7999), windowName = "video"):          
            self.remoteAddress = remoteAddress;        
            self.resolution = resolution;          
            self.name = windowName;          
            self.mutex = threading.Lock();        
            self.src=911+15        
            self.interval=0        
            self.path=os.getcwd()        
            self.img_quality = 15
        def _setSocket(self):      
            self.socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM);  
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
        def connect(self):      
            self._setSocket();      
            self.socket.connect(self.remoteAddress);  
        def _processImage(self):    
            self.socket.send(struct.pack("lhh",self.src,self.resolution[0],self.resolution[1]));
            while(1):        
                info = struct.unpack("lhh",self.socket.recv(8));        
                bufSize = info[0];        
                if bufSize:           
                     try:                  
                        self.mutex.acquire();                
                        self.buf=b''                
                        tempBuf=self.buf;                
                        while(bufSize):                 #循环读取到一张图片的长度
                            tempBuf = self.socket.recv(bufSize);                    
                            bufSize -= len(tempBuf);                    
                            self.buf += tempBuf;                
                            data = numpy.fromstring(self.buf,dtype='uint8')
                            self.image=cv2.imdecode(data,1)         
                            cv2.imshow(self.name,self.image)            
                     except:                
                         print("接收失败")                
                         pass;              
                     finally:                
                         self.mutex.release();               
                         if cv2.waitKey(10) == 27:                    
                             self.socket.close()                    
                             cv2.destroyAllWindows()                    
                             print("放弃连接")                    
                             break
        def getData(self, interval):            
            showThread=threading.Thread(target=self._processImage);     
            showThread.start();      
            if interval != 0:   # 非0则启动保存截图到本地的功能  
                saveThread=threading.Thread(target=self._savePicToLocal,args = (interval, 
                    ));          
                saveThread.setDaemon(1);          
                saveThread.start();  
        def setWindowName(self, name):      
            self.name = name; 
        def setRemoteAddress(remoteAddress):      
            self.remoteAddress = remoteAddress;   
        def _savePicToLocal(self, interval):      
        while(1):          
            try:              
                self.mutex.acquire();              
                path=os.getcwd() + "\\" + "savePic";              
                if not os.path.exists(path):                  
                    os.mkdir(path);            
                cv2.imwrite(path + "\\" + time.strftime("%Y%m%d-%H%M%S", 
                        time.localtime(time.time())) + ".jpg",self.image)        
            except:              
                pass;          
            finally:              
                self.mutex.release();              
                time.sleep(interval);
        def check_config(self):    
            path=os.getcwd()    
            print(path)      
            if os.path.isfile(r'%s\video_config.txt'%path) is False:        
                f = open("video_config.txt", 'w+')        
                print("w = %d,h = %d" %(self.resolution[0],self.resolution[1]),file=f)
                print("IP is %s:%d" %(self.remoteAddress[0],self.remoteAddress[1]),file=f)
                print("Save pic flag:%d" %(self.interval),file=f)        
                print("image's quality is:%d,range(0~95)"%(self.img_quality),file=f)   
                f.close()        
                print("初始化配置");    
            else:        
                f = open("video_config.txt", 'r+')        
                tmp_data=f.readline(50)#1 resolution
                num_list=re.findall(r"\d+",tmp_data)        
                self.resolution[0]=int(num_list[0])        
                self.resolution[1]=int(num_list[1])        
                tmp_data=f.readline(50)#2 ip,port        
                num_list=re.findall(r"\d+",tmp_data)        
                str_tmp="%d.%d.%d.%d"        
                        %(int(num_list[0]),int(num_list[1]),int(num_list[2]),int(num_list[3])) 
                self.remoteAddress=(str_tmp,int(num_list[4]))        
                tmp_data=f.readline(50)#3 savedata_flag
                self.interval=int(re.findall(r"\d",tmp_data)[0])        
                tmp_data=f.readline(50)#3 savedata_flag        
                #print(tmp_data)        
                self.img_quality=int(re.findall(r"\d+",tmp_data)[0]) 
               #print(self.img_quality)        
                self.src=911+self.img_quality        
                f.close()        
                print("读取配置")
    def main():    
        print("创建连接...")    
        cam = webCamConnect();    
        cam.check_config()    
        print("像素为:%d * %d"%(cam.resolution[0],cam.resolution[1]))    
        print("目标ip为%s:%d"%(cam.remoteAddress[0],cam.remoteAddress[1])) 
        cam.connect();      
        cam.getData(cam.interval);  
    if __name__ == "__main__":      
        main();  
    

    相关文章

      网友评论

        本文标题:基于python和opencv的视频传输程序(一)

        本文链接:https://www.haomeiwen.com/subject/znravttx.html