【问题标题】:Double imshow in python script with opencv使用opencv在python脚本中进行双重imshow
【发布时间】:2020-12-15 14:24:08
【问题描述】:

我有以下代码:

import numpy as np
import cv2
import pickle
import rtsp
import PIL as Image

face_cascade = cv2.CascadeClassifier('cascades\data\haarcascade_frontalface_alt2.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read("trainner.yml")

labels = {"person_name": 1}
with open("labels.pickle", 'rb') as f:
    og_labels = pickle.load(f)
    labels = {v:k for k,v in og_labels.items()}

url = 'rtsp://user:pass@xxx.xxx.x.xxx:YYYY/stream0/mobotix.mjpeg'
with rtsp.Client(url) as client:
  client.preview()
  while True:
    frame = client.read(raw=True)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)
    for (x,y,w,h) in faces:
      print(x,y,w,h)
      roi_gray = gray[y:y+h, x:x+w]
      roi_color = frame[y:y+h, x:x+w]
        
      #recognize?
      id_, conf = recognizer.predict(roi_gray)
      if conf>=45: # and conf <=85:
        print(id_)
        print(labels[id_])
        font = cv2.FONT_HERSHEY_SIMPLEX
        name = labels[id_]
        color = (0,0,255)
        stroke = 2
        cv2.putText(frame, name, (x,y), font, 1, color, stroke, cv2.LINE_AA)

      #img_item = "my-image.png"
      #cv2.imwrite(img_item, roi_gray)

      color = (0, 0, 255)
      stroke = 2
      end_cord_x = x + w
      end_cord_y = y + h
      cv2.rectangle(frame, (x,y), (end_cord_x, end_cord_y), color, stroke)

    cv2.imshow('IP cam',frame)
   
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

一切正常,我正在运行我的代码,首先它打开“client.preview”的凸轮视图,此时人脸检测不起作用。当我关闭这个时,IPcam 窗口打开并且一切正常。 (RTSP 流仍然会丢失很多帧,但没有直接问题)。

如果我不使用代码“client.preview”,我会因为 src_empty 而从 opencv 收到错误消息。 如果我尝试将代码更改为“client.read()”,则由于 src_empty,opencv 会发生错误。

我应该如何解决这个问题?

【问题讨论】:

    标签: python opencv rtsp face-detection


    【解决方案1】:

    在 rtsp 客户端收到第一帧之前,rtsp 客户端上的读取调用将返回 None。当您调用“client.preview”时,打开窗口所需的时间使 rtsp 客户端有足够的时间在调用第一次读取之前从流中接收第一帧。超出此范围的所有读取调用将始终返回一个框架,这就是为什么当它包含在代码中时一切正常。您的问题的解决方案是检查 rtsp 客户端的读取功能的结果,以确保您在处理之前已收到帧。

    import numpy as np
    import cv2
    import pickle
    import rtsp
    import PIL as Image
    import time
    
    face_cascade = cv2.CascadeClassifier('cascades\data\haarcascade_frontalface_alt2.xml')
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    recognizer.read("trainner.yml")
    
    labels = {"person_name": 1}
    with open("labels.pickle", 'rb') as f:
        og_labels = pickle.load(f)
        labels = {v:k for k,v in og_labels.items()}
    
    url = 'rtsp://user:pass@xxx.xxx.x.xxx:YYYY/stream0/mobotix.mjpeg'
    with rtsp.Client(url) as client:
      client.preview()
      while True:
        frame = client.read(raw=True)
        if frame is not None:
            time.sleep(.10)
        else:
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)
            for (x,y,w,h) in faces:
            print(x,y,w,h)
            roi_gray = gray[y:y+h, x:x+w]
            roi_color = frame[y:y+h, x:x+w]
                
            #recognize?
            id_, conf = recognizer.predict(roi_gray)
            if conf>=45: # and conf <=85:
                print(id_)
                print(labels[id_])
                font = cv2.FONT_HERSHEY_SIMPLEX
                name = labels[id_]
                color = (0,0,255)
                stroke = 2
                cv2.putText(frame, name, (x,y), font, 1, color, stroke, cv2.LINE_AA)
    
            #img_item = "my-image.png"
            #cv2.imwrite(img_item, roi_gray)
    
            color = (0, 0, 255)
            stroke = 2
            end_cord_x = x + w
            end_cord_y = y + h
            cv2.rectangle(frame, (x,y), (end_cord_x, end_cord_y), color, stroke)
    
            cv2.imshow('IP cam',frame)
        
            if cv2.waitKey(20) & 0xFF == ord('q'):
                break
    
    cv2.destroyAllWindows()
    

    【讨论】:

    • if not frame: ValueError: 具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()
    • 我的错。当您将帧作为原始数组而不是图像读取时,您需要更明确地使用相等性测试。所以“如果不是框架:”需要是“如果框架不是无:”。我已经更新了答案。
    • 好的,所以如果我在其中使用带有 client.preview() 的相同代码,它就会从框架中陷入循环。当我在调试期间查看帧变量时。它是一个数组 [0:720],在里面我又得到了前 6 个数组,但其他的都是空的,直到总 len():300
    • 如果我删除 client.preview()。它从 opencv 得到一个错误,即 scr.empty() cv2.error: OpenCV(4.3.0) python\opencv\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src。函数'cv::cvtColor'中的empty()。在调试帧变量中数组的相同外观时
    【解决方案2】:

    好的,我知道 RTSP 协议首先发送空帧并建立缓冲区。

    with rtsp.Client(url) as client:
      while True:
        frame = client.read(raw=True)
        if not frame:
            time.sleep(.30)
        else:
          gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
          faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)
          for (x,y,w,h) in faces:
            
          cv2.imshow('IP cam',frame)
          
          if cv2.waitKey(20) & 0xFF == ord('q'):
            break
    
    cv2.destroyAllWindows()
    

    由于双重功能,我删除了以下行:client.preview()。 代码正在启动,在一段时间后我收到以下错误:

    if not frame:
    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
    

    【讨论】:

      猜你喜欢
      • 2018-03-20
      • 1970-01-01
      • 1970-01-01
      • 2017-06-08
      • 1970-01-01
      • 1970-01-01
      • 2012-12-23
      • 2017-09-26
      • 2015-02-23
      相关资源
      最近更新 更多