Python 提高Matplotlib图形和OpenCV视频处理性能

Python 提高Matplotlib图形和OpenCV视频处理性能,python,performance,opencv,matplotlib,video-processing,Python,Performance,Opencv,Matplotlib,Video Processing,在以下代码数组中使用Opencv库完成对象检测过程之后,我将输出信息作为matplotlib的参数。但是视频处理的速度很慢。如果我只进行对象检测,而不运行图形部分;实时目标检测做得很好。但是当你同时做这两件事时,物体检测过程会变慢。你对加快这个过程有什么建议吗 pixel_number_row = [] while True: ret, frame = cap.read() if ret == True : hsv = cv2.cvtColor(frame,

在以下代码数组中使用Opencv库完成对象检测过程之后,我将输出信息作为matplotlib的参数。但是视频处理的速度很慢。如果我只进行对象检测,而不运行图形部分;实时目标检测做得很好。但是当你同时做这两件事时,物体检测过程会变慢。你对加快这个过程有什么建议吗

pixel_number_row = []
while True:
   ret, frame = cap.read()

   if ret == True :     
      hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
      y , x = hsv.shape[:2] #x = 320 , y = 240

      # Define 'brown' range in HSV colorspace
      lower = np.array([10, 100, 20])
      upper = np.array([20, 255, 200])

      # Threshold the HSV image to get only brown color
      mask1 = cv2.inRange(hsv, lower, upper)
      kernel = np.ones((5,5),np.uint8)
      thresh = cv2.dilate(mask1,kernel,iterations = 2)

      # find contours in thresholded image, then grab the largest
      # one
      cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
      cnts = imutils.grab_contours(cnts)
      c = max(cnts, key=cv2.contourArea)

      # determine the most extreme points along the contour
      extLeft  = tuple(c[c[:, :, 0].argmin()][0])
      extRight = tuple(c[c[:, :, 0].argmax()][0])
      extTop   = tuple(c[c[:, :, 1].argmin()][0])
      extBot   = tuple(c[c[:, :, 1].argmax()][0])

      cv2.drawContours(thresh, [c], -1, (0, 255, 255), 2)
      cv2.circle(thresh, extLeft , 8, (0, 0, 255)  , -1)
      cv2.circle(thresh, extRight, 8, (0, 255, 0)  , -1)
      cv2.circle(thresh, extTop  , 8, (255, 0, 0)  , -1)
      cv2.circle(thresh, extBot  , 8, (255, 255, 0), -1)

      x_center = (extLeft[0] + extRight[0] + extTop[0] + extBot[0])/4
      y_center = (extLeft[1] + extRight[1] + extTop[1] + extBot[1])/4

      cv2.circle(frame,(x_center, y_center), 3, (0,255,0), -1)

      cv2.line(frame,(extLeft[0] ,0),(extLeft[0],y) ,(0,255,0),2)             # y axis - binary 
      cv2.line(frame,(extRight[0],0),(extRight[0],y),(0,255,0),2)                 # y axis - binary 
      cv2.line(frame,(0,extTop[1])  ,(x,extTop[1])  ,(0,255,0),2)                 # x axis - binary 
      cv2.line(frame,(0,extBot[1])  ,(x,extBot[1])  ,(0,255,0),2)                 # x axis - binary 

      pixel_number_row.append(x_center)


      plt.plot(pixel_number_row - pixel_number_row[0]) # plotting by columns
      plt.xlabel('frame number')
      plt.ylabel('x axis moving')
      # fig.canvas.draw()
      plt.pause(0.001)

      if (cnt % 60 == 0):
          pixel_number_row = []
          plt.clf()
         cnt += 1

      # show the output image
      # cv2.imshow("mask" , thresh)
      cv2.imshow("Image", frame)
  k = cv2.waitKey(1)
  if k == 27:
      break


print(end - start)
plt.show()
cv2.destroyAllWindows()

一个潜在的原因可能是读取帧时的I/O延迟。由于
cv2.VideoCapture().read()
是一种阻塞操作,因此主程序将暂停,直到从相机设备读取并返回一帧。提高性能的一种方法是生成另一个线程来并行处理抓取帧,而不是依赖单个线程按顺序抓取帧。我们可以通过创建一个新线程来提高性能,该线程只轮询新帧,而主线程处理/绘制最新帧

您当前的方法(顺序):

线程1:抓取帧
->
处理帧
->
绘图

def process_frames():
    while True:
        # Grab most recent frame
        # Process/plot frame
        ...
提议的方法(并行):

线程1:抓斗框架

from threading import Thread
import time

def get_frames():
    while True:
        ret, frame = cap.read()
        time.sleep(.01)

thread_frames = Thread(target=self.get_frames, args=())
thread_frames.daemon = True
thread_frames.start()
线程2:进程帧
->
绘图

def process_frames():
    while True:
        # Grab most recent frame
        # Process/plot frame
        ...
通过使用单独的线程,您的程序将是并行的,因为始终有一个帧准备好进行处理,而不必等待一个帧读入,然后才能完成处理


注意:此方法将在减少I/O延迟的基础上提高性能。这并不是FPS的真正增加,因为它大大减少了延迟(帧始终可用于处理;我们不需要轮询相机设备并等待I/O完成)

谢谢,我会尽力的,我完全同意你最后的意见。因为当我只编译目标检测部分时,视频帧速率非常好。也许这将有助于分离过程部分。谢谢你的建议:)