简体   繁体   English

OpenCV - 使用多个网络摄像机进行动作捕捉

[英]OpenCV - Motion capture with multiple ip cameras

I have three IP cameras around my house and I want to capture an image when a motion is detected.我的房子周围有三个 IP 摄像头,我想在检测到运动时捕捉图像。 I want to run the motion capture algorithm in the same time for all 3 cameras.我想同时为所有 3 个摄像机运行运动捕捉算法。

I manage to do the job for one camera - Open the stream + motion detection algorithm + store image in case of detection :我设法为一台相机完成这项工作 - 打开流 + 运动检测算法 + 存储图像以备检测:

import cv2


cap3 = cv2.VideoCapture('http://X.X.X.X:XXXX/stream.mjpg')


ret3, frame31 = cap3.read()
ret3, frame32 = cap3.read()

while (True):
    diff3 = cv2.absdiff(frame31, frame32)
    gray3 = cv2.cvtColor(diff3, cv2.COLOR_BGR2GRAY)
    blur3 = cv2.GaussianBlur(gray3, (5, 5), 0)
    _, tresh3 = cv2.threshold(blur3, 30, 255, cv2.THRESH_BINARY)
    dilated3 = cv2.dilate(tresh3, None, iterations=3)
    contours3, _ = cv2.findContours(dilated3, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    for contour in contours3:
        (x, y, w, h) = cv2.boundingRect(contour)
        if cv2.contourArea(contour) < 800:
            continue
        cv2.rectangle(frame31, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(frame31, "Status: {}".format('Movement'), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
        t = time.localtime()
        filename = "RASP" + str(t[0]) + str(t[1]) + str(t[2]) + "_" + str(t[3]) + str(t[4]) + str(t[5]) + ".jpg"
        cv2.imwrite(filename, frame31)

    frame31 = frame32
    ret3, frame32 = cap3.read()

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap3.release()
cv2.destroyAllWindows()

The problem I have is when I try to do the same job in parallel for the three cameras.我遇到的问题是当我尝试为三台摄像机并行执行相同的工作时。 What I do is duplicating the same process in the while loop for the three cameras and when I do so, it starts running for a few seconds and then I get this error :我所做的是在三个摄像头的 while 循环中复制相同的过程,当我这样做时,它开始运行几秒钟,然后出现此错误:

Traceback (most recent call last):
  File "C:/Users/Guillaume/PycharmProjects/IPCAM/IPCAM2.py", line 54, in <module>
    gray2 = cv2.cvtColor(diff2, cv2.COLOR_BGR2GRAY)
cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'

The code I run in below :我在下面运行的代码:

import cv2
import numpy as np
from datetime import datetime
import time

cap2 = cv2.VideoCapture('rtsp://')  # IPCAM2
cap = cv2.VideoCapture('rtsp://')  # IPCAM1
cap3 = cv2.VideoCapture('http://')  # RASP

def rescale_frame(frame, percent=75):
    width = int(frame.shape[1] * percent / 100)
    height = int(frame.shape[0] * percent / 100)
    dim = (width, height)
    return cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)

while (True):
    ret1, frame11 = cap.read()
    ret1, frame12 = cap.read()

    ret2, frame21 = cap2.read()
    ret2, frame22 = cap2.read()

    ret3, frame31 = cap3.read()
    ret3, frame32 = cap3.read()

    diff1 = cv2.absdiff(frame11, frame12)
    gray1 = cv2.cvtColor(diff1, cv2.COLOR_BGR2GRAY)
    blur1 = cv2.GaussianBlur(gray1, (5, 5), 0)
    _, tresh1 = cv2.threshold(blur1, 40, 255, cv2.THRESH_BINARY)
    dilated1 = cv2.dilate(tresh1, None, iterations=3)
    contours1, _ = cv2.findContours(dilated1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    for contour in contours1:
        (x, y, w, h) = cv2.boundingRect(contour)
        if cv2.contourArea(contour) < 1000:
            continue
        cv2.rectangle(frame11, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(frame11, "Status: {}".format('Movement'), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
        t = time.localtime()
        filename = str(t[0]) + str(t[1]) + str(t[2]) + "_" + str(t[3]) + str(t[4]) + str(t[5]) + ".jpg"
        cv2.imwrite(filename, frame11)

    # cv2.line(frame, (0, 300), (200, 200), (0, 255, 0), 5)
    resizedframe11 = rescale_frame(frame11, percent=75)

    cv2.imshow('frame', resizedframe11)

    frame11 = frame12
    ret1, frame12 = cap.read()

    diff2 = cv2.absdiff(frame21, frame22)
    gray2 = cv2.cvtColor(diff2, cv2.COLOR_BGR2GRAY)
    blur2 = cv2.GaussianBlur(gray2, (5, 5), 0)
    _, tresh2 = cv2.threshold(blur2, 40, 255, cv2.THRESH_BINARY)
    dilated2 = cv2.dilate(tresh2, None, iterations=3)
    contours2, _ = cv2.findContours(dilated2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    for contour in contours2:
        (x, y, w, h) = cv2.boundingRect(contour)
        if cv2.contourArea(contour) < 1000:
            continue
        cv2.rectangle(frame21, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(frame21, "Status: {}".format('Movement'), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
        t = time.localtime()
        filename = str(t[0]) + str(t[1]) + str(t[2]) + "_" + str(t[3]) + str(t[4]) + str(t[5]) + ".jpg"
        cv2.imwrite(filename, frame21)
    resizedframe21 = rescale_frame(frame21, percent=75)

    cv2.imshow('frame2', resizedframe21)

    frame21 = frame22
    ret2, frame22 = cap2.read()

    diff3 = cv2.absdiff(frame31, frame32)
    gray3 = cv2.cvtColor(diff3, cv2.COLOR_BGR2GRAY)
    blur3 = cv2.GaussianBlur(gray3, (5, 5), 0)
    _, tresh3 = cv2.threshold(blur3, 40, 255, cv2.THRESH_BINARY)
    dilated3 = cv2.dilate(tresh3, None, iterations=3)
    contours3, _ = cv2.findContours(dilated3, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    for contour in contours3:
        (x, y, w, h) = cv2.boundingRect(contour)
        if cv2.contourArea(contour) < 800:
            continue
        cv2.rectangle(frame31, (x, y), (x + w, y + h), (0, 255, 0), 2)
        cv2.putText(frame31, "Status: {}".format('Movement'), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
        t = time.localtime()
        filename = "RASP" + str(t[0]) + str(t[1]) + str(t[2]) + "_" + str(t[3]) + str(t[4]) + str(t[5]) + ".jpg"
        cv2.imwrite(filename, frame31)
    resizedframe31 = rescale_frame(frame31, percent=75)

    cv2.imshow('frame3', resizedframe31)

    frame31 = frame32
    ret3, frame32 = cap3.read()

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

Thanks Kartik and thekangaroo for your answers.感谢 Kartik 和 thekangaroo 的回答。 I managed to run my three cameras at the same time using threads.我设法使用线程同时运行我的三个相机。 I am just opening them and showing a resized stream.我只是打开它们并显示调整大小的流。 There is another issue as one cameras, and then a second, stops after a random time between 5 to 20 seconds.还有一个问题,一个摄像头,然后一个摄像头,在 5 到 20 秒之间的随机时间后停止。 The stream stops and then the windows closes without any messages.流停止,然后窗口关闭,没有任何消息。 It seems to me that it is due to lagging getting the image from the cameras... any ideas to avoid that with openCV ?在我看来,这是由于从相机获取图像滞后......有什么想法可以避免使用 openCV 吗?

Thanks again for your helpful answers.再次感谢您的有用回答。

Below is the code I use :下面是我使用的代码:

import cv2
import threading
import time

class camThread(threading.Thread):
    def __init__(self, previewName, camID):
        threading.Thread.__init__(self)
        self.previewName = previewName
        self.camID = camID
    def run(self):
        print("Starting " + self.previewName)
        camPreview(self.previewName, self.camID)

def rescale_frame(frame, percent=75):
    width = int(frame.shape[1] * percent / 100)
    height = int(frame.shape[0] * percent / 100)
    dim = (width, height)
    return cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)

def camPreview(previewName, camID):
    cv2.namedWindow(previewName)
    cam = cv2.VideoCapture(camID)
    if cam.isOpened():  # try to get the first frame
        rval, frame = cam.read()
    else:
        time.sleep(10)
        rval, frame = cam.read()

    percent = 50
    width = int(frame.shape[1] * percent / 100)
    height = int(frame.shape[0] * percent / 100)
    dim = (width, height)

    while rval:
        # cv2.imshow(previewName, frame)
        cv2.imshow(previewName, cv2.resize(frame, dim, interpolation=cv2.INTER_AREA))
        time.sleep(0.5)
        rval, frame = cam.read()
        key = cv2.waitKey(20)
        print(previewName + str(cam.isOpened()))

# Create two threads as follows
thread1 = camThread("CLIO", 'rtsp://xxxx')
thread2 = camThread("JARDIN", 'rtsp://xxxx')
thread3 = camThread("RASPCAM", 'http://xxxx')

thread1.start()
thread2.start()
thread3.start()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM