Necesito que utilices los siguientes tres códigos para que funcionen perfectamente y tengan una estructura más adecuada para cumplir con el siguiente objetivo: Objetivo 1. Identificación objetos de interés en videos: El objetivo 1 consiste en identificar de manera automatizada objetos de interés en videos capturados por sensores FLIR y Aeronaves Remotamente Pilotadas, en los cuales se evidencian situaciones de afectación ambiental a la Amazonía colombiana. Se requiere entonces una librería open source creada en python que genere un archivo con el resultado del análisis y recuadros de los objetos identificados. La librería debe tener un método que reciba como parámetro la ruta del video y del archivo que contiene el resultado del análisis: detect_objects_in_video(video_path, output_path)
El método debe generar un archivo con el resultado del análisis, en la ruta dada. El formato de este archivo debe ser CSV. Cada fila debe tener la siguiente estructura: <id>, <object_type>, <time>, <coordinates_text>
<id>:= “Identificador del objeto encontrado. Puede ser un número o cadena única que servirá para identificar el archivo con el recuadro generado.”
<object_type>:= “Tipo de objeto identificado. Puede tener los siguientes: VEHICULO, CONSTRUCCIÓN, VIA, OTROS“
<time>: = ”Tiempo en el video de aparición del objeto, en el formato HH:MM:SS (hora militar)”
<coordinates_text>: = ”Texto de coordenadas que aparece en la imagen mientras se ve el objeto”
Adicionalmente, dentro de la carpeta destino se debe crear un carpeta con nombre IMG, que incluirá los recuadros de los objetos identificados. Las imágenes con el recuadro deben tener como nombre el id del objeto reportado en el archivo de resultado.
Primer código y el más importante: “
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)

“
El resultado que me entregues debe estar indentado donde sea pertintente