Сортування зображень за співвідношенням сторін


13

Я намагаюся вибрати декілька художніх зображень, щоб відповідати деяким новим кадрам. Я хотів би мати можливість сортувати ці зображення за близькістю до певного співвідношення сторін, а потім переглядати їх у зменшуваному порядку близькості через щось на кшталт feh.

Чи є якийсь славний однорядковий вираз Unix? В іншому випадку кілька десятків рядків Python повинні очистити це.


3
Ви можете потягнути співвідношення сторін з допомогою ImageMagick, наприклад identify -format "%[fx:w/h]:%M\n" *.jpg. Я не знаю, як легко сортувати за близькістю до довільного значення. sortсхоже, не підтримує таке сортування.
NN

Ну, в основному, ви хочете перетворити ці числа в цілочисельну метрику відстані, а потім можете передати їх на сортування -n. Здається, ви насправді можете виконати всю математику з ImageMagick.
дероберт

Відповіді:


8

Використовуючи коментар ImageMagick NN в якості ведучого, виявляється, ви можете дозволити йому робити довільні обчислення як частину свого -formatрезультату. Отже, один із можливих способів:

identify -format "%[fx:round(100000*abs((4/3)-(w/h)))]:%M\n" *.jpg | \
    sort -n -k1 -t:

слід робити те, що ти хочеш. Зауважте, що 4/3 є постійним, бажаним співвідношенням сторін. Звичайно, це можна побачити як результат попереднього identify(у відповідності "найближчим до цього зображення").

Для пояснення ми беремо очевидну різницю між бажаним і фактичним співвідношенням сторін. Потім множення на велику кількість і округлення. Помножувати і кругляти відбувається тому, що сортування обробляє лише цілі числа, а не раціональні.

редагувати

Виявляється, sortце робить раціональні, а не просто цілі числа. Її навіть вказано в єдиній специфікації Unix (v4). Отже, ви можете позбутися цього вирішення:

identify -format "%[fx:abs((4/3)-(w/h))]:%M\n" *.jpg | \
    sort -n -k1 -t:

Де ви знайшли документацію щодо опції -формату Identify? Я нічого не бачив на сторінці чоловіка і витратив досить багато часу, намагаючись зрозуміти прокляту річ :).
terdon

О, і в моїй системі ваша команда, здається, не працює. Я потрапляю 33333:cover.jpgтам, де cover.jpg - 500x500.
terdon

2
@terdon добре, це тому, що він має співвідношення 1/1, а не 4/3. 4 / 3-1 = 1/3 = .333…. Просто змініть це значення 4/3 на потрібне співвідношення (яке звучить як його 1/1). Документи розміщуються на imagemagick.org/script/fx.php, як правило, заплутаним. Зайняв мене час, щоб їх також знайти.
дероберт

Дякуємо за посилання Щодо решти, я був ідіот. У моїй тестовій папці був лише один jpg (решта - png), тому, оскільки я побачив лише один рядок виводу, я припустив, що це бажаний результат, і для того, щоб визначити, було вказано, що зображення має 4/3 співвідношення сторін. Це те, що я намагаюся думати ввечері в понеділок ... +1 для елегантного рішення.
terdon

Гарна відповідь! Чи є спосіб додати якусь мітку до імен файлів усіх зображень, що не відповідають бажаному співвідношенню?
Менталіст

3

Ну, найпростіший спосіб зробити це було б використовувати ImageMagick . Він повинен бути у сховищах вашого дистрибутива Linux, для систем на базі debian запускайте:

sudo apt-get install imagemagick

Одна з програм набору ImageMagick полягає в тому identify, що це буде надрукувати характеристики списку вхідних файлів зображень. Поєднавши його sort, ви отримаєте список зображень, відсортованих за розміром (ви можете змінити png за будь-яким розширенням, яке ви маєте:

identify *png | sort -gk 3

Якщо вам потрібне співвідношення сторін, а не лише розмір, спробуйте щось подібне:

  1. Простий варіант, припускаючи, що назви ваших зображень не мають пробілів :

    identify *png *jpg *gif | \
    gawk '{split($3,sizes,"x"); print $1,sizes[1]/sizes[2]}' | \
    sed 's/\[.\]//' | sort -gk 3
    

    Команда gawk розбиває 3-е поле (розмір зображення, який має формат LxH) в масив "розміри", після чого друкує 1-е поле (назва зображення) та результат ділення довжини зображення на його висоту. sedКоманда просто прикрашає висновок і sortкоманда сортує результат по співвідношенню розміру зображення.

  2. Більш складний, він може мати справу з пробілами у назвах файлів:

    find . \( -iname  "*png" -o -iname "*jpg" -o -iname "*gif" \) -exec identify {} \; |\
    perl -ne '/(.+?)\s+[A-Z]{3}\s+(\d+)x(\d+)/; print "$1 ", $2/$3, "\n"' | \
    sort -gk 2
    

    Тут ми використовуємо findдля виявлення цікавлять нас файлів і запускаємо identifyкоманду, а потім проводимо її вихід через невеликий сценарій PERL. Регулярний вираз шукає три великі літери ( [A-Z]{3}), які мають бути форматом зображення. Як тільки ми це виявили, легко визначити назву зображення та розміри зображення.

    Я не використовую тут gawk, оскільки наявність пробілів у назвах вхідних файлів буде заплутати номери полів. Нарешті, сценарій роздрукує ім'я зображення та результат поділу довжини / висоти, яке ми sortчислимо.

Якщо просто переглядати наявні співвідношення сторін недостатньо, якщо у вас є принаймні одне зображення з потрібним співвідношенням сторін, просто використовуйте grep, щоб витягти зображення, співвідношення яких найближче:

identify *png *jpg *gif | \
gawk '{split($3,sizes,"x"); print $1,sizes[1]/sizes[2]}' |\
sed 's/\[.\]//' | sort -gk 3 | grep -C 10 GOOD_IMAGE.jpg

2

Ви можете обчислити різницю кожного співвідношення сторін із посиланням. Схоже, відповідь Дероберта, але простіше:

ref=4/3
identify -format "%[fx:abs(w/h - $ref)] %M\n" *.jpg | sort -n -k1

Хм, мабуть, це щось робить раціонально. Я був під враженням, що це не було ...
derobert

2

Співвідношення сторін - це лише число, тож ви можете переглядати зображення відповідно до їх назв, якщо ім'я має префікс співвідношення сторін. Створення символьних зв’язків із попередньо відкладеним співвідношенням сторін дозволяє переглядати зображення, відсортовані за співвідношенням сторін.

Наступні глядачі працюють як очікували. ( feh не вперед / назад, навіть для реальних зображень - у моїй системі)

  • комікс
  • eog (Око Гнома / Переглядач зображень)
  • gwenview

picd='/media/dat_ext4/pictures/jpg/misc'
srtd="$picd/ar-sort"   # directory to hold "sorted" symbolic links
mkdir -p "$srtd"              

find "$picd" -maxdepth 1 -type f -name "*" -print0 | 
  while IFS= read -d $'\0' -r file ; do
    [[ $(file -ib "$file") != image* ]] && continue  # skip non-image files
    ar="$(identify -format "%[fx:w/h]" "$file")"  
    slink="$(printf '%s/%06.4f %s' "$srtd" "$ar" "$(basename "$file")")"
    # make symbolic link in 'ar-sort' directory
    ln -s "$file" "$slink"  
    echo "$slink" 
  done 

Зайдіть у ar-sortкаталог і просто перегляньте з будь-якої початкової точки (співвідношення сторін), яка вас цікавить.

Назви символічних посилань виглядають приблизно так:

0.6732 Gold Bars.jpg
0.7242 Light Bulb.jpg
0.8022 Escher - Waterfall.jpg
1.3696 Old Typewriter.jpg
1.6000 King Tut.jpg

Примітка: якщо ваші параметри локалі використовують інший знак десяткової точки, ніж крапка, це не працюватиме. Легко виправити , хоча: stackoverflow.com/questions/12845997 / ...
Jobjörn Folkesson

1

Моя звичайна міркування - використовувати метрику відстані в квадраті помилки, де б я не чув слова "ступінь близькості". Однозначно можна використовувати абсолютні значення, і це було б швидше. Сценарій приймає за аргумент ідеальне співвідношення сторін, обробляє всі файли * .jpg у поточному каталозі та виводить їх, відсортованих у порядку зростання, що розходяться від ідеального співвідношення.

head вилучає кінцевий символ кінця рядка, вставлений ImageMagick.

Сценарій містить команду gawk, яка встановлює роздільник вихідного поля на малоймовірний символ, обчислює різницю у квадраті та виводить назад назву файлу різниці пар | Сортування виконується, і непотрібна інформація (квадратична різниця співвідношення сторін) знижується cut.

#!/bin/sh
if [ x"$1" = "x" ] ; then
  echo "Usage: $0 TargetAspectRatio" >&2
  exit 2
fi
ASPECT_CMD="BEGIN{OFS=\"|\";}\
{\
print (\$1-$1)^2, \$2;\
}"
identify -format "%[fx:w/h]:%M\n" *.jpg | head -n-1 | gawk -F":" "$ASPECT_CMD" | sort -k1 -t"|" | cut -f2 -d"|"

Зверніть увагу, що він використовує квадратичну відстань та обчислення в межах gawk / awk :) (Спасибі @NN за початковий ярлик)
Мисливець на оленів

Не могли б ви додати пояснення сценарію до своєї відповіді? Зробило б це краще.
NN
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.