【问题标题】:OpenCV - Motion capture with multiple ip camerasOpenCV - 使用多个 ip 摄像机进行运动捕捉
【发布时间】:2020-12-24 14:44:13
【问题描述】:

我的房子周围有三个 IP 摄像头,我想在检测到运动时捕获图像。我想同时为所有 3 个摄像头运行动作捕捉算法。

我设法为一台摄像机完成这项工作 - 打开流 + 运动检测算法 + 存储图像以防检测:

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()

我遇到的问题是当我尝试为三个摄像头并行执行相同的工作时。 我所做的是在三个摄像头的 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'

我在下面运行的代码:

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()

【问题讨论】:

  • 为什么不创建线程并使用单独的线程处理每个相机。这将节省时间
  • 感谢 Karthik。我会看看它。我不知道这个库。不要犹豫,分享有关如何使用多个线程处理此问题的更多详细信息。

标签: python opencv camera ip


【解决方案1】:

感谢 Kartik 和 thekangaroo 的回答。 我设法使用线程同时运行我的三个相机。我只是打开它们并显示调整大小的流。 还有一个问题是一个摄像机,然后第二个摄像机在 5 到 20 秒之间的随机时间后停止。流停止,然后窗口关闭,没有任何消息。 在我看来,这是由于从相机中获取图像的滞后......有什么想法可以避免使用 openCV 吗?

再次感谢您的有用回答。

下面是我使用的代码:

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()

【讨论】:

    猜你喜欢
    • 2017-11-10
    • 2020-02-23
    • 2015-04-25
    • 2013-03-13
    • 2018-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多