如何解决使用 OpenCV 的占用计数器
我使用 OpenCV 创建了一个占用计数器。当我导入视频时,代码运行良好,并在他们通过时计算人数。但是当我将数据输入更改为网络摄像头时,计数无法正常工作。有时它会计算一个人,有时它不会(尽管它可以正确跟踪它们),有时它会将一个人计算为多个。我假设该算法不够快,无法处理实时数据输入,并且视频输入帧比实时视频输入少。有关如何解决此问题的任何想法?
请在下面找到最少的可重现代码。
cap = cv.VideoCapture("C:\\Users\\USER_NAME\\Downloads\\example_01.mp4")
# Print the capture properties to console
for i in range(19):
print( i,cap.get(i))
h = 480
w = 640
frameArea = h*w
areaTH = frameArea/250
print( 'Area Threshold',areaTH)
# Entry / exit lines
line_up = int(1*(h/5))
line_down = int(2*(h/5))
up_limit = int(0.5*(h/5))
down_limit = int(2.5*(h/5))
#Background Subtractor
fgbg = cv.createBackgroundSubtractormog2(detectShadows = True)
while(cap.isOpened()):
ret,frame = cap.read()
try:
ret,imBin= cv.threshold(fgmask,200,255,cv.THRESH_BINARY)
ret,imBin2 = cv.threshold(fgmask2,cv.THRESH_BINARY)
#opening (erode-> dilate) to remove noise.
mask = cv.morphologyEx(imBin,cv.MORPH_OPEN,kernelOp)
mask2 = cv.morphologyEx(imBin2,kernelOp)
#Closing (dilate -> erode) to join white regions.
mask = cv.morphologyEx(mask,cv.MORPH_CLOSE,kernelCl)
mask2 = cv.morphologyEx(mask2,kernelCl)
except:
print('EOF')enter code here
print( 'UP:',cnt_up)
print ('DOWN:',cnt_down)
break
contours0,hierarchy =
cv.findContours(mask2,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
for cnt in contours0:
area = cv.contourArea(cnt)
if area > areaTH:
#################
# TRACKING #
#################
M = cv.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
x,y,w,h = cv.boundingRect(cnt)
new = True
if cy in range(up_limit,down_limit):
for i in persons:
if abs(x-i.getX()) <= w and abs(y-i.getY()) <= h:
# the object is close to one that has already been detected before
new = False
i.updateCoords(cx,cy) # update coordinates in the object and resets age
if i.going_UP(line_down,line_up) == True:
cnt_up += 1;
print( "ID:",i.getId(),'crossed going up at',time.strftime("%c"))
log.write("ID: "+str(i.getId())+' crossed going up at ' + time.strftime("%c") + '\n')
elif i.going_DOWN(line_down,line_up) == True:
cnt_down += 1;
print( "ID:",'crossed going down at',time.strftime("%c"))
log.write("ID: " + str(i.getId()) + ' crossed going down at ' + time.strftime("%c") + '\n')
break
if i.getState() == '1':
if i.getDir() == 'down' and i.getY() > down_limit:
i.setDone()
elif i.getDir() == 'up' and i.getY() < up_limit:
i.setDone()
if i.timedOut():
#sacar i de la lista persons
index = persons.index(i)
persons.pop(index)
del i #release the memory of i
if new == True:
p = Person1.MyPerson(pid,cx,cy,max_p_age)
persons.append(p)
pid += 1
cv.circle(frame,(cx,cy),5,(0,255),-1)
img = cv.rectangle(frame,(x,y),(x+w,y+h),0),2)
感谢和问候
苏拉布
解决方法
我无法运行您的代码,但如果是实时视频源的问题,我为您提供了以下解决方案:
# Define the thread that will continuously pull frames from the camera
class CameraBufferCleanerThread(threading.Thread):
def __init__(self,camera,name='camera-buffer-cleaner-thread'):
self.camera = camera
self.last_frame = None
self.cancel = False
super(CameraBufferCleanerThread,self).__init__(name=name)
self.start()
def run(self):
while not self.cancel:
ret,self.last_frame = self.camera.read()
这将创建一个线程并始终拉取最新的帧并将其存储在 last_frame
属性中。
要使用它,只需在上述类中填充视频捕获并获取循环中的最新帧。
vcap = cv2.VideoCapture("rtsp://user:pass@10.0.0.5:554/s0")
# Start the cleaning thread
cam_cleaner = CameraBufferCleanerThread(vcap)
while(1):
if cam_cleaner.last_frame is None:
continue
image = cam_cleaner.last_frame.copy()
我遇到了类似的问题,这为我解决了。看来这也能帮你解决。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。