Beispiel #1
0
def add_new_blobs(boxes, classes, confidences, blobs, frame, tracker,
                  counting_line, line_position, mcdf):
    # add new blobs to existing blobs
    matched_blob_ids = []
    for _idx in range(len(boxes)):
        _type = classes[_idx] if classes != None else None
        _confidence = confidences[_idx] if confidences != None else None

        box_centroid = get_centroid(boxes[_idx])
        box_area = get_area(boxes[_idx])
        match_found = False
        for _id, blob in blobs.items():
            if blob.counted == False and get_iou(boxes[_idx],
                                                 blob.bounding_box) > 0.5:
                match_found = True
                if _id not in matched_blob_ids:
                    blob.num_consecutive_detection_failures = 0
                    matched_blob_ids.append(_id)
                temp_blob = create_blob(
                    boxes[_idx], _type, _confidence, frame,
                    tracker)  # TODO: update blob w/o creating temp blob
                blob.update(temp_blob.bounding_box, _type, _confidence,
                            temp_blob.tracker)
                break

        if not match_found and not is_passed_counting_line(
                box_centroid, counting_line, line_position):
            _blob = create_blob(boxes[_idx], _type, _confidence, frame,
                                tracker)
            blob_id = generate_vehicle_id()
            blobs[blob_id] = _blob

    blobs = remove_stray_blobs(blobs, matched_blob_ids, mcdf)
    return blobs
Beispiel #2
0
def add_new_blobs(boxes, blobs, frame, tracker, current_blob_id, counting_line,
                  line_position, mcdf):
    # add new blobs to existing blobs
    matched_blob_ids = []
    for box in boxes:
        box_centroid = get_centroid(box)
        box_area = get_area(box)
        match_found = False
        for _id, blob in blobs.items():
            if blob.counted == False and box_contains_point(
                    box, blob.centroid):
                match_found = True
                if _id not in matched_blob_ids:
                    blob.num_consecutive_detection_failures = 0
                    matched_blob_ids.append(_id)
                temp_blob = create_blob(
                    box, frame,
                    tracker)  # TODO: update blob w/o creating temp blob
                blob.update(temp_blob.bounding_box, temp_blob.tracker)
                break

        if not match_found and not is_passed_counting_line(
                box_centroid, counting_line, line_position):
            _blob = create_blob(box, frame, tracker)
            blobs[current_blob_id] = _blob
            current_blob_id += 1

    blobs = remove_stray_blobs(blobs, matched_blob_ids, mcdf)
    return blobs, current_blob_id
    def count(self, frame):
        log = []
        self.frame = frame

        for _id, blob in list(self.blobs.items()):
            # update trackers
            success, box = blob.tracker.update(self.frame)
            if success:
                blob.num_consecutive_tracking_failures = 0
                blob.update(box)
            else:
                blob.num_consecutive_tracking_failures += 1

            # count vehicles that have left the frame if no counting line exists
            # or those that have passed the counting line if one exists
            if (self.counting_line == None and
                    (blob.num_consecutive_tracking_failures == self.mctf or blob.num_consecutive_detection_failures == self.mcdf) and
                    not blob.counted) \
                        or \
                    (self.counting_line != None and
                    is_passed_counting_line(blob.centroid, self.counting_line, self.cl_position) and
                    not blob.counted):
                blob.counted = True
                self.vehicle_count += 1
                # classes_of_interest = ['bicycle', 'car', 'motorcycle', 'bus', 'truck', 'person']
                if blob.vehicle_type == 'bicycle':
                    self.bicycle_count += 1
                elif blob.vehicle_type == 'car':
                    self.car_count += 1
                elif blob.vehicle_type == 'truck':
                    self.truck_count += 1
                elif blob.vehicle_type == 'bus':
                    self.bus_count += 1
                log.append({
                    'blob_id': _id,
                    'count': self.vehicle_count,
                    'datetime': datetime.now()
                })

            if blob.num_consecutive_tracking_failures >= self.mctf:
                # delete untracked blobs
                del self.blobs[_id]

        if self.frame_count >= self.di:
            # rerun detection
            droi_frame = get_roi_frame(self.frame, self.droi)
            boxes, classes_types = get_bounding_boxes(droi_frame,
                                                      self.detector)
            self.blobs, current_blob_id = add_new_blobs(
                boxes, classes_types, self.blobs, self.frame, self.tracker,
                self.blob_id, self.counting_line, self.cl_position, self.mcdf)
            self.blob_id = current_blob_id
            self.blobs = remove_duplicates(self.blobs)
            self.frame_count = 0

        self.frame_count += 1

        return log
def add_new_blobs(boxes, classes, confidences, blobs, frame, tracker, counting_line, line_position, mcdf):
    '''
    Adds new blobs or updates existing ones.
    '''
    matched_blob_ids = []
    for i, box in enumerate(boxes):
        _type = classes[i] if classes is not None else None
        _confidence = confidences[i] if confidences is not None else None
        _tracker = get_tracker(tracker, box, frame)

        box_centroid = get_centroid(box)
        match_found = False
        for _id, blob in blobs.items():
            if not blob.counted and get_overlap(box, blob.bounding_box) >= 0.7:
                match_found = True
                if _id not in matched_blob_ids:
                    blob.num_consecutive_detection_failures = 0
                    matched_blob_ids.append(_id)
                blob.update(box, _type, _confidence, _tracker)

                logger.debug('Blob updated.', extra={
                    'meta': {
                        'cat': 'BLOB_UPSERT',
                        'vehicle_id': _id,
                        'bounding_box': blob.bounding_box,
                        'type': blob.type,
                        'type_confidence': blob.type_confidence,
                        'image': get_base64_image(get_box_image(frame, blob.bounding_box)),
                    },
                })
                break

        if not match_found and not is_passed_counting_line(box_centroid, counting_line, line_position):
            _blob = Blob(box, _type, _confidence, _tracker)
            blob_id = generate_vehicle_id()
            blobs[blob_id] = _blob

            logger.debug('Blob created.', extra={
                'meta': {
                    'cat': 'BLOB_UPSERT',
                    'vehicle_id': blob_id,
                    'bounding_box': _blob.bounding_box,
                    'type': _blob.type,
                    'type_confidence': _blob.type_confidence,
                    'image': get_base64_image(get_box_image(frame, _blob.bounding_box)),
                },
            })

    blobs = remove_stray_blobs(blobs, matched_blob_ids, mcdf)
    return blobs
Beispiel #5
0
    def count(self, frame):
        log = []
        self.frame = frame

        if self.frame_count >= self.di:
            # rerun detection
            droi_frame = get_roi_frame(self.frame, self.droi)
            boxes = get_bounding_boxes(droi_frame, self.detector)
            self.blobs, current_blob_id = add_new_blobs(
                boxes, self.blobs, self.frame, self.tracker, self.blob_id,
                self.counting_line, self.cl_position, self.mcdf)
            self.blob_id = current_blob_id
            self.blobs = remove_duplicates(self.blobs)
            self.frame_count = 0

        for _id, blob in list(self.blobs.items()):
            # update trackers
            success, box = blob.tracker.update(self.frame)
            if success:
                blob.num_consecutive_tracking_failures = 0
                blob.update(box)
            else:
                blob.num_consecutive_tracking_failures += 1

            # delete untracked blobs
            if blob.num_consecutive_tracking_failures >= self.mctf:
                del self.blobs[_id]

            # count vehicles
            if is_passed_counting_line(blob.centroid, self.counting_line,
                                       self.cl_position) and not blob.counted:
                blob.counted = True
                self.vehicle_count += 1
                (x, y, w, h) = [int(v) for v in blob.bounding_box]
                roi = self.frame[y:y + h + 40, x:x + w + 40]
                #cv2.imwrite(f"./detected/{self.vehicle_count}.jpg", roi)
                cv2.imwrite("./roi.jpg", roi)
                log.append({
                    'blob_id': _id,
                    'count': self.vehicle_count,
                    'datetime': datetime.now()
                })

        self.frame_count += 1

        return log
Beispiel #6
0
def add_new_blobs(boxes, blobs, frame, tracker, current_blob_id, counting_line,
                  line_position):
    # add new blobs to existing blobs
    for box in boxes:
        box_centroid = get_centroid(box)
        box_area = get_area(box)
        match_found = False
        for _id, blob in blobs.items():
            if blob.counted == False and \
                    ((blob.area >= box_area and box_contains_point(blob.bounding_box, box_centroid)) \
                    or (box_area >= blob.area and box_contains_point(box, blob.centroid))):
                match_found = True
                temp_blob = create_blob(
                    box, frame,
                    tracker)  # TODO: update blob w/o creating temp blob
                blob.update(temp_blob.bounding_box, temp_blob.tracker)
                break

        if not match_found and not is_passed_counting_line(
                box_centroid, counting_line, line_position):
            _blob = create_blob(box, frame, tracker)
            blobs[current_blob_id] = _blob
            current_blob_id += 1
    return blobs, current_blob_id
        for _id, blob in list(blobs.items()):
            # update trackers
            success, box = blob.tracker.update(frame)
            if success:
                blob.num_consecutive_tracking_failures = 0
                blob.update(box)
            else:
                blob.num_consecutive_tracking_failures += 1

            # delete untracked blobs
            if blob.num_consecutive_tracking_failures >= MAX_CONSECUTIVE_TRACKING_FAILURES:
                del blobs[_id]

            # count vehicles
            if is_passed_counting_line(blob.centroid, counting_line,
                                       clposition) and not blob.counted:
                blob.counted = True
                vehicle_count += 1

                # log count data to a file (vehicle_id, count, datetime)
                if args.record:
                    _row = '{0}, {1}, {2}\n'.format('v_' + str(_id),
                                                    vehicle_count,
                                                    datetime.now())
                    log_file.write(_row)
                    log_file.flush()

        if frame_counter >= DETECTION_INTERVAL:
            # rerun detection
            droi_frame = get_roi_frame(frame, droi)
            boxes = get_bounding_boxes(droi_frame, detector)
Beispiel #8
0
    def count(self, frame):
        log = []
        self.frame = frame

        for _id, blob in list(self.blobs.items()):
            # update trackers
            success, box = blob.tracker.update(self.frame)
            if success:
                blob.num_consecutive_tracking_failures = 0
                blob.update(box)
                log_info(
                    'Vehicle tracker updated.', {
                        'event': 'TRACKER_UPDATE',
                        'vehicle_id': _id,
                        'bounding_box': blob.bounding_box,
                        'centroid': blob.centroid,
                    })
                f = './ProcessRecords/Vehicletrackerupdated58.txt'
                with open(f, "a") as file:
                    file.write('TRACKER_UPDATE' + '-' + 'id' + str(_id) + '-' +
                               'bounding_box' + str(blob.bounding_box) + '-' +
                               'centroid' + str(blob.centroid) + "\n")

            else:
                blob.num_consecutive_tracking_failures += 1

            # count vehicles that have left the frame if no counting line exists
            # or those that have passed the counting line if one exists
            if (self.counting_line == None and \
                    (blob.num_consecutive_tracking_failures == self.mctf or blob.num_consecutive_detection_failures == self.mcdf) and \
                    not blob.counted) \
                        or \
                    (self.counting_line != None and \
                    # don't count a blob if it was first detected at a position past the counting line
                    # this enforces counting in only one direction


                    not is_passed_counting_line(blob.position_first_detected, self.counting_line, self.cl_position) and \
                    is_passed_counting_line(blob.centroid, self.counting_line, self.cl_position) and \
                    not blob.counted):
                blob.counted = True
                self.vehicle_count += 1
                # count by vehicle type
                if blob.type != None:
                    if blob.type in self.types_counts:
                        self.types_counts[blob.type] += 1
                    else:
                        self.types_counts[blob.type] = 1
                log_info(
                    'Vehicle counted.', {
                        'event': 'VEHICLE_COUNT',
                        'id': _id,
                        'type': blob.type,
                        'count': self.vehicle_count,
                        'position_first_detected':
                        blob.position_first_detected,
                        'position_counted': blob.centroid,
                        'counted_at': time.time(),
                    })
                f = './ProcessRecords/Vehiclecounted58.txt'
                with open(f, "a") as file:
                    file.write('VEHICLE_COUNT' + '-' + 'id' + str(_id) + '-' +
                               'type' + str(blob.type) + '-' + 'count' +
                               str(self.vehicle_count) + '-' +
                               'position_first_detected' +
                               str(blob.position_first_detected) + '-' +
                               'position_counted' + str(blob.centroid) + '-' +
                               'counted_at' + str(time.time()) + "\n")

            if blob.num_consecutive_tracking_failures >= self.mctf:
                # delete untracked blobs
                del self.blobs[_id]

        if self.frame_count >= self.di:
            # rerun detection
            droi_frame = get_roi_frame(self.frame, self.droi)
            _bounding_boxes, _classes, _confidences = get_bounding_boxes(
                droi_frame, self.detector)
            self.blobs = add_new_blobs(_bounding_boxes, _classes, _confidences,
                                       self.blobs, self.frame, self.tracker,
                                       self.counting_line, self.cl_position,
                                       self.mcdf)
            self.blobs = remove_duplicates(self.blobs)
            self.frame_count = 0

        self.frame_count += 1

        return log
Beispiel #9
0
def add_new_blobs(boxes, classes, confidences, blobs, frame, tracker, counting_line, line_position, mcdf):
    # add new blobs or update existing ones
    matched_blob_ids = []
    for i in range(len(boxes)):
        _type = classes[i] if classes != None else None
        #print (confidences)
        if confidences != []:
            _confidence = confidences[i]
        else:
            _confidence=None

        box_centroid = get_centroid(boxes[i])
        box_area = get_area(boxes[i])
        match_found = False
        for _id, blob in blobs.items():
            #print (_id,blob)
            if blob.counted == False and get_iou(boxes[i], blob.bounding_box) > 0.5:
                match_found = True
                if _id not in matched_blob_ids:
                    blob.num_consecutive_detection_failures = 0
                    matched_blob_ids.append(_id)
                temp_blob = create_blob(boxes[i], _type, _confidence, frame, tracker) # TODO: update blob w/o creating temp blob
                blob.update(temp_blob.bounding_box, _type, _confidence, temp_blob.tracker)
                #blob.trajectory

                # Create a sequence of points to make a contour
                #contour=cv2.contourArea([(100,100),(200,200),(500,500)])
                #cv2.pointPolygonTest([(100,100),(200,200),(500,500)], box_centroid, false)
                #area_of_left_left = np.array([[1, 1], [10, 50], [50, 50]], dtype=np.int32)
                # area_of_left_straight=np.array([[1, 1], [10, 50], [50, 50]], dtype=np.int32)
                # area_of_left_right=np.array([[1, 1], [10, 50], [50, 50]], dtype=np.int32)
                # area_of_left=np.array([[1, 1], [10, 50], [50, 50]], dtype=np.int32)

                #left_left = object_in_polygon(frame, area_of_left_left,box_centroid)

                #print(box_centroid)
                #print(left_left)

                log_info('Blob updated.', {
                    'event': 'BLOB_UPSERT',
                    'vehicle_id': _id,
                    'bounding_box': blob.bounding_box,
                    'type': blob.type,
                    'type_confidence': blob.type_confidence,
                    'center': box_centroid,
                    #'direction': direction
                    #'trajectory':trajectory.append
                    #'image': get_base64_image(get_box_image(frame, blob.bounding_box))
                })
                f = './ProcessRecords/Blobupdated58.txt'
                with open(f, "a") as file:
                    file.write(
                        'BLOB_UPSERT' + '-' + 'id' + str(_id) + '-' + 'bounding_box'+str(blob.bounding_box)+'-'+'type' + str(blob.type) + '-' + 'type_confidence' + str(
                            blob.type_confidence) + '-' + 'center' + str(
                            box_centroid) + "\n")

                break

        if not match_found and not is_passed_counting_line(box_centroid, counting_line, line_position):
            _blob = create_blob(boxes[i], _type, _confidence, frame, tracker)
            blob_id = generate_vehicle_id()
            blobs[blob_id] = _blob

            log_info('Blob created.', {
                'event': 'BLOB_UPSERT',
                'vehicle_id': blob_id,
                'bounding_box': _blob.bounding_box,
                'type': _blob.type,
                'type_confidence': _blob.type_confidence,
                'center': box_centroid

                #'image': get_base64_image(get_box_image(frame, _blob.bounding_box))
            })
            f = './ProcessRecords/Blobcreated58.txt'
            with open(f, "a") as file:
                file.write(
                    'BLOB_UPSERT' + '-' + 'id' + str(blob_id) + '-' + 'bounding_box' + str(
                        _blob.bounding_box) + '-' + 'type' + str(_blob.type) + '-' + 'type_confidence' + str(
                        _blob.type_confidence) + '-' + 'center' + str(box_centroid) + "\n")

    blobs = remove_stray_blobs(blobs, matched_blob_ids, mcdf)
    return blobs
Beispiel #10
0
    def count(self, frame):

        log = []

        self.frame = frame



        if self.frame_count >= self.di:

            # rerun detection

            droi_frame = get_roi_frame(self.frame, self.droi)
        
            boxes = get_bounding_boxes(droi_frame, self.detector)
            #print(self.blobs)
            self.blobs, current_blob_id = add_new_blobs(boxes, self.blobs, self.frame, self.tracker, self.blob_id, self.counting_line, self.cl_position, self.mcdf, self.detector)
            
            self.blob_id = current_blob_id

            self.blobs = remove_duplicates(self.blobs)

            self.frame_count = 0



        for _id, blob in list(self.blobs.items()):
            
            # update trackers
            #print(blob[0])
            success, box = blob[0].tracker.update(self.frame)
            
            if success:

                blob[0].num_consecutive_tracking_failures = 0

                blob[0].update(box)

            else:

                blob[0].num_consecutive_tracking_failures += 1



            # delete untracked blobs

            if blob[0].num_consecutive_tracking_failures >= self.mctf:

                del self.blobs[_id]



            # count vehicles

            if is_passed_counting_line(blob[0].centroid, self.counting_line, self.cl_position) and not blob[0].counted:
                
                blob[0].counted = True
                
                if blob[1] == 'car':
                    self.countCar +=1
                elif blob[1] == 'bus':
                    self.countBus +=1
                elif blob[1] == 'truck':
                    self.countTruck +=1
                elif blob[1] == 'person':
                    self.countPerson +=1
                elif blob[1] == 'bicycle':
                    self.countBicycle +=1
                elif blob[1] == 'motorcycle':
                    self.countMotorcycle +=1
                    
                self.vehicle_count += 1

                log.append({'blob_id': _id, 'count': self.vehicle_count, 'datetime': datetime.now()})

        self.frame_count += 1

        return log
Beispiel #11
0
def add_new_blobs(boxes, classes, confidences, blobs, frame, tracker,
                  counting_line, line_position, mcdf):
    # add new blobs or update existing ones
    matched_blob_ids = []
    for i in range(len(boxes)):
        _type = classes[i] if classes != None else None
        _confidence = confidences[i] if confidences != None else None
        _tracker = get_tracker(tracker, boxes[i], frame)

        box_centroid = get_centroid(boxes[i])
        box_area = get_area(boxes[i])
        match_found = False
        for _id, blob in blobs.items():
            if blob.counted == False and get_iou(boxes[i],
                                                 blob.bounding_box) > 0.5:
                match_found = True
                if _id not in matched_blob_ids:
                    blob.num_consecutive_detection_failures = 0
                    matched_blob_ids.append(_id)
                blob.update(boxes[i], _type, _confidence, _tracker)

                log_info(
                    'Blob updated.', {
                        'cat':
                        'BLOB_UPSERT',
                        'vehicle_id':
                        _id,
                        'bounding_box':
                        blob.bounding_box,
                        'type':
                        blob.type,
                        'type_confidence':
                        blob.type_confidence,
                        'image':
                        get_base64_image(
                            get_box_image(frame, blob.bounding_box))
                    })
                break

        if not match_found and not is_passed_counting_line(
                box_centroid, counting_line, line_position):
            _blob = Blob(boxes[i], _type, _confidence, _tracker)
            blob_id = generate_vehicle_id()
            blobs[blob_id] = _blob

            log_info(
                'Blob created.', {
                    'cat':
                    'BLOB_UPSERT',
                    'vehicle_id':
                    blob_id,
                    'bounding_box':
                    _blob.bounding_box,
                    'type':
                    _blob.type,
                    'type_confidence':
                    _blob.type_confidence,
                    'image':
                    get_base64_image(get_box_image(frame, _blob.bounding_box))
                })

    blobs = remove_stray_blobs(blobs, matched_blob_ids, mcdf)
    return blobs
def add_new_blobs(boxes, blobs, frame, tracker, current_blob_id, counting_line,
                  line_position, mcdf, detector):
    path = 'detectors\yolo'
    labelsPath = os.path.join(path, 'coco.names')
    LABELS = open(labelsPath).read().strip().split("\n")
    # add new blobs to existing blobs
    matched_blob_ids = []
    if detector == 'yolo':
        for box in boxes:
            #print(boxes)
            box_centroid = get_centroid(box[0])
            box_area = get_area(box[0])
            match_found = False
            for _id, blob in blobs.items():
                #print(blobs.items())
                if blob[0].counted == False and box_contains_point(
                        box[0], blob[0].centroid):
                    #((blob.area >= box_area and box_contains_point(blob.bounding_box, box_centroid)) \
                    #or (box_area >= blob.area and box_contains_point(box[0], blob.centroid))):
                    match_found = True
                    if _id not in matched_blob_ids:

                        blob[0].num_consecutive_detection_failures = 0

                        matched_blob_ids.append(_id)
                    temp_blob = create_blob(
                        box[0], frame,
                        tracker)  # TODO: update blob w/o creating temp blob
                    blob[0].update(temp_blob.bounding_box, temp_blob.tracker)
                    break

            if not match_found and not is_passed_counting_line(
                    box_centroid, counting_line, line_position):
                _blob = create_blob(box[0], frame, tracker)
                blobs[current_blob_id] = _blob, LABELS[box[1][0]]
                current_blob_id += 1
    else:
        for box in boxes:
            #print(boxes)
            box_centroid = get_centroid(box)
            box_area = get_area(box)
            match_found = False
            for _id, blob in blobs.items():
                #print(blobs.items())
                if blob.counted == False and box_contains_point(
                        box, blob.centroid):
                    #((blob.area >= box_area and box_contains_point(blob.bounding_box, box_centroid)) \
                    #or (box_area >= blob.area and box_contains_point(box[0], blob.centroid))):
                    match_found = True
                    if _id not in matched_blob_ids:

                        blob.num_consecutive_detection_failures = 0

                        matched_blob_ids.append(_id)
                    temp_blob = create_blob(
                        box, frame,
                        tracker)  # TODO: update blob w/o creating temp blob
                    blob.update(temp_blob.bounding_box, temp_blob.tracker)
                    break

            if not match_found and not is_passed_counting_line(
                    box_centroid, counting_line, line_position):
                _blob = create_blob(box, frame, tracker)
                blobs[current_blob_id] = _blob
                current_blob_id += 1

    blobs = remove_stray_blobs(blobs, matched_blob_ids, mcdf)
    return blobs, current_blob_id
Beispiel #13
0
def add_new_blobs(boxes, classes, confidences, blobs, frame, tracker, counting_line, line_position, mcdf):
    # add new blobs or update existing ones
    matched_blob_ids = []
    print(classes)
    print(boxes)
    for i in range(len(boxes)):
        if classes != []:
            print(classes[i])
            _type = classes[i]
        else:
            _type=None
        print (confidences)
        if confidences != []:
            _confidence = confidences[i]
        else:
            _confidence=None

        box_centroid = get_centroid(boxes[i])
        box_area = get_area(boxes[i])
        match_found = False
        for _id, blob in blobs.items():
            #print (_id,blob)
            if blob.counted == False and get_iou(boxes[i], blob.bounding_box) > 0.5:
                match_found = True
                if _id not in matched_blob_ids:
                    blob.num_consecutive_detection_failures = 0
                    matched_blob_ids.append(_id)
                temp_blob = create_blob(boxes[i], _type, _confidence, frame, tracker) # TODO: update blob w/o creating temp blob
                blob.update(temp_blob.bounding_box, _type, _confidence, temp_blob.tracker)
                #blob.trajectory


                # Create a sequence of points to make a contour

                #contour=cv2.contourArea([(100,100),(200,200),(500,500)])
                #cv2.pointPolygonTest([(100,100),(200,200),(500,500)], box_centroid, false)


                log_info('Blob updated.', {
                    'event': 'BLOB_UPSERT',
                    'vehicle_id': _id,
                    'bounding_box': blob.bounding_box,
                    'type': blob.type,
                    'type_confidence': blob.type_confidence,
                    'center': box_centroid,
                    #'direction': direction
                    #'trajectory':trajectory.append
                    #'image': get_base64_image(get_box_image(frame, blob.bounding_box))
                })

                break

        if not match_found and not is_passed_counting_line(box_centroid, counting_line, line_position):
            _blob = create_blob(boxes[i], _type, _confidence, frame, tracker)
            blob_id = generate_vehicle_id()
            blobs[blob_id] = _blob

            log_info('Blob created.', {
                'event': 'BLOB_UPSERT',
                'vehicle_id': blob_id,
                'bounding_box': _blob.bounding_box,
                'type': _blob.type,
                'type_confidence': _blob.type_confidence,
                'centere': box_centroid

                #'image': get_base64_image(get_box_image(frame, _blob.bounding_box))
            })

    blobs = remove_stray_blobs(blobs, matched_blob_ids, mcdf)
    return blobs
    def count(self, frame):
        _timer = cv2.getTickCount(
        )  # set timer to calculate processing frame rate

        self.frame = frame

        for _id, blob in list(self.blobs.items()):
            # update trackers
            success, box = blob.tracker.update(self.frame)
            if success:
                blob.num_consecutive_tracking_failures = 0
                blob.update(box)
                logger.debug('Vehicle tracker updated.',
                             extra={
                                 'meta': {
                                     'cat': 'TRACKER_UPDATE',
                                     'vehicle_id': _id,
                                     'bounding_box': blob.bounding_box,
                                     'centroid': blob.centroid,
                                 },
                             })
            else:
                blob.num_consecutive_tracking_failures += 1

            # count vehicles that have left the frame if no counting line exists
            # or those that have passed the counting line if one exists
            if (self.counting_line == None and \
                    (blob.num_consecutive_tracking_failures == self.mctf or blob.num_consecutive_detection_failures == self.mcdf) and \
                    not blob.counted) \
                        or \
                    (self.counting_line != None and \
                    # don't count a blob if it was first detected at a position past the counting line
                    # this enforces counting in only one direction


                    not is_passed_counting_line(blob.position_first_detected, self.counting_line, self.cl_position) and \
                    is_passed_counting_line(blob.centroid, self.counting_line, self.cl_position) and \
                    not blob.counted):
                blob.counted = True
                self.vehicle_count += 1
                # count by vehicle type
                if blob.type != None:
                    if blob.type in self.types_counts:
                        self.types_counts[blob.type] += 1
                    else:
                        self.types_counts[blob.type] = 1
                logger.info('Vehicle counted.',
                            extra={
                                'meta': {
                                    'cat': 'VEHICLE_COUNT',
                                    'id': _id,
                                    'type': blob.type,
                                    'count': self.vehicle_count,
                                    'position_first_detected':
                                    blob.position_first_detected,
                                    'position_counted': blob.centroid,
                                    'counted_at': time.time(),
                                },
                            })

            if blob.num_consecutive_tracking_failures >= self.mctf:
                # delete untracked blobs
                del self.blobs[_id]

        if self.frame_count >= self.di:
            # rerun detection
            droi_frame = get_roi_frame(self.frame, self.droi)
            _bounding_boxes, _classes, _confidences = get_bounding_boxes(
                droi_frame, self.detector)
            self.blobs = add_new_blobs(_bounding_boxes, _classes, _confidences,
                                       self.blobs, self.frame, self.tracker,
                                       self.counting_line, self.cl_position,
                                       self.mcdf)
            self.blobs = remove_duplicates(self.blobs)
            self.frame_count = 0

        self.frame_count += 1

        self.processing_frame_rate = round(
            cv2.getTickFrequency() / (cv2.getTickCount() - _timer), 2)
        logger.debug('Processing frame rate updated.',
                     extra={
                         'meta': {
                             'cat': 'PROCESSING_SPEED',
                             'frame_rate': self.processing_frame_rate
                         },
                     })