2

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:

  1. 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. enter image description here 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?

  2. 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()

enter image description here

Michael
  • 1,170
  • 2
  • 14
  • 35

1 Answers1

2

I believe following the steps below will solve your first problem to a large extent:

1.Preprocessing:

Image preprocessing is very crucial because a computer does not see an image as we humans perceive. Hence, it is always advised to look for ways to enhance the image rather than working on it directly.

For the given image, the man in a jacket appears to be having the same color as the background. I applied histogram equalization to all the three channels of the image and merged them to get the following:

enter image description here

The man is visible slightly better than before.

2. Color Space:

Your choice of going with HSV color space was right. But why restrict to the three channels together? I obtained the hue channel and got the following:

enter image description here

3. Fine Tuning

Now to the image above, you will have to apply some optimal threshold and then follow it up with a morphological erosion operation to get a better silhouette of the man in the frame.

Note: In order to solve your second problem you can also go with some morphological operations after applying a threshold.

Community
  • 1
  • 1
Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
  • oh, I appriciate so much your answer, this makes a lot of sense, I will check your idea in the soonest time and let you know – Michael Sep 02 '17 at 16:34
  • hey again @Jeru Luke. I tried out your suggestion and as it turned out histogram equalization really improved results, but not enough even this time. Now subtractor able to absorb more regions, however in case with that man, he is still invisible (see edited question). – Michael Sep 05 '17 at 12:22
  • What I did: 1. convert the image to HSV 2. apply CLAHE histogram equaliztion 3. apply background subtractor The reason why I don`t use only hue channel as u proposed is that other people become same gray color as background in such case. So further operation will not have any sense. Am I doing something wrong or missing some details? – Michael Sep 05 '17 at 12:23
  • @Michael I wrote this keeping the man in the picture in mind and not the others. In order to generalize it for other people with different colors of jacket, this won't help. A more robust approach with rule based conditions will be better. In simple words: a condition for each or a group of colors. – Jeru Luke Sep 05 '17 at 12:31
  • ok, I will try to discover something more to improve accuracy of algorithm. Thanks for your suggestion. It was helpful. – Michael Sep 05 '17 at 12:44