Gestión y Aumento de Datos para el Algoritmo de Detección de Texto DB

El procesamiento eficiente de datos es un pilar fundamental en el entrenamiento de modelos de detección de texto como DB (Differential Binarization). Este proceso abarca desde la carga inicial de imágenes hasta la generación de mapas de probabilidad y umbrales necesarios para el aprendizaje supervisado.

Estructura del Cargador de Datos

En las implementaciones de DB basadas en PyTorch, se suele extender la clase DataLoader para integrra configuraciones dinámicas. Este cargador no solo gestiona la paralelización mediante hilos (num_workers), sino que también orquestra la canalización de transformaciones.

class DBDataLoader(torch.utils.data.DataLoader):
    """
    Cargador de datos personalizado para DB que hereda de PyTorch.
    Gestiona la configuración de lotes y la inicialización de procesos.
    """
    def __init__(self, dataset, config_params, is_training=True):
        self.dataset = dataset
        self.batch_size = config_params.get('batch_size', 16)
        self.workers = config_params.get('num_workers', 4)
        self.shuffle = is_training
        
        super(DBDataLoader, self).__init__(
            dataset=self.dataset,
            batch_size=self.batch_size,
            num_workers=self.workers,
            shuffle=self.shuffle,
            pin_memory=True,
            drop_last=is_training
        )

La lógica de aumento de datos se ejecuta dentro del método __getitem__ del conjunto de datos, donde se aplican de forma secuencial múltiples transformaciones sobre la imagen y sus polígonos correspondientes.

Módulos de Transformación y Aumento

Aumento Geométrico (AugmentDetectionData)

Este módulo utiliza librerías como imgaug para realizar operaciones como volteos horizontales, rotaciones afines y cambios de escala. Es crucial que tanto la imagen como los puntos clave (vértices del texto) se transformen de manera sincronizada.

def aplicar_aumentos(self, item_data):
    frame = item_data['image']
    poligonos = item_data['polys']
    
    # Definición de secuencia de aumentos
    seq = iaa.Sequential([
        iaa.Fliplr(0.5),
        iaa.Affine(rotate=(-10, 10)),
        iaa.Resize((0.5, 3.0))
    ])
    
    # Asegurar que la transformación sea determinística para imagen y puntos
    det_seq = seq.to_deterministic()
    item_data['image'] = det_seq.augment_image(frame)
    item_data['polys'] = self.transformar_puntos(det_seq, poligonos, frame.shape)
    
    return item_data

Recorte Estratégico (RandomCropData)

A diferencia de un recorte aleatorio simple, en la detección de texto se busca evitar la partición de instancias de texto. El algoritmo identifica regiones vacías (ejes sin presencia de texto) para determinar los límites del recorte, garantizando que al menos algunos objetos permanezcan íntegros.

Generación de Mapas para DB

El algoritmo DB requiere objetivos específicos: el mapa de segmentación (GT) y el mapa de umbrales (Threshold Map).

Mapa de Segmentación y Encogimiento

Utilizando el algoritmo de Vatti, los polígonos originales se encogen para crear el mapa de probabilidad básico. Esto ayuda al modelo a separar instancias de texto muy cercanas.

def generar_mapa_segmentacion(self, img_shape, poligonos, ratio=0.4):
    h, w = img_shape[:2]
    mapa_gt = np.zeros((h, w), dtype=np.float32)
    for poly in poligonos:
        # Calcular distancia de encogimiento basada en área y perímetro
        area = self.calcular_area_poligono(poly)
        perimetro = self.calcular_perimetro_poligono(poly)
        distancia = area * (1 - ratio**2) / perimetro
        
        # Realizar offset con pyclipper
        pco = pyclipper.PyclipperOffset()
        pco.AddPath(poly, pyclipper.JT_ROUND, pyclipper.ET_CLOSEDPOLYGON)
        poly_encogido = pco.Execute(-distancia)
        
        if len(poly_encogido) > 0:
            cv2.fillPoly(mapa_gt, [np.array(poly_encogido[0]).astype(np.int32)], 1)
    return mapa_gt

Mapa de Umbrales (Border Map)

Este mapa se genera expandiendo los polígonos y calculando la distancia de cada píxel hacia los bordes del polígono oirginal. El resultado es un gradiente que permite al modelo aprender dónde establecer el umbral de binarización de forma adaptativa.

  • Distancia de expansión: Se calcula de forma similar al encogimiento.
  • Normalización: Los valores de distancia se normalizan entre un rango mínimo y máximo predefinido (usualmente 0.3 a 0.7).

Normalización y Filtrado

Finalmente, los datos se normalizan restando la media de color y escalando los valores de los píxeles al rango [0, 1]. El módulo FilterKeys elimina metadatos innecesarios para el entrenamiento (como rutas de archivos o etiquetas temporales), dejando solo los tensores requeridos por la red neuronal.

def normalizar_tensor(self, payload):
    img = payload['image'].astype(np.float32)
    # Media estándar de ImageNet o del dataset específico
    media = np.array([122.68, 116.67, 104.01])
    img -= media
    img /= 255.0
    # Reordenar a formato [Canal, Alto, Ancho]
    payload['image'] = torch.from_numpy(img).permute(2, 0, 1)
    return payload

Etiquetas: PyTorch Computer Vision Text Detection DBNet Image Augmentation

Publicado el 7-25 22:41