Opencv3 - 如何根据轮廓和矩形为我计数的人提供 ID?
Opencv3 - How to give ID to the people I count based on contours and rectrangles?
我想为我在其上绘制矩形的轮廓区域提供 ID。现在我的代码跟踪屏幕上的移动对象并在它们周围放置一个矩形。我想给每个矩形一个 ID。我知道如何计算屏幕上有多少个矩形,但我不知道如何为矩形提供一个确切的 ID,当另一个矩形加入屏幕时该 ID 不会改变。
我用来绘制矩形的代码:
video_path = 'C:\Users\MONSTER\Desktop\video.avi'
cv2.ocl.setUseOpenCL(False)
version = cv2.__version__.split('.')[0]
print(version)
#read video file
cap = cv2.VideoCapture(video_path)
#check opencv version
if version == '2' :
fgbg = cv2.BackgroundSubtractorMOG2()
if version == '3':
fgbg = cv2.createBackgroundSubtractorMOG2()
while (cap.isOpened):
#if ret is true than no error with cap.isOpened
ret, frame = cap.read()
if ret==True:
#apply background substraction
fgmask = fgbg.apply(frame)
ret1,th1 = cv2.threshold(fgmask,150,200,cv2.THRESH_BINARY)
#check opencv version
if version == '2' :
(contours, hierarchy) = cv2.findContours(th1.copy(),
cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
if version == '3' :
(im2, contours, hierarchy) = cv2.findContours(th1.copy(),
cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
if cv2.contourArea(c) < 200:
continue
#get bounding box from countour
(x, y, w, h) = cv2.boundingRect(c)
#draw bounding box
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow('foreground and background',th1)
cv2.imshow('rgb',frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
我将上面的代码更改为下面的代码以将文本放在矩形上,但是当另一个矩形连接时文本会发生变化。
i = 1
for c in contours:
if cv2.contourArea(c) < 200:
continue
#get bounding box from countour
(x, y, w, h) = cv2.boundingRect(c)
#draw bounding box
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
i = i + 1
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame,str(i),(x,y), font, 2,(255,255,255),2,cv2.LINE_AA)
你有没有想过给矩形准确的 ID。
您的代码不进行跟踪。仅来自背景的检测。要使您的代码本机进行跟踪,恐怕不是那么简单。只有当你有一个完美连接的对象并且只有 1 个对象时,跟踪才会发生。它通常很少发生,因为故障检测一直在发生。这样就创建了多个RECT。
当你进入场景时,ID会根据不同的帧保持变化,有如下图这样的多次检测。我以前试过。每次边界矩形都会因对象而异。特别是当你使用像 bgfg 这样的简单方法时,这种丢失轨迹或丢失 ID 几乎每一帧都会发生。
正确的方法是使用真实的跟踪算法不断更新对象。例如
https://www.youtube.com/watch?v=qvcyK4ZMKbM
TLD tracker的输入来自
得到的Rect
(x, y, w, h) = cv2.boundingRect(c)
源代码在github。随意测试它
https://github.com/gnebehay/TLD
跟着安装起来,集成到你当前的检测路由中。
https://github.com/zk00006/OpenTLD/wiki/Installation
您需要跟踪多个对象。
- 你需要检查它们的交叉点,当它们碰撞时停止跟踪。
https://www.pyimagesearch.com/2018/08/06/tracking-multiple-objects-with-opencv/
我想为我在其上绘制矩形的轮廓区域提供 ID。现在我的代码跟踪屏幕上的移动对象并在它们周围放置一个矩形。我想给每个矩形一个 ID。我知道如何计算屏幕上有多少个矩形,但我不知道如何为矩形提供一个确切的 ID,当另一个矩形加入屏幕时该 ID 不会改变。
我用来绘制矩形的代码:
video_path = 'C:\Users\MONSTER\Desktop\video.avi'
cv2.ocl.setUseOpenCL(False)
version = cv2.__version__.split('.')[0]
print(version)
#read video file
cap = cv2.VideoCapture(video_path)
#check opencv version
if version == '2' :
fgbg = cv2.BackgroundSubtractorMOG2()
if version == '3':
fgbg = cv2.createBackgroundSubtractorMOG2()
while (cap.isOpened):
#if ret is true than no error with cap.isOpened
ret, frame = cap.read()
if ret==True:
#apply background substraction
fgmask = fgbg.apply(frame)
ret1,th1 = cv2.threshold(fgmask,150,200,cv2.THRESH_BINARY)
#check opencv version
if version == '2' :
(contours, hierarchy) = cv2.findContours(th1.copy(),
cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
if version == '3' :
(im2, contours, hierarchy) = cv2.findContours(th1.copy(),
cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
if cv2.contourArea(c) < 200:
continue
#get bounding box from countour
(x, y, w, h) = cv2.boundingRect(c)
#draw bounding box
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow('foreground and background',th1)
cv2.imshow('rgb',frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
我将上面的代码更改为下面的代码以将文本放在矩形上,但是当另一个矩形连接时文本会发生变化。
i = 1
for c in contours:
if cv2.contourArea(c) < 200:
continue
#get bounding box from countour
(x, y, w, h) = cv2.boundingRect(c)
#draw bounding box
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
i = i + 1
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame,str(i),(x,y), font, 2,(255,255,255),2,cv2.LINE_AA)
你有没有想过给矩形准确的 ID。
您的代码不进行跟踪。仅来自背景的检测。要使您的代码本机进行跟踪,恐怕不是那么简单。只有当你有一个完美连接的对象并且只有 1 个对象时,跟踪才会发生。它通常很少发生,因为故障检测一直在发生。这样就创建了多个RECT。
当你进入场景时,ID会根据不同的帧保持变化,有如下图这样的多次检测。我以前试过。每次边界矩形都会因对象而异。特别是当你使用像 bgfg 这样的简单方法时,这种丢失轨迹或丢失 ID 几乎每一帧都会发生。
正确的方法是使用真实的跟踪算法不断更新对象。例如
https://www.youtube.com/watch?v=qvcyK4ZMKbM
TLD tracker的输入来自
得到的Rect(x, y, w, h) = cv2.boundingRect(c)
源代码在github。随意测试它
https://github.com/gnebehay/TLD
跟着安装起来,集成到你当前的检测路由中。
https://github.com/zk00006/OpenTLD/wiki/Installation
您需要跟踪多个对象。
- 你需要检查它们的交叉点,当它们碰撞时停止跟踪。
https://www.pyimagesearch.com/2018/08/06/tracking-multiple-objects-with-opencv/