5

Im using the following code to count the number of people in realtime webcam from morning till night

people_list = []

while True:
    _, frame = video_capture.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(gray, 1.3, 5)

    detections = faceCascade.detectMultiScale(gray, 1.15, 5)

    for i in range(len(detections)):
        face_i = detections[i]
        x, y, w, h = face_i

        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 222, 0), 1)
        font = cv2.FONT_HERSHEY_SIMPLEX
        people_list.insert(len(people_list)+1,i)

        cv2.putText(frame, "id: "+str ( people_list[i]), (x, y), font, 2, (255, 255, 255), 2, cv2.LINE_AA)

    # Display the resulting frame
    cv2.imshow('Video', frame)

everytime when a new face is detected, the people_list count increases. However, the people_list count is being increased for every frame instead of every new faces. How can I be able to sort this out?

Gambit1614
  • 8,547
  • 1
  • 25
  • 51
  • 1
    Do the users contain any unique identifiers? If so, create a set of unique identifiers instead of a list. Edit: It might also be worth checking if the identifier is already in the set and skip it, otherwise your software will be constantly inserting data into the set for every iteration – Alan Kavanagh Aug 30 '17 at 09:25
  • no... they dont have one... i have to assign it based on the number of people visited from from morning –  Aug 30 '17 at 09:30
  • 2
    Well then it sounds like you need to re-assess your way of storing users. How will you know if a specific user leaves? – Alan Kavanagh Aug 30 '17 at 09:31
  • if he goes out of the frame, he is gone... –  Aug 30 '17 at 09:33
  • 1
    Another way to do it would be to keep a count of the current viewers and only increment if the current viewers rises higher than the last total amount of current users - and if it decreases then decrease without changing the total_faces and update the current count – Alan Kavanagh Aug 30 '17 at 09:33
  • can you please help me to do that... it will save my life :) –  Aug 30 '17 at 09:34
  • 3
    `detectMultiScale` is only able to tell you where faces are located in the input frame. Thus, it is not able to identify (with IDs) faces. To count the number of people somewhat accurately, you will have to track the faces between frames, this [answer](https://stackoverflow.com/a/36274515/5799975) should get you started. – Elouarn Laine Aug 30 '17 at 09:45
  • OpenCV can't help you on your thing ! What a `legend` ? – dsgdfg Sep 08 '17 at 07:53
  • If you need to recognize faces and assign a unique ID to it, one way is to do it through Azure cognitive service. They have an face API where you can upload a face picture and store an ID. Each time you can send a face image up to see if your image matches any of face id you have previous defined. Noted that this would cause some money each call and have quite a bit of latency as your number of face stored increases. – chrisckwong821 Sep 11 '17 at 06:24

3 Answers3

0

No need for a list...

First of all, as you have no IDs for the people, storing the people seen in a list is pointless so you should just use a variable storing an int:

people_count = 0

and then instead of this:

people_list.insert(len(people_list)+1,i)

you need to check if the number of people in the current frame is greater than the number of people in the last frame and if it is then increment the people_count by the number of people in the current frame - the number of people in the last frame. So if there were 4 people last frame and there are 6 this frame then increment by 2.

So instead of the line above, do something like:

if len(detections) > last_count:
   people_count += len(detections - last_count)

last_count = len(detection)

This should work for you assuming you declare last_count as 0 at the start of your code...

However saying this, as mentioned in the comments, if you cannot uniquely identify the faces, then there will be a significant floor in your program.

The floor is that if person A enters the room, people_count will increment and then if person B enters as well, people_count will now be 2. If person A leaves now it remains at 2 (as there have been 2 people). But now if person A returns, it will raise the count to 3 which is wrong as you have seen only 2 people.

In addition, if you miss a face for just one frame, then the count will increment as it will take this as that person left and a new person came into the room.

p.s as a sidenote, when adding to the end of the list, you shouldn't use .insert(len(lst), val), instead you should use .append(val) as this is much neater :)

Joe Iddon
  • 20,101
  • 7
  • 33
  • 54
0

Basically, what you are doing is people_list.insert(len(people_list)+1,i) .

What the insert command essentially does is : The first argument is the index of the element before which to insert. And people_list.insert(0, x) inserts at the front of the list, and people_list.insert(len(people_list), x) is equivalent to a.append(x). However you are are doing (len() + 1 , i).

This is how a list index values look like : 0 1 2 3 4 5 . Here len(arr_list)=6 . So here arr_list.insert(len(arr_list), x) would insert i at the 6th index, which is like append.

Shivansh Jagga
  • 1,541
  • 1
  • 15
  • 24
0

Working on face-count change to solve the problem is a great hack that might work. but-

Consider this case- A person enters the frame exactly when another person leaves the frame. Now looking at the list count, there's no way you can tell that.

Also if the face cascade fails to detect face in one frame, then you'll have an erroneous count.

Since the question has opencv tagged, I suggest-

  • Look for a face in the image.
  • Once a face is found, stop considering that face again until it is lost. How you'll know the face is lost when you are not finding face? Track the face after finding and adding a mask over it. There are many ways for tracking. Optical flow, camshift might work. Also look about KCF, MIL, Boosting trackers available from opencv 3.

Then keep updating the number of faces just like you are doing now. It gives you a better count for people entering and leaving. But not the distinct people count as you are not storing the faces.

I.Newton
  • 1,753
  • 1
  • 10
  • 14