cv2.TrackerUpdate causing 1 minute video to run for 3 min

I have a program using OpenCV that counts items as they pass down a conveyor belt. The problem is that the TrackerUpdate() function is creating the bottleneck when i define success and new_bbox:

success, new_bbox = tracker.update(cv2.cvtColor(thresh,cv2.COLOR_GRAY2BGR))

Can anybody help me figure out why this is happening as well as a workaround to make the video play at normal speed?

import cv2
import numpy as np

# Intersection over Union function
def iou(boxA, boxB):
    xA = max(boxA[0], boxB[0])
    yA = max(boxA[1], boxB[1])
    xB = min(boxA[0] + boxA[2], boxB[0] + boxB[2])
    yB = min(boxA[1] + boxA[3], boxB[1] + boxB[3])

    interArea = max(xB - xA, 0) * max(yB - yA, 0)
    boxAArea = boxA[2] * boxA[3]
    boxBArea = boxB[2] * boxB[3]
    iou = interArea / float(boxAArea + boxBArea - interArea)

    return iou

# Check if the contour could be a pizza
def is_potential_pizza(contour):
    (x, y), radius = cv2.minEnclosingCircle(contour)
    area = cv2.contourArea(contour)
    circularity = (4 * np.pi * area) / (cv2.arcLength(contour, True) ** 2) if cv2.arcLength(contour, True) else 0
    if 0.2 < circularity < 1.5 and area > 200:  # Adjust these values as necessary
        return True
    return False

cap = cv2.VideoCapture("path\\video.mp4")
video_writer = cv2.VideoWriter("output.avi", cv2.VideoWriter_fourcc(*'XVID'), int(cap.get(cv2.CAP_PROP_FPS)), (int(cap.get(3)), int(cap.get(4))))
trackers = {}
next_tracker_id = 0

LINE_POINTS_BACK = [(609, 140), (627, 158)]  # back line points
LINE_POINTS_FRONT = [(900, 275), (1000, 400)]  # front line points

start_set=set()
end_set=set()
crossed_pizza_back = 0
crossed_pizza_front = 0

while True:
    ret, image = cap.read()
    
    if not ret:
        break

    # Convert to grayscale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Apply a threshold to get the white areas in the image (adjust the threshold value as needed)
    _, thresh = cv2.threshold(gray, 190, 255, cv2.THRESH_BINARY)

    # Erosion and dilation (morphological transformations)
    kernel = np.ones((3,3), np.uint8)
    thresh = cv2.erode(thresh, kernel, iterations=1)
    
    #Dilation
    kernel = np.ones((3,3), np.uint8)
    thresh = cv2.dilate(thresh, kernel, iterations=1)
    
    # Apply a morphological operation to fill in the gaps
    kernel = np.ones((3,3), np.uint8)
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
    
    # Apply a morphological operation to remove small holes
    kernel = np.ones((3,3), np.uint8)
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    
    # sharpen the image
    kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
    thresh = cv2.filter2D(thresh, -1, kernel)
    
    

    # Find contours
    contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)


# Process new contours for potential new trackers
    for contour in contours:
        if is_potential_pizza(contour):
            bbox = cv2.boundingRect(contour)
            # Check if the new bounding box overlaps with any existing trackers
            if not any(iou(bbox, tracked_bbox[1]) > 0.2 for (_, tracked_bbox) in trackers.items()):
              new_tracker = cv2.TrackerKCF.create()
              new_tracker.init(cv2.cvtColor(thresh,cv2.COLOR_GRAY2BGR), bbox)
              trackers[next_tracker_id] = (new_tracker, bbox)
              next_tracker_id += 1


    # Update the trackers
    trackers_to_delete = []
    for tracker_id, (tracker, _) in trackers.items():
        success, new_bbox = tracker.update(cv2.cvtColor(thresh,cv2.COLOR_GRAY2BGR))
      
        if success:
            trackers[tracker_id] = (tracker, new_bbox)  # Update the tracker's bbox
           
        else:
            trackers_to_delete.append(tracker_id)  # Mark this tracker for deletion

    # Delete trackers that failed to update
    for tracker_id in trackers_to_delete:
        del trackers[tracker_id]


    # Draw the bounding boxes for all trackers
    for tracker_id, (_, bbox) in trackers.items():
        p1 = (int(bbox[0]), int(bbox[1]))
        p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
        center_x,center_y=(p1[0]+p2[0])//2,(p1[1]+p2[1])//2
        crossed_color=0
        
        # Check if the pizza has crossed the line
        if center_x>=LINE_POINTS_BACK[1][0] and center_y>=LINE_POINTS_BACK[0][1] and center_y<=LINE_POINTS_BACK[1][1]:
            end_set.add(tracker_id)
            if tracker_id in start_set:
                crossed_pizza_back += 1
                start_set.remove(tracker_id)
                crossed_color=255
        elif center_x<=LINE_POINTS_BACK[1][0] and center_y>=LINE_POINTS_BACK[0][1] and center_y<=LINE_POINTS_BACK[1][1]:
            start_set.add(tracker_id)
            if tracker_id in end_set:
                crossed_pizza_back -= 1
                end_set.remove(tracker_id)
        
        if center_x>=LINE_POINTS_FRONT[1][0] and center_y>=LINE_POINTS_FRONT[0][1] and center_y<=LINE_POINTS_FRONT[1][1]:
            end_set.add(tracker_id)
            if tracker_id in start_set:
                crossed_pizza_front += 1
                start_set.remove(tracker_id)
                crossed_color=255
        elif center_x<=LINE_POINTS_FRONT[1][0] and center_y>=LINE_POINTS_FRONT[0][1] and center_y<=LINE_POINTS_FRONT[1][1]:
            start_set.add(tracker_id)
            if tracker_id in end_set:
                crossed_pizza_front -= 1
                end_set.remove(tracker_id)

        cv2.rectangle(image, p1, p2, (0, crossed_color, 0), 2, 1)
        cv2.putText(image, str(tracker_id), (center_x,center_y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (crossed_color, 0, 1), 2)
       
        
    

    # Displaying pizza counts for front & back line
    cv2.line(image, LINE_POINTS_BACK[0], LINE_POINTS_BACK[1], (0, 255, 0), 2)
    cv2.line(image, LINE_POINTS_FRONT[0], LINE_POINTS_FRONT[1], (0, 255, 0), 2)
    cv2.putText(image, f"Back Line Pizza Count: {crossed_pizza_back}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
    cv2.putText(image, f"Front Line Pizza Count: {crossed_pizza_front}", (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
    

    cv2.imshow("Detected Pizzas", image)
    cv2.imshow("Detected Pizzas 2", thresh)
    video_writer.write(image)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break


cv2.destroyAllWindows()
cap.release()
video_writer.release()