Я восстановил огромное количество изображений после случайного форматирования диска.
Большое количество этих изображений повреждено, т. е. 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++, но быть хорошо читаемыми на обычно более снисходительных визуализаторах изображений.