Обнаружение «плохих» изображений из командной строки

Обнаружение «плохих» изображений из командной строки

Я восстановил огромное количество изображений после случайного форматирования диска.

Большое количество этих изображений повреждено, т. е. 100% зеленого или 70% серого. К сожалению, у всех них все еще есть данные EXIF, поэтому я не могу использовать их, чтобы сходу определить, какие изображения плохие.

Пример плохого изображения

решение1

Использование Imagemagick

Этот код показывает общее количество пикселей в изображении:

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

а этот даст вам название доминирующего цвета и количество пикселей:

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

Пример:

$ 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

Это может быть основой для написания скрипта оболочки, но он не подходит для проверки большого количества файлов, так как Imagemagick невероятно гибок, но медлителен.

Использование Октавы

Следующий скрипт Octave можно вызвать непосредственно из командной строки. Его аргументами должны быть два имени каталога errdirи baddirи список файлов изображений. Файлы, для которых библиотека LibMagick++, используемая Octave, выдает предупреждение или ошибку, перемещаются в errdir; файлы, для которых последние 25% строк имеют одинаковый цвет, перемещаются в baddir; остальные файлы остаются нетронутыми. На стандартный вывод выводится краткий отчет.

Если вам нужен только отчет без перемещения файлов, не указывайте имена каталогов в качестве первых двух аргументов.

#!/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

Для работы вам необходимо установить Octave. Скопируйте вышеприведенное в файл с именем badimage, сделайте его исполняемым с помощью chmod +x badimageи протестируйте скрипт следующим образом ./badimage *.jpg: вы увидите список файлов с их статусом (хороший, плохой, ошибка).

Посмотрите на вывод и, возможно, измените порог внутри скрипта на более агрессивное (более низкий порог) или более консервативное (более высокий порог) поведение. Вы можете тестировать его столько, сколько захотите, поскольку он не перемещает и не изменяет файлы, если вы указываете в качестве аргументов только имена файлов изображений.

Как только вы будете удовлетворены результатами, создайте два каталога mkdir errpics badpics. Затем вызовите скрипт как ./badimage errpics badpics *.jpg. Таким образом скрипт переместит ваши файлы в каталоги, как описано выше.

ПРЕДОСТЕРЕЖЕНИЕ: после использования этого скрипта обязательно проверьте хорошую выборку изображений, помеченных как плохие или с ошибками, прежде чем удалять их!

Алгоритм, который обнаруживает плохие изображения, надежен для фотографий, но не обязательно для рисунков, логотипов, диаграмм, графиков, которые могут содержать широкие законные области одного цвета. Ошибочные файлы могут быть плохими или поврежденными с точки зрения LibMagick++, но быть хорошо читаемыми на обычно более снисходительных визуализаторах изображений.

Связанный контент