Detectando imagens "ruins" na linha de comando

Detectando imagens "ruins" na linha de comando

Restaurei um grande número de imagens de formatação acidental de um disco.

Um grande número dessas imagens está corrompido, ou seja. 100% verde ou 70% cinza. Infelizmente, todos eles ainda têm dados EXIF, então não posso usá-los imediatamente para descobrir quais imagens estão ruins.

Exemplo de imagem ruim

Responder1

Usando Imagemagick

Este fornece o número total de pixels na imagem:

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

e este fornece o nome da cor dominante e o número de pixels:

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

Exemplo:

$ 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 pode ser a base para escrever um script de shell, mas não é bom para verificar muitos arquivos, pois o Imagemagick é incrivelmente flexível, mas lento

Usando oitava

O script Octave a seguir pode ser chamado diretamente da linha de comando. Seus argumentos devem ser dois nomes de diretório errdire baddiruma lista de arquivos de imagem. Arquivos para os quais a biblioteca LibMagick++ usada pelo Octave fornece um aviso ou erro são movidos para errdir; arquivos para os quais os últimos 25% das linhas são da mesma cor são movidos para baddir; outros arquivos permanecem intactos. Um relatório conciso é fornecido na saída padrão.

Se você deseja apenas o relatório, sem mover arquivos, não forneça nomes de diretórios como dois primeiros 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

Você precisa ter o Octave instalado para que isso funcione. Copie o acima em um arquivo chamado badimage, torne-o executável chmod +x badimagee teste o script como ./badimage *.jpg: você verá uma lista de arquivos com seus status (bom, ruim, erro).

Observe a saída e possivelmente altere o limite dentro do script para um comportamento mais agressivo (limite inferior) ou mais conservador (limite superior). Você pode testá-lo pelo tempo que quiser, pois ele não move nem altera arquivos se você fornecer apenas nomes de arquivos de imagem como argumentos.

Quando estiver satisfeito com os resultados, crie dois diretórios mkdir errpics badpics. Em seguida, chame o script como ./badimage errpics badpics *.jpg. Dessa forma, o script move seus arquivos nos diretórios descritos acima.

CAVEAT: depois de usar este script, certifique-se de verificar uma boa amostra de imagens marcadas como ruins ou com erros antes de excluí-las!

O algoritmo que detecta imagens ruins é confiável para fotos, mas não necessariamente para desenhos, logotipos, diagramas, gráficos, que podem conter amplas áreas legítimas da mesma cor. Os arquivos com erros podem estar ruins ou danificados do ponto de vista do LibMagick++, mas podem ser bem legíveis nos visualizadores de imagens geralmente mais tolerantes.

informação relacionada