Te voy a compartir tres códigos de programación en Python y debes mezclarlos para que se analicen videos y se identifiquen los objetos, tiempo del video, coordenadas y se exporte a un csv esa información.
La idea es que uses y descartes todo lo que sea necesario para cumplir con el objetivo anterior, todos los códigos son funcionales, sólo debes ajustar lo que sea necesario:

primer código:
"
import os
import av
import cv2
import torch
import easyocr
import numpy as np
import urllib.request
import matplotlib.pyplot as plt
from segment_anything import SamAutomaticMaskGenerator, sam_model_registry


def detect_objects_in_video(video_path, output_path):
    """
    Detects objects in the given video and saves the results to the given output path
    """

    # Download model weights
    model_path = "sam_vit_h_4b8939.pth"
    model_url = "https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth"
    if not os.path.exists(model_path):
        urllib.request.urlretrieve(url, model_path)
        print("Model Weights downloaded successfully.")

    # Create the model
    device = "cuda" if torch.cuda.is_available() else "cpu"
    sam = sam_model_registry["vit_h"](checkpoint="sam_vit_h_4b8939.pth")
    sam.to(device=device)
    mask_generator = SamAutomaticMaskGenerator(sam)
    reader = easyocr.Reader(["es"], gpu=torch.cuda.is_available())

    # Open the video file using PyAV
    container = av.open(video_path)

    # Create the output directory
    output_dir = os.path.split(output_path)[0]
    img_dir = os.path.join(output_dir, "IMG")
    os.makedirs(name=img_dir, exist_ok=True)

    # Create the csv file
    with open(output_path, "w") as f:
        f.write("id,object_type,time,coordinates_text\n")

    # Iterate over each frame in the video
    for i, frame in enumerate(container.decode(video=0)):
        time = frame.time
        frame = frame.to_rgb().to_ndarray()

        # Discard frames with a low variance of pixel values
        # or with temporal proximity to the previous frame
        if i % 100 == 0 and frame.var() > 3000:
            segment_frame(frame, mask_generator, os.path.join(img_dir, f'{i:08d}.png'))
            seconds = int(int(time) % 60)
            minutes = int((time // 60) % 60)
            hours = int(time // 3600)
            coordinates = get_coordinates(reader, frame)
            time = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
            
            # Append to the csv file
            with open(output_path, "a") as f:
                f.write(f"{i},object,{time},\"{coordinates}\"\n")

    # Close the video file
    container.close()

    # Free memory
    del sam
    del mask_generator
    del reader

def segment_frame(frame, mask_generator, savepath, top_n=15):
    """
    Performs inference on the given frame and returns the segmentation masks
    """

    # Generate the masks from SAM
    masks = mask_generator.generate(frame)

    # Sort the masks by confidence
    confidences = list(map(lambda x:x["predicted_iou"], masks))
    masks = list(map(lambda x:x[0], sorted(zip(masks, confidences), key=lambda x:x[1], reverse=True)))

    # Save results
    show_anns(frame, masks[:top_n], savepath)

def show_anns(frame, anns, savepath):
    """
    Creates an image with the given annotations and saves it to the given path
    """

    plt.figure(figsize=(20,20))
    plt.imshow(frame)
    
    if len(anns) == 0:
        return
    sorted_anns = sorted(anns, key=(lambda x: x['area']), reverse=True)
    ax = plt.gca()
    ax.set_autoscale_on(False)

    img = np.ones((sorted_anns[0]['segmentation'].shape[0], sorted_anns[0]['segmentation'].shape[1], 4))
    img[:,:,3] = 0
    for ann in sorted_anns:
        m = ann['segmentation']
        color_mask = np.concatenate([np.random.random(3), [0.35]])
        img[m] = color_mask
        
    ax.imshow(img)
    plt.axis('off')
    plt.savefig(savepath, bbox_inches='tight') 

def get_coordinates(reader, frame):
    """
    Returns the coordinates of the given frame
    """
    result = reader.readtext(frame, paragraph=False)
    text = " ".join(map(str, result))

"

Segundo código:

"
import numpy as np
import cv2
import easyocr
import imutils


class VideoAnalyzer():
    def __init__(self):
        """
        This function uses of entity labels from spacy to find dates. It also use the re library to find patterns in the text
        that could lead in to a date.
        input: 
        output: 
        """
        self.reader = easyocr.Reader(
            ["es", "en"], gpu=True)  # instance  Reader class, used for character recognition
        print("Reader easyocr class started")
        # initialize variables
        self.date = "NA"
        self.hour = "NA"
        self.coord1 = "NA"
        self.coord2 = "NA"
        self.id = 0
        self.object = "NA"

    def get_id(self):
        self.id += 1
        return self.id

    def detect_objects_in_video(self, video_path: str, output_path: str):
        with open(output_path, 'w') as f:  # start writing output
            f.write('id,type,time,coordinates\n')
            videocap = cv2.VideoCapture(video_path)
            framespersecond = int(videocap.get(cv2.CAP_PROP_FPS))
            for i in range(framespersecond):
                if i % 10 != 0: # skip frames because it is too slow
                    continue
                _, frame = videocap.read()  # get frame
                # call method that reads text from the frame and updates time, coordinates and date
                self.read_ocr(frame)
                if self.coord1 == "NA" or self.coord2 == "NA": # if coordinates are not found, skip frame
                    continue
                # call method that gets objects from the frame
                objects = self.give_objects(frame)
                for obj in objects:
                    obj_id = obj['id']
                    obj_type = obj['type']
                    detection = f'{obj_id},{obj_type},{self.hour},{self.coord1 + " - " + self.coord2}\n'
                    f.write(detection)

    def read_ocr(self, frame):
        """
        This function uses the easyocr library to read text from the frame and updates time, coordinates and date
        input: frame
        """
        result = self.reader.readtext(
            frame, paragraph=True)  # read text from image
        for res in result:
            text = res[1]  # get text
            chars = text.split(" ")  # Separate chars by spaces
            self.parse_time_date(chars)  # get time and date of the frame
            self.parse_coordinates(chars)  # get coordinates of the plane

    def parse_coordinates(self, chars: list):
        """
        This function uses the easyocr library to read text from the frame and updates time, coordinates and date
        input: chars
        """
        try:
            for i in range(len(chars)):
                if (len(chars[i]) > 10) and (len(chars[i+1]) > 10):  # Clasify chars by lenght
                    indx = len(chars[i])
                    self.coord1 = str(chars[i][indx-11:indx-10])+"°"+str(chars[i][indx-9:indx-7])+"'"+str(
                        chars[i][indx-6:indx-4])+"."+str(chars[i][indx-3:indx-1]) + '" N'  # Get first coordenate
                    self.coord2 = str(chars[i+1][indx-11:indx-9])+"°"+str(chars[i+1][indx-8:indx-6])+"'"+str(
                        chars[i+1][indx-5:indx-3])+"."+str(chars[i+1][indx-2:indx]) + '" W'  # Get second coordenate
        except:
            self.coord1 = "NA"
            self.coord2 = "NA"

    def parse_time_date(self, chars: list):
        """
        This function uses the easyocr library to read text from the frame and updates time, coordinates and date
        input: chars
        """
        for i in range(len(chars)):
            if (len(chars[i]) == 8):  # Clasify chars by lenght
                if ("/" in chars[i]):
                    self.date = str(
                        chars[i][0:2])+"/"+str(chars[i][3:5])+"/"+str(chars[i][6:8])  # Get date
                elif ("8" in chars[i]):
                    self.hour = str(
                        chars[i][0:2])+":"+str(chars[i][3:5])+":"+str(chars[i][6:8])  # Get time

    def give_objects(self, frame) -> list:
        """
        This function uses the contours of the image to find objects in the frame
        input: frame
        output: list of objects
        """

        img = np.asanyarray(frame)[:, :, ::-1].copy()
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        # apply thresholding to convert the grayscale image to a binary image
        _, thresh = cv2.threshold(gray, 50, 255, 0)

        # find the contours
        cnts, _ = cv2.findContours(
            thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        cnts = cnts[0] if imutils.is_cv2() else cnts[1]

        # sort the contours by area and select maximum 10 contours
        cntsSorted = sorted(cnts, key=lambda x: cv2.contourArea(x))

        for _ in range(min(2, len(cntsSorted))):
            yield {
                'type': "VEHICULO",
                'id': self.get_id()
            }

"

tercer código:

"
!apt-get update --yes && apt-get install ffmpeg --yes
!pip install -q git+https://github.com/huggingface/transformers.git

import os
from glob import glob as gb
import os
import pandas as pd
import json
import codefestImagenes as ci
from PIL import Image
import requests
from transformers import CLIPProcessor, CLIPModel

def convertir_video_a_imagen(video):
    comando = f"ffmpeg -i {video} -vf fps=1 Imagenes/{video}/imagen_%04d_seg.jpg"
    os.system(comando)

def obtener_rutas_archivos(ubicacionCarpeta):
    ruta = os.path.abspath(ubicacionCarpeta)
    pathArchivos = gb(ruta + '/*.jpg')
    return pathArchivos


def preEtiquetadoImagenes(listaubicaArchivos):
    model = CLIPModel.from_pretrained("openai/clip-vit-large-patch14")
    processor = CLIPProcessor.from_pretrained("openai/clip-vit-large-patch14")
    etiquetado = {}
    for imag in listaubicaArchivos:
        df = {}
        url = imag
        image = Image.open(url)
        inputs = processor(text=["deforestation", "construction","jungle","river","boat","machinery","builds","clouds"],images=image, return_tensors="pt", padding=True)
        imagen = imag.split("/")[-1] +"_"+ imag.split("/")[-2]
        outputs = model(**inputs)
        logits_per_image = outputs.logits_per_image # this is the image-text similarity score
        probs = logits_per_image.softmax(dim=1) # we can take the softmax to get the label probabilities
        Etiqueta = ["deforestation", "construction","jungle","river","boat","machinery","builds","clouds"]
        Probabilidad = probs[0]*100
        df['Etiqueta'] = Etiqueta
        lista = list(Probabilidad.detach().numpy())
        df['Probabilidad'] = list(map(str, lista))
        etiquetado[imagen] = df
    with open("archivo-salida.json", "w") as outfile:
        json.dump(etiquetado, outfile)
        
def detect_objects_in_video(video_path, output_path):
    convertir_video_a_imagen(video_path)
    rutas = obtener_rutas_archivos(f"Imagenes/{video_path}/")
    preEtiquetadoImagenes(rutas)

"