martes, 11 de junio de 2024

Automatización de Marcas de Agua en Imágenes y Clasificación Basada en Luminosidad

Por Julio Alberto Lascano

En esta entrada, exploraremos dos scripts útiles para la manipulación de imágenes: uno para aplicar una marca de agua y otro para clasificar imágenes según sus características. Ambos scripts son herramientas valiosas para fotógrafos, diseñadores gráficos y cualquier persona que trabaje con imágenes digitales. La combinación de Bash y Python permite crear una solución eficiente y automatizada para procesar múltiples imágenes a la vez.

Introducción a las Librerías cv2 (OpenCV) y NumPy

En el mundo de la programación y la informática, existen herramientas poderosas que nos permiten realizar tareas complejas de manera más sencilla y eficiente. Hoy, vamos a explorar dos de estas herramientas: cv2 (también conocida como OpenCV) y NumPy.

¿Qué es cv2 (OpenCV)?

OpenCV (Open Source Computer Vision Library) es una biblioteca de software de visión por computadora. Esto significa que proporciona una gran cantidad de funciones que permiten a las computadoras "ver" y procesar imágenes y videos. Con OpenCV, puedes realizar tareas como:

  • Detectar y reconocer caras en imágenes.
  • Seguir objetos en movimiento en videos.
  • Aplicar filtros y efectos a imágenes.
  • Medir distancias y tamaños en fotografías.
Detectar y reconocer caras en imágenes


La librería cv2 es simplemente el módulo de Python para usar OpenCV. Es una herramienta muy potente en el campo de la inteligencia artificial y la visión por computadora.

¿Qué es NumPy?

NumPy (Numerical Python) es una biblioteca para el lenguaje de programación Python que permite realizar operaciones matemáticas y estadísticas de manera eficiente. Es especialmente útil cuando trabajamos con grandes cantidades de datos, ya que está diseñada para realizar cálculos rápidos y precisos. Con NumPy, puedes:

  • Crear y manipular arreglos (matrices) de datos.
  • Realizar operaciones matemáticas complejas.
  • Procesar datos de manera eficiente.
  • Integrar con otras librerías científicas y de análisis de datos.

NumPy es la base para muchas otras librerías científicas y de aprendizaje automático en Python, como SciPy, Pandas y TensorFlow.

NumPy - Software de análisis numérico

¿Por qué Usar cv2 y NumPy Juntas?

La combinación de cv2 y NumPy es muy común en proyectos de visión por computadora. NumPy se utiliza para manejar y procesar los datos de las imágenes (que son, en esencia, matrices de números) de manera eficiente, mientras que cv2 proporciona las herramientas específicas para la visión por computadora. Juntas, estas librerías permiten desarrollar aplicaciones poderosas que pueden analizar y manipular imágenes y videos de maneras muy avanzadas.

Descripción de los Scripts

aplicar_marca_agua.sh

Este script de Bash automatiza el proceso de aplicar una marca de agua a todas las imágenes en un directorio especificado. Utiliza las potentes herramientas de ImageMagick para realizar esta tarea de manera eficiente. A continuación, se detalla el flujo de trabajo del script:

  • Verificación de comandos de ImageMagick: Se asegura de que los comandos 'identify', 'convert' y 'composite' estén disponibles.
  • Definición de parámetros: Se especifican las rutas de las marcas de agua (blanca y negra), el directorio de imágenes a procesar, el factor de escala para el tamaño de la marca de agua y el directorio de salida.
  • Verificación de parámetros y rutas: Se comprueba que todos los parámetros necesarios se han proporcionado y que las rutas de las marcas de agua y el directorio de imágenes existen. Si el directorio de salida no existe, se crea automáticamente.
  • Bucle para procesar cada imagen: Itera sobre cada archivo en el directorio de imágenes, verificando si es una imagen válida.
  • Obtención del tamaño de la imagen: Utiliza el comando 'identify' para obtener el tamaño de la imagen en píxeles.
  • Cálculo del tamaño de la marca de agua: Calcula el tamaño de la marca de agua proporcional al tamaño de la imagen original.
  • Redimensionamiento de la marca de agua: Redimensiona la marca de agua al tamaño calculado.
  • Aplicación de la marca de agua: Aplica la marca de agua al pie de la imagen con un margen inferior centrado.
  • Eliminación de archivos temporales: Elimina el archivo temporal de la marca de agua redimensionada después de aplicarla a la imagen.

clasificar_imagen_v5.py

Este script de Python se utiliza para determinar el color (blanco o negro) más adecuado para la marca de agua en función de la luminosidad de la región inferior de la imagen. Utiliza las bibliotecas OpenCV (cv2) y NumPy, que son herramientas poderosas para la visión por computadora y la manipulación de matrices numéricas.

  • OpenCV (cv2): Es una biblioteca popular de código abierto para visión por computadora y procesamiento de imágenes. Proporciona una amplia gama de funciones para manipular y analizar imágenes.
  • NumPy: Es una biblioteca fundamental en Python para la computación científica y numérica. Proporciona un objeto de matriz multidimensional y una variedad de funciones para operar sobre estas matrices.

Cómo Funciona

El script de Python realiza una segmentación basada en color en la región inferior de la imagen para identificar ciertos tonos o rangos de color. Luego, calcula la luminosidad promedio de esta región y decide si la marca de agua debe ser blanca o negra basándose en la luminosidad calculada.

Pasos del Proceso

  • Carga de la imagen: El script carga la imagen proporcionada como argumento.
  • Definición de la región inferior: Se define una región en la parte inferior de la imagen, que es donde se aplicará la marca de agua.
  • Segmentación basada en color: Se segmenta la región inferior para identificar ciertos tonos de color.
  • Cálculo de la luminosidad promedio: Se calcula la luminosidad promedio de la región inferior y de la región donde se detecta un color específico.
  • Decisión del color de la marca de agua: Basándose en la luminosidad promedio y la presencia de un color específico, el script decide si la marca de agua debe ser blanca o negra.

Este enfoque asegura que la marca de agua se vea correctamente en la imagen, proporcionando un buen contraste independientemente de la luminosidad de la región donde se aplica.

Descripción del Script: aplicar_marca_agua.sh

El script aplicar_marca_agua.sh automatiza el proceso de aplicar una marca de agua a todas las imágenes en un directorio especificado. A continuación, se explica paso a paso lo que hace el script:

  1. Verificación de comandos de ImageMagick: Se verifica si los comandos 'identify', 'convert' y 'composite' están disponibles.
  2. Definición de parámetros:
    • MARCA_DE_AGUA_BLANCA: Ruta de la imagen que se utilizará como marca de agua blanca.
    • MARCA_DE_AGUA_NEGRA: Ruta de la imagen que se utilizará como marca de agua negra.
    • DIRECTORIO_IMAGENES: Directorio que contiene las imágenes a las que se aplicará la marca de agua.
    • FACTOR_ESCALA: Factor de escala que determina el tamaño proporcional de la marca de agua en relación con el ancho de la imagen original.
    • DIRECTORIO_SALIDA: Directorio donde se guardarán las imágenes con la marca de agua aplicada.
  3. Verificación de parámetros y rutas:
    • Se verifica que todos los parámetros necesarios se han proporcionado.
    • Se verifica que las rutas de las marcas de agua y el directorio de imágenes existen.
    • Si el directorio de salida no existe, se crea automáticamente.
  4. Bucle para procesar cada imagen: Se utiliza un bucle 'for' para iterar sobre cada archivo en el directorio de imágenes especificado.
  5. Obtención del tamaño de la imagen: Se utiliza el comando 'identify' para obtener el tamaño de la imagen en píxeles.
  6. Cálculo del tamaño de la marca de agua: Se calcula el tamaño de la marca de agua proporcional al tamaño de la imagen original, utilizando el factor de escala definido.
  7. Redimensionamiento de la marca de agua: Se redimensiona la marca de agua al tamaño calculado y se elimina cualquier perfil de color incrustado para evitar advertencias.
  8. Aplicación de la marca de agua: Se aplica la marca de agua al pie de la imagen con un margen inferior centrado utilizando el comando 'composite'.
  9. Eliminación de archivos temporales: Se elimina el archivo temporal de la marca de agua redimensionada después de aplicarla a la imagen.
 
#!/bin/bash

# --------------------------------------------------------------------------------------------------------------------------------------
# File: aplicar_marca_agua.sh
# By Julio Alberto Lascano http://drcalambre.blogspot.com/
#________          _________        .__                ___.                  
#\______ \_______  \_   ___ \_____  |  | _____    _____\_ |_________   ____  
# |    |  \_  __ \ /    \  \/\__  \ |  | \__  \  /     \| __ \_  __ \_/ __ \ 
# |    `   \  | \/ \     \____/ __ \|  |__/ __ \|  Y Y  \ \_\ \  | \/\  ___/ 
#/_______  /__|     \______  (____  /____(____  /__|_|  /___  /__|    \___  >
#        \/                \/     \/          \/      \/    \/            \/ 
# --------------------------------------------------------------------------------------------------------------------------------------
# Last modified:2024-06-10
# --------------------------------------------------------------------------------------------------------------------------------------
# Descripción del script: aplicar_marca_agua.sh
# --------------------------------------------------------------------------------------------------------------------------------------
# Uso: aplicar_marca_agua.sh -b [marca_agua_blanca] -n [marca_agua_negra] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]
# --------------------------------------------------------------------------------------------------------------------------------------
# Este script automatiza el proceso de aplicar una marca de agua a todas las imágenes en un directorio especificado.
# A continuación se explica paso a paso lo que hace el script:
#
# 1. Verificación de comandos de ImageMagick:
#    - Se verifica si los comandos 'identify', 'convert' y 'composite' están disponibles.
#
# 2. Definición de parámetros:
#    - MARCA_DE_AGUA_BLANCA: Ruta de la imagen que se utilizará como marca de agua blanca.
#    - MARCA_DE_AGUA_NEGRA: Ruta de la imagen que se utilizará como marca de agua negra.
#    - DIRECTORIO_IMAGENES: Directorio que contiene las imágenes a las que se aplicará la marca de agua.
#    - FACTOR_ESCALA: Factor de escala que determina el tamaño proporcional de la marca de agua en relación con el ancho de la imagen original.
#    - DIRECTORIO_SALIDA: Directorio donde se guardarán las imágenes con la marca de agua aplicada.
#
# 3. Verificación de parámetros y rutas:
#    - Se verifica que todos los parámetros necesarios se han proporcionado.
#    - Se verifica que las rutas de las marcas de agua y el directorio de imágenes existen.
#    - Si el directorio de salida no existe, se crea automáticamente.
#
# 4. Bucle para procesar cada imagen:
#    - Se utiliza un bucle 'for' para iterar sobre cada archivo en el directorio de imágenes especificado.
#    - Se verifica si el archivo actual en el bucle es un archivo regular utilizando la condición 'if [ -f "$IMAGEN" ]'.
#
# 5. Obtención del tamaño de la imagen:
#    - Se utiliza el comando 'identify' para obtener el tamaño de la imagen en píxeles.
#
# 6. Cálculo del tamaño de la marca de agua:
#    - Se calcula el tamaño de la marca de agua proporcional al tamaño de la imagen original, utilizando el factor de escala definido.
#
# 7. Redimensionamiento de la marca de agua:
#    - Se redimensiona la marca de agua al tamaño calculado y se elimina cualquier perfil de color incrustado para evitar advertencias.
#
# 8. Aplicación de la marca de agua:
#    - Se aplica la marca de agua al pie de la imagen con un margen inferior centrado utilizando el comando 'composite'.
#
# 9. Eliminación de archivos temporales:
#    - Se elimina el archivo temporal de la marca de agua redimensionada después de aplicarla a la imagen.
# --------------------------------------------------------------------------------------------------------------------------------------


# Verificación de comandos de ImageMagick
if ! command -v identify &> /dev/null || ! command -v convert &> /dev/null || ! command -v composite &> /dev/null
then
    echo "ImageMagick no está instalado o los comandos necesarios no están disponibles. Por favor, instálalo antes de ejecutar este script."
    exit 1
fi

# Manejo de errores
# Se añade manejo de errores para asegurar que el script se detenga si ocurre algún problema. 
# Se hace con: set -e lo que hace que el script termine si algún comando falla.

set -e

# Uso: aplicar_marca_agua.sh -b [marca_agua_blanca] -n [marca_agua_negra] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]
while getopts "b:n:d:s:o:" opt; do
    case ${opt} in
        b ) MARCA_DE_AGUA_BLANCA=$OPTARG ;;
        n ) MARCA_DE_AGUA_NEGRA=$OPTARG ;;
        d ) DIRECTORIO_IMAGENES=$OPTARG ;;
        s ) FACTOR_ESCALA=$OPTARG ;;
        o ) DIRECTORIO_SALIDA=$OPTARG ;;
        \? ) echo "Uso: aplicar_marca_agua.sh -b [marca_agua_blanca] -n [marca_agua_negra] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]"
             exit 1 ;;
    esac
done

# Verificación de parámetros
if [ -z "$MARCA_DE_AGUA_BLANCA" ] || [ -z "$MARCA_DE_AGUA_NEGRA" ] || [ -z "$DIRECTORIO_IMAGENES" ] || [ -z "$FACTOR_ESCALA" ] || [ -z "$DIRECTORIO_SALIDA" ]; then
    echo ""
    echo "Uso: aplicar_marca_agua.sh -b [marca_agua_blanca] -n [marca_agua_negra] -d [directorio_imagenes] -s [factor_escala] -o [directorio_salida]"
    echo ""
    echo "Todos los parámetros (-b, -n, -d, -s, -o) son obligatorios."
    echo "-------------------------------------------------------------------------------------------------------------"
    echo "Factor de escala para el tamaño de la marca de agua -s [factor_escala]"
    echo "Por ejemplo: -s 0.15 , un factor de escala del 15% es adecuado para la fotografia de paisajes."
    echo "-------------------------------------------------------------------------------------------------------------"
    exit 1
fi

# Verificación de la existencia de las rutas de las marcas de agua
if [ ! -f "$MARCA_DE_AGUA_BLANCA" ]; then
    echo "La ruta de la marca de agua blanca ($MARCA_DE_AGUA_BLANCA) no existe."
    exit 1
fi

if [ ! -f "$MARCA_DE_AGUA_NEGRA" ]; then
    echo "La ruta de la marca de agua negra ($MARCA_DE_AGUA_NEGRA) no existe."
    exit 1
fi

# Verificación de la existencia del directorio de imágenes
if [ ! -d "$DIRECTORIO_IMAGENES" ]; then
    echo "El directorio de imágenes ($DIRECTORIO_IMAGENES) no existe."
    exit 1
fi

# Verificación de la existencia del directorio de salida
if [ ! -d "$DIRECTORIO_SALIDA" ]; then
    echo "El directorio de salida ($DIRECTORIO_SALIDA) no existe. Creando el directorio..."
    mkdir -p "$DIRECTORIO_SALIDA"
fi

# Obtener el directorio del script Bash
SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"

# Ruta del script Python relativo al directorio del script Bash
SCRIPT_PATH="$SCRIPT_DIR/scripts/clasificar_imagen_v5.py"

# Verificar que el script Python exista
if [[ ! -f "$SCRIPT_PATH" ]]; then
  echo "El script $SCRIPT_PATH no existe. Verifica la ruta."
  exit 1
fi

contador=0
tiempo_inicio=$(date +%s)

# Aplicar marca de agua a cada imagen en el directorio
for IMAGEN in "$DIRECTORIO_IMAGENES"/*; do
    if [ -f "$IMAGEN" ] && file --mime-type "$IMAGEN" | grep -q -E "image/(png|gif|jpeg|jpg)"; then
        nombre_imagen=$(basename "$IMAGEN")
        
        # La expresión ${nombre_imagen##*.} utiliza un mecanismo de expansión de parámetros en el shell 
        # de Unix para extraer la extensión de un nombre de archivo.
        # Significa eliminar todo hasta el último punto en el nombre del archivo, y devolver lo que queda.
        
        
        extension_imagen="${nombre_imagen##*.}"
        
        # Obtener el tamaño de la imagen (ancho x altura)
        tamano_imagen=$(identify -format "%wx%h" "$IMAGEN")
        
        # Separar el ancho y la altura
        ancho_imagen=$(echo "$tamano_imagen" | cut -d'x' -f 1)
        altura_imagen=$(echo "$tamano_imagen" | cut -d'x' -f 2)
        
        # Calcular el tamaño de la marca de agua proporcional al tamaño de la imagen
        tamano_marca=$(echo "$ancho_imagen * $FACTOR_ESCALA" | bc)
        
        # Llamada al script de Python para determinar el color (blanco o negro)
        resultados=$(python "$SCRIPT_PATH" "$DIRECTORIO_IMAGENES$nombre_imagen" "$FACTOR_ESCALA")
        
        # Imprimir los resultados
        
        # Leer los resultados separados
		read -r resultado_color luminosidad <<< "$resultados"
		        
        # Imprimir el resultado capturado para depuración
        
		echo "-------------------------------"
		echo "Color marca de agua: $resultado_color"
		echo "Luminosidad: $luminosidad"
		echo "-------------------------------"
		echo "Aplicando marca de agua a $DIRECTORIO_IMAGENES$nombre_imagen -> $DIRECTORIO_SALIDA${nombre_imagen%.*}_wm.$extension_imagen"

        # Seleccionar la marca de agua según el color determinado
        case "$resultado_color" in
            "blanco")
                MARCA_DE_AGUA=$MARCA_DE_AGUA_BLANCA
                ;;
            "negro")
                MARCA_DE_AGUA=$MARCA_DE_AGUA_NEGRA
                ;;
            *)
                echo "Color desconocido: $color. Usando la marca de agua blanca por defecto."
                MARCA_DE_AGUA=$MARCA_DE_AGUA_BLANCA
                ;;
        esac
        
     
        # Redimensionar la marca de agua al tamaño calculado y eliminar el perfil de color
        # Crear un archivo temporal
        marca_de_agua_redimensionada=$(mktemp)
        convert "$MARCA_DE_AGUA" -resize "${tamano_marca}x${tamano_marca}" -strip "$marca_de_agua_redimensionada"
        
        # Aplicar marca de agua al pie de la imagen con margen inferior centrado
        composite -dissolve 50% -gravity South -geometry +0+50   "$marca_de_agua_redimensionada" "$IMAGEN" "$DIRECTORIO_SALIDA/${nombre_imagen%.*}_wm.$extension_imagen"
        
        # Eliminar el archivo temporal de la marca de agua redimensionada
        rm "$marca_de_agua_redimensionada"
        
        # Incrementar el contador por cada imagen procesada
		contador=$((contador + 1))
        
    fi
done

# Calcular el tiempo total transcurrido
tiempo_fin=$(date +%s)
tiempo_total=$((tiempo_fin - tiempo_inicio))

# Convertir tiempo total a formato hh:mm:ss
horas=$((tiempo_total / 3600))
minutos=$(( (tiempo_total % 3600) / 60 ))
segundos=$((tiempo_total % 60))

# Mostrar el total de imágenes procesadas y el tiempo que tomó
echo "Total de imágenes procesadas: $contador"
# Formatear la salida
printf "Tiempo total transcurrido: %02d:%02d:%02d\n" $horas $minutos $segundos


Descripción del Script: clasificar_imagen_v5.py

El script clasificar_imagen_v5.py carga la imagen y define la región inferior de la misma para segmentación basada en color y análisis de luminosidad promedio. A continuación, se detallan las funcionalidades del script:

  1. Segmentación basada en color en la región inferior:
    • Identifica ciertos tonos o rangos de color en la región inferior de la imagen.
  2. Cálculo de la luminosidad promedio:
    • Calcula la luminosidad promedio de la región inferior y de la región donde se detecta un color específico.
    • Basándose en la luminosidad promedio y la presencia de color específico, decide si la marca de agua debe ser blanca o negra.
  3. Bibliotecas utilizadas:
    • cv2 (OpenCV): Biblioteca popular para la visión por computadora y el procesamiento de imágenes.
    • NumPy: Biblioteca fundamental para computación científica y numérica en Python.

El script imprime el resultado (blanco o negro) junto con la luminosidad promedio de la región inferior.

 
#!/usr/bin/env python

# --------------------------------------------------------------------------------------------------------------------------------------
# File: clasificar_imagen_v5.py
# By Julio Alberto Lascano http://drcalambre.blogspot.com/
#________          _________        .__                ___.                  
#\______ \_______  \_   ___ \_____  |  | _____    _____\_ |_________   ____  
# |    |  \_  __ \ /    \  \/\__  \ |  | \__  \  /     \| __ \_  __ \_/ __ \ 
# |    `   \  | \/ \     \____/ __ \|  |__/ __ \|  Y Y  \ \_\ \  | \/\  ___/ 
#/_______  /__|     \______  (____  /____(____  /__|_|  /___  /__|    \___  >
#        \/                \/     \/          \/      \/    \/            \/ 
# --------------------------------------------------------------------------------------------------------------------------------------
# Last modified:2024-05-30
# --------------------------------------------------------------------------------------------------------------------------------------
# Descripción del script: clasificar_imagen_v5.py
# Carga la imagen y define la región inferior de la misma.
# --------------------------------------------------------------------------------------------------------------------------------------
# Segmentación basada en color en la región inferior y luminosidad promedio de la región inferior:
# --------------------------------------------------------------------------------------------------------------------------------------
# Realiza una segmentación basada en color en la región inferior para identificar ciertos tonos o rangos de color.
# Calcula la luminosidad promedio de la región inferior y de la región donde se detecta un color específico.
# Basándose en la luminosidad promedio y la presencia de color específico, decide si la marca de agua debe ser blanca o negra.
# Imprime el resultado (blanco o negro) junto con la luminosidad promedio de la región inferior.
# --------------------------------------------------------------------------------------------------------------------------------------
# cv2
# --------------------------------------------------------------------------------------------------------------------------------------
# La biblioteca cv2, o OpenCV (Open Source Computer Vision Library), es una biblioteca popular de código abierto diseñada para 
# la visión por computadora y el procesamiento de imágenes. Ofrece una amplia gama de funciones y algoritmos que permiten realizar 
# una variedad de tareas relacionadas con el procesamiento de imágenes y la visión por computadora.
# --------------------------------------------------------------------------------------------------------------------------------------
# NumPy
# --------------------------------------------------------------------------------------------------------------------------------------
# NumPy es una biblioteca fundamental en Python para computación científica y numérica. Proporciona un objeto de matriz 
# multidimensional, junto con una variedad de funciones para operar en estas matrices.
# NumPy se utiliza específicamente para calcular la media (np.mean) y la desviación estándar (np.std) de la luminosidad del color detectado
# en la región inferior de la imagen. Estas estadísticas se utilizan luego para ajustar dinámicamente el valor del umbral para decidir si 
# aplicar una marca de agua blanca o negra.
# --------------------------------------------------------------------------------------------------------------------------------------


import sys
import cv2
import numpy as np

# Función para calcular la luminosidad promedio de una región de la imagen
def calcular_luminosidad_promedio(region):
    luminosidad = cv2.mean(region)[0]
    return luminosidad

def main():
    # Verificar que se proporcionen los argumentos necesarios
    if len(sys.argv) < 3:
        print("Uso: clasificar_imagen_v5.py  ")
        sys.exit(1)

    # Ruta de la imagen proporcionada como argumento
    ruta_imagen = sys.argv[1]

    # Definir el factor de escala proporcionado como argumento
    try:
        FACTOR_ESCALA = float(sys.argv[2])
    except ValueError:
        print("El factor de escala debe ser un número.")
        sys.exit(1)

    # Cargar la imagen
    img = cv2.imread(ruta_imagen)

    # Verificar si la imagen se cargó correctamente
    if img is None:
        print("Error al cargar la imagen. Verifique la ruta y el formato del archivo.")
        sys.exit(1)

    # Obtener dimensiones de la imagen
    alto, ancho, _ = img.shape

    # Calcular el tamaño del cuadrante a analizar
    #
    # FACTOR_ESCALA se usa para determinar el tamaño del cuadrante a analizar en la imagen. Ese cuadrante es el que ocupara la marca de agua.
    # alto_cuadrante y ancho_cuadrante se calculan como una fracción de las dimensiones de la imagen.
    #
    # Región Inferior Centrada:
    # Las coordenadas (y_inicio, x_inicio) se calculan para centrar el cuadrante horizontalmente y posicionarlo en la parte inferior de la imagen.
    #
    # Segmentación y Análisis:
    # La segmentación basada en color y el cálculo de luminosidad promedio se realizan en esta región inferior centrada.
    # Esto asegura que el análisis se realice en la parte de la imagen donde estará la marca de agua, considerando su posición centrada y tamaño relativo basado en el factor de escala.

    alto_cuadrante = int(alto * FACTOR_ESCALA * 2)
    ancho_cuadrante = int(ancho * FACTOR_ESCALA * 2)

    # Definir las coordenadas del cuadrante inferior centrado
    y_inicio = alto - alto_cuadrante  # Inicio del cuadrante inferior
    x_inicio = (ancho - ancho_cuadrante) // 2  # Centrar horizontalmente

    # Extraer el cuadrante inferior centrado de la imagen
    region_inferior = img[y_inicio:, x_inicio:x_inicio + ancho_cuadrante]

    # Segmentación basada en color en la región inferior de la imagen
    region_inferior_hsv = cv2.cvtColor(region_inferior, cv2.COLOR_BGR2HSV)
    lower_color = (0, 50, 50)  # Define el rango inferior de color HSV
    upper_color = (20, 255, 255)  # Define el rango superior de color HSV
    mask_color = cv2.inRange(region_inferior_hsv, lower_color, upper_color)

    # Calcular la luminosidad promedio del color detectado en la región inferior
    luminosidad_color = calcular_luminosidad_promedio(mask_color)

    # Calcular estadísticas sobre la luminosidad promedio del color
    luminosidad_color_mean = np.mean(luminosidad_color)
    luminosidad_color_std = np.std(luminosidad_color)

    # Ajustar dinámicamente el valor de umbral_color
    umbral_color = luminosidad_color_mean + 2 * luminosidad_color_std  # Por ejemplo, media + 2 * desviación estándar

    # Calcular la luminosidad promedio de la región inferior
    luminosidad_region_inferior = calcular_luminosidad_promedio(region_inferior)

    # Decidir el color de la marca de agua basado en la luminosidad promedio y el umbral dinámico
    
    # El valor de 127 se utiliza como umbral de luminosidad. Este valor se elige arbitrariamente como punto de corte 
    # para distinguir entre regiones relativamente oscuras y regiones relativamente claras en la imagen. 
    # Un valor de 127 corresponde aproximadamente a la mitad del rango de 0 a 255 en el espacio de color de escala de grises, 
    # donde 0 representa el negro absoluto y 255 representa el blanco absoluto.
    # Si la luminosidad promedio de la región inferior es menor o igual a 127, se considera que esta región es relativamente 
    # oscura. En este caso, se asume que una marca de agua blanca sería más visible y contrastaría mejor con el fondo oscuro. 
    # Por lo tanto, se decide aplicar una marca de agua blanca.
    #
    # La variable luminosidad_color_mean contiene la luminosidad promedio del color detectado en la región inferior de la imagen. 
    # Esta región se segmenta en función de ciertos tonos o rangos de color específicos, como se especifica en el código.
    #
    # Umbral dinámicamente ajustado (umbral_color): En lugar de utilizar un umbral estático, como en el caso 
    # de luminosidad_region_inferior <= 127, aquí se calcula y utiliza un umbral dinámico basado en las estadísticas de la 
    # luminosidad del color detectado en la región inferior. Este umbral puede ajustarse según las características específicas de 
    # la imagen en términos de iluminación, tonos de color, etc.
    #
    # Decisión de aplicar marca de agua blanca o negra: Si la luminosidad promedio del color detectado en la región inferior es menor 
    # o igual al umbral dinámicamente ajustado (umbral_color), se considera que esta región es relativamente oscura en términos de color. 
    # En este caso, se asume que una marca de agua blanca sería más visible y contrastaría mejor con el fondo oscuro. 
    # Por lo tanto, se decide aplicar una marca de agua blanca.
    #
    # Adaptabilidad del umbral dinámico: Al calcular el umbral dinámicamente en función de las estadísticas de la luminosidad del color 
    # detectado, se mejora la adaptabilidad del proceso de decisión a diferentes condiciones de iluminación y variaciones en los tonos de
    # color de la imagen.
    
    if luminosidad_region_inferior <= 127 and luminosidad_color_mean <= umbral_color:
        resultado_color = "blanco"
    else:
        resultado_color = "negro"

    # Imprimir el resultado y la luminosidad
    print(resultado_color, luminosidad_region_inferior)

if __name__ == "__main__":
    main()


Uso de la Desviación Estándar

La desviación estándar mide qué tan dispersos están los valores de luminosidad. Si todos los valores son muy similares, la desviación estándar será baja; si hay mucha variación, será alta.

Se calcula un "umbral" dinámico usando la desviación estándar. Este umbral es una combinación de la luminosidad promedio del color y la desviación estándar de esa luminosidad.

Conclusión

La combinación de estos dos scripts proporciona una solución robusta y eficiente para aplicar marcas de agua a un gran número de imágenes de manera automatizada. Utilizando Bash y Python, se puede asegurar que cada imagen reciba una marca de agua que se ajuste perfectamente a sus características específicas, mejorando así la presentación y protección de sus imágenes digitales.

Dependencias

- **Imagemagick**:Paquete de software para manipular y editar imágenes.

- **bc**: es una calculadora de precisión arbitraria en Unix-like.

- **OpenCV (`cv2`)**: una popular biblioteca de código abierto diseñada para visión por computadora y procesamiento de imágenes.

- **NumPy**: Biblioteca fundamental en Python para computación científica y numérica. Se utiliza para calcular estadísticas como la media y la desviación estándar de la luminosidad para la detección de color en la región inferior de la imagen.

 
antix1@antix1:~ sudo apt-get install imagemagick bc
antix1@antix1:~ sudo apt-get install python3-opencv
antix1@antix1:~ sudo apt-get install python3-numpy

Los escript se pueden descargar desde mi repositorio en GitHub:

https://github.com/DrCalambre/watermark 

Entradas relacionadas tambien en este blog:

Como crear una Marca de Agua con GIMP.



No hay comentarios.:

Publicar un comentario

Déjanos tu comentario!