I have kind of challenging task and spent a lot of time on it but without satisfactory results.
The sense is to perform a background subtraction for future people counting. I am doing this with Python 3 and OpenCV 3.3. I have applied cv2.createBackgroundSubtractorMOG2
but faced two main difficulties:
As background is almost dark, and some people that walk on video are wearing dark staff, subtractor sometimes is unable to detect them properly, it simply skips them (take a look at the image below). Converting image from BGR to HSV made little changes but i expect even better result. As you can see, a man in grey clothes is not detected well. How is it possible to improve this? If there is more efficient methods, please provide this information, I appreciate and welcome any help! Maybe there is sense to use stereo camera and try to process objects using images depth?
Another question that worries me, is what if a couple of people will be close to each other in case of hard traffic? The region will be simply merged and counted as simple. What can be done in such case?
Thanks in advance for any information!
UPD:
I performed histogram equalization on every channel of the image with HSV colorspace, but even now I am not able to absorb some people with color close to background color.
Here is code updated:
import cv2
import numpy as np
import imutils
cap = cv2.VideoCapture('test4.mp4')
clahe = cv2.createCLAHE(2.0, (8,8))
history = 50
fgbg = cv2.createBackgroundSubtractorMOG2(history=history, detectShadows=True)
while cap.isOpened():
frame = cap.read()[1]
width, height = frame.shape[:2]
frame = imutils.resize(frame, width=min(500, width))
origin = frame.copy()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
for channel in range(3):
hsv[:,:,channel] = clahe.apply(hsv[:,:,channel])
fgmask = fgbg.apply(hsv, learningRate=1 / history)
blur = cv2.medianBlur(fgmask, 5)
cv2.imshow('mask', fgmask)
cv2.imshow('hcv', hsv)
cv2.imshow('origin', origin)
k = cv2.waitKey(30) & 0xff
if k == 27 or k == ord('q'):
break
cap.release()
cv2.destroyAllWindows()