我正在使用 YOLOv7 和 Python 开发实时车牌识别系统。车牌识别分两个阶段完成,使用两个 YOLOv7 模型,每个模型都运行完美。
在这个系统中,我必须从位于停车场不同位置的网络摄像机中抓取帧,然后检查其中是否存在车牌以进行进一步处理。基于此功能,我决定专用一个
Process
来处理每个摄像头,以便对每个网关的监控并行且独立于其他摄像头,保持系统的实时行为。
我使用Docker来部署这个系统,安装方便,可移植。
这是代码:
main.py
# Receiving urls
camera_urls = ['camera_1_url', 'camera_2_url']
for i, camera_url in enumerate(camera_urls):
cameras.append(Process(target=camera_process, args=(i + 1, camera_url)))
for camera in cameras:
camera.start()
for camera in cameras:
camera.join()
camera_process.py
def camera_process(cam_id, url):
cam = Camera(cam_id, url)
plate_detector = PlateDetector(DETECTION_MODEL)
plate_reader = PlateReader(OCR_MODEL)
while True:
if cam.stopped:
cam.attempt_to_connect()
im = cam.get_frame()
if im is None:
continue
sleep(cam.FPS)
detected, plate = plate_detector.detect(im)
if detected:
successful, prediction = plate_reader.predict(plate)
if successful:
send_plate(cam_id, url, prediction, plate) # send detected plate to core software to check for access
相机.py
class Camera:
def __init__(self, id, src):
self.src = src
self.id = id
self.FPS = setting.FPS
self.capture = cv2.VideoCapture(self.src)
self.stopped = True
self.attempt_to_connect()
def update(self):
while self.capture.isOpened():
(self.status, self.frame) = self.capture.read()
if not self.status:
self.capture.release()
break
time.sleep(self.FPS)
self.stopped = True
def get_frame(self):
return self.frame
def attempt_to_connect(self):
while not self.capture.isOpened():
time.sleep(5)
self.capture = cv2.VideoCapture(self.src)
self.capture.set(cv2.CAP_PROP_BUFFERSIZE, 2)
self.thread = Thread(target=self.update, args=())
self.thread.daemon = True
self.thread.start()
self.stopped = False
问题 当我在使用单个 IP 摄像头的 20 核机器上运行我的程序时,系统的性能是可以接受的并且速度很快。但当我添加另一个摄像头时,性能会显着下降。我怀疑两者是否并行运行,尽管我的 77% 的 CPU 正在被使用。
我尝试运行两个单独的 Docker 镜像,每个镜像处理其中一个 url,但结果是相同的。
在寻找解决方案时,我遇到了this方法,该方法不会为每个相机创建单独的进程并循环抓取帧。我不确定这是一个好的解决方案。
现在我不知道如何克服这个问题并实现不同数量的相机的性能相同。
我错过了什么吗? 和GIL有关系吗? 我可以使用其他并行范例吗? 或者Python对于这个功能来说不是一个好的选择,我必须切换到另一种编程语言? (如果有,哪一个?)
如有任何帮助,我们将不胜感激。
我只需要使用
torch.multiprocessing.Process
类而不是使用 multiprocessing.Process
。在目标函数中,我还添加了torch.set_num_threads(4)
。现在我的程序并行运行。