Detectar imágenes "malas" desde la línea de comando

Detectar imágenes "malas" desde la línea de comando

He restaurado una gran cantidad de imágenes a partir de un formateo accidental de un disco.

Una gran cantidad de estas imágenes están corruptas, es decir. 100% verde o 70% gris. Desafortunadamente, todos todavía tienen datos EXIF, por lo que no puedo usarlos para determinar qué imágenes son malas.

Ejemplo de mala imagen

Respuesta1

Usando Imagemagick

Este te da el número total de píxeles de la imagen:

identify -verbose  ~/www/pictures/ISTI-F.jpg | sed -n '/.*Pixels: /s///p'

y este te da el nombre del color dominante y el número de píxeles:

convert ~/www/pictures/ISTI-F.jpg -format "%c" histogram:info: | sort -nr -t: | head -1 | sed 's/\(.*\):.*#\(......\).*/\2\1/'

Ejemplo:

$ identify -verbose ISTI-F.jpg | sed -n '/.*Pixels: /s///p'
1920000
$ convert ISTI-F.jpg -format "%c" histogram:info: | sort -nr -t: | head -1 | sed 's/\(.*\):.*#\(......\).*/\2\1/'
FFFFFF   1667711

Esta puede ser la base para escribir un script de shell, pero no es bueno para verificar muchos archivos, ya que Imagemagick es increíblemente flexible, pero lento.

Usando Octava

El siguiente script de Octave se puede llamar directamente desde la línea de comando. Sus argumentos deben ser dos nombres de directorio errdiry baddiruna lista de archivos de imágenes. Los archivos para los cuales la biblioteca LibMagick++ utilizada por Octave da una advertencia o error se mueven a errdir; los archivos en los que el último 25% de las filas son del mismo color se mueven a baddir; otros archivos quedan intactos. Se proporciona un informe conciso sobre la producción estándar.

Si desea solo el informe, sin mover archivos, no proporcione nombres de directorio como los dos primeros argumentos.

#!/usr/bin/octave -qf

threshold = 0.25;

usage = "Usage is: badfiles <file...> OR badfiles <errdir> <baddir> <file...>\n";
files\n";
assert(nargin>0, usage);
dryrun = isfile(argv{1});
if !dryrun
  errdir = argv{1};
  baddir = argv{2};
  assert(isfolder(errdir) && isfolder(baddir) && isfile(argv{3}), usage);
endif

start = 1 + 2*(!dryrun);
for fname = argv()(start:end)'
  q = [];
  f = fname{};

  warning error
  try
    q = imread(fname{});
  catch err
  end_try_catch
  warning on

  if isempty(q)
    printf("error\t");
    dryrun || movefile(f, errdir);
  else
    qt = all(q == q(end,1,:) ,2);
    qtt = squeeze(all(qt, 3));
    r = 1 - find(qtt==0, 1, 'last') / size(q, 1);
    if (r > threshold)
      printf("bad--%02d\t", ceil(100*r));
      dryrun || movefile(f, baddir);
    else
      printf("good-%02d\t", ceil(100*r));
    endif
  endif

  disp(f);
endfor

Necesitas tener Octave instalado para que esto funcione. Copie lo anterior en un archivo llamado badimage, hágalo ejecutable chmod +x badimagey pruebe el script como ./badimage *.jpg: verá una lista de archivos con su estado (bueno, malo, error).

Mire el resultado y posiblemente cambie el umbral dentro del script para lograr un comportamiento más agresivo (umbral más bajo) o más conservador (umbral más alto). Puede probarlo todo el tiempo que desee, ya que no mueve ni cambia archivos si solo proporciona nombres de archivos de imágenes como argumentos.

Una vez que esté satisfecho con los resultados, cree dos directorios mkdir errpics badpics. Luego llame al script como ./badimage errpics badpics *.jpg. De esta manera, el script mueve sus archivos en los directorios como se describe anteriormente.

ADVERTENCIA: después de usar este script, asegúrese de revisar una buena muestra de imágenes marcadas como malas o con errores antes de eliminarlas.

El algoritmo que detecta malas imágenes es fiable para las fotografías, pero no necesariamente para dibujos, logotipos, diagramas o gráficos, que pueden contener amplias áreas legítimas del mismo color. Los archivos con errores pueden ser malos o estar dañados desde el punto de vista de LibMagick++, pero pueden leerse bien en los visualizadores de imágenes generalmente más indulgentes.

información relacionada