我家周围有三个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()

最佳答案

感谢Kartik和thekangaroo的回答。
我设法使用线程同时运行三个摄像机。我只是打开它们并显示调整大小的流。
还有一个问题,一台摄像机,然后在5到20秒之间的随机时间后停止一秒钟。流停止,然后窗口关闭,没有任何消息。
在我看来,这是由于无法从摄像机获取图像而导致的。。。
再次感谢您的帮助。
以下是我使用的代码:

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

关于python - OpenCV-使用多个IP摄像机进行运动捕捉,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63756205/

10-11 11:30