LeonLok / Deep-SORT-YOLOv4

People detection and optional tracking with Tensorflow backend.
GNU General Public License v3.0
496 stars 170 forks source link

How to get asynchronous mode working? #4

Open akanuasiegbu opened 4 years ago

akanuasiegbu commented 4 years ago

So why does videocaptureasync.py have NoneType? And how to fix this error? While running asynchronous mode it kind of works and goes through while loop in demo.py . From the image below demo.py goes through while loop 42 times and then has an error. I found a link that talked about this error but unable to fix the error currently. https://github.com/alievk/avatarify/issues/67

VideoAsync

doubleLLL3 commented 4 years ago

Hey, same as you. Did you fix it? I just find if I change the sleep time longer in the videocaptureasync.py, it will read more frames and it's very slow.

def update(self):
        while self.started:
      →→sleep(0.03)
            grabbed, frame = self.cap.read()
            with self.read_lock:
                self.grabbed = grabbed
                self.frame = frame

So I think is the speed of detect + track slower than video capture async, so if it continues to detect but the video had been loaded over. Do you have any idea? I'm new in async module, I want to find this problem later.

doubleLLL3 commented 4 years ago

I made some try, and here is my solution: (changes in the videocaptureasync.py)

def __init__(self, file_path):
    ...
    self.first = True # add, wait long time for loading model at first frame
    self.next = True # add, now can update next frame

def update(self):
    while self.started:
        if not self.next: # add, wait long time for loading model at first frame, so it won't lost many frames
            continue # add
        sleep(0.03) # can be changed to match your model speed
        ...

def read(self):
    if self.first: # add
        self.next = False # add, pause update() for loading model at first frame
        self.first = False # add
    else: # add
        self.next = True # add
    if self.frame is None: # add, the last frame is None, so be careful at the last frame ☆☆☆
        return False, 0 # add ☆☆☆
    with self.read_lock:
        ...

Beacause I only use GTX 1060 for the test, I add self.first and self.next. It can prevent losing many frames that loading models at first takes much time.

If you don't care about it, you can just add the last 2 lines with ☆☆☆.

TibRib commented 3 years ago

Hi, I'm a bit late to the party but before seeing your solution I found out you can add this small verification to allow the detection to terminate well.

Your solution seems more optimized so don't mind me if I use it :)

videocaptureasync.py,

def update(self):
        while self.started:
            sleep(0.03)
            grabbed, frame = self.cap.read()
            if not grabbed or frame is None or frame.size == 0:  #Added line
                self.grabbed = False                             #Added line
                continue                                         #Added line
            with self.read_lock:
                self.grabbed = grabbed
                self.frame = frame

Anyway, I leave it there in case it's useful to someone