使用nodejs和python构建一个远程监控系统1.视频采集模块
使用nodejs和python构建一个远程监控系统3.web模块的编写
视屏采集模块完成之后,开始编写视屏分发程序和主控程序
1.分发器(目前采用UDP协议,以后可以扩展一个支持TCP协议的分发器支持高清视屏传输)
#encoding=utf-8
import socket
import cv2
import numpy
from io import BytesIO
from utils import IOUtil,logger
from PIL import Image
from settings import *
import time
'''
传递者模块,用于分发需要散布的信息
'''
class Dispatcher(object):
#信息分发器,用于将信息分发到指定的ip和端口上
def __init__(self):
#初始化udp socket
self._sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
self.fileName = 0
logger.info("分发器初始化完毕")
def dispenseImage(self,frame,address):
#分发图片到指定的地址
if frame is None:
return
try:
#将brg图像转化为rgb图像,工具类中有封装
self._sock.sendto(IOUtil.array_to_bytes(frame[...,::-1]),address)
except Exception as e:
logger.error("分发器错误:"+str(e))
def dispenseCommand(self,command,address):
if command is None:
return
try:
self._sock.sendto(bytes(command),address)
except Exception as e:
raise Exception(e)
def close(self):
self._sock.close()
2.主控程序编写,python的多线程模块无法优化CPU密集型任务,但在后期会用多进程对程序进行优化,所以目前使用类似的多线程模式
#encoding=utf-8
import cv2
from managers import CameraManager
from transmitters import Dispatcher
from threading import Thread
from settings import *
import time
import copy
import multiprocessing
from utils import IOUtil,logger
'''
主控程序
'''
class Camera(object):
#主控程序
def __init__(self,captureManager = None,dispatcher = None,isShow=True):
'''
:param captureManager: 视屏采集器
:param dispatcher:信息分发器
'''
logger.info("主控程序初始化...")
self.captureManager = captureManager if captureManager is not None else CameraManager(cv2.VideoCapture(0))
self.dispatcher = dispatcher if dispatcher is not None else Dispatcher()
#是否开启图像分发
self.isDispense = True
#是否在本地显示
self.isShow = isShow
#是否开启预警
self.isWarning = True
#item为预警器处理后的图像以及坐标信息
#原始图像
self.frame = None
logger.info("主控程序初始化完毕...")
def _dispatch(self):
#信息分发线程
logger.info("是否开启图片分发:"+str(self.isDispense))
while self.isDispense:
try:
self.dispatcher.dispenseImage(self.frame,(IMAGE_IP,IMAGE_PORT))
except EOFError as e:
print(e)
def run(self):
logger.info("\n################################################################")
self.startDispatch()
self.captureManager.start()
time.sleep(1)
while self.captureManager.isWorking():
self.frame = self.captureManager.getFrame()
if self.frame is None:
continue
if self.isShow and self.frame is not None:
cv2.imshow("show",self.frame)
keycode = cv2.waitKey(1)
self.onKeypress(keycode)
def startDispatch(self):
#开启分发
logger.info("开启分发")
Thread(target=self._dispatch,args=()).start()
def onKeypress(self,keycode):
#按钮回调函数
if keycode == 32:
#空格键截图
self.captureManager.writeImage()
elif keycode == 9:
#tab键开启录像
if not self.captureManager.isWritingVideo():
self.captureManager.startWritingVideo()
else:
self.captureManager.stopWritingVideo()
elif keycode == 27:
#esc键结束应用
self.isDispense = False
self.captureManager.stop()
self.dispatcher.close()
self.isWarning= False
if __name__=="__main__":
Camera().run()
视屏采集模块结束,至此python模块完成