Python 提高Matplotlib图形和OpenCV视频处理性能
在以下代码数组中使用Opencv库完成对象检测过程之后,我将输出信息作为matplotlib的参数。但是视频处理的速度很慢。如果我只进行对象检测,而不运行图形部分;实时目标检测做得很好。但是当你同时做这两件事时,物体检测过程会变慢。你对加快这个过程有什么建议吗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,
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完成) 谢谢,我会尽力的,我完全同意你最后的意见。因为当我只编译目标检测部分时,视频帧速率非常好。也许这将有助于分离过程部分。谢谢你的建议:)