Який найкращий алгоритм зменшення масштабу зображення (якісно)?


80

Я хочу з'ясувати, який алгоритм найкращий, який можна використовувати для зменшення розміру растрової картинки. З найкращим я маю на увазі той, який дає найкращі результати. Я знаю про бікубік, але чи є щось краще ще? Наприклад, я чув від деяких людей, що Adobe Lightroom має якийсь власний алгоритм, який дає кращі результати, ніж стандартний бікубічний, який я використовував. На жаль, я хотів би сам використовувати цей алгоритм у своєму програмному забезпеченні, тому ретельно охороняється комерційна таємниця Adobe не допоможе.

Додано:

Я перевірив Paint.NET і, на мій подив, здається, що Super Sampling краще, ніж bicubic при зменшенні розміру зображення. Це змушує мене задуматись, чи не потрібні взагалі алгоритми інтерполяції.

Це також нагадало мені алгоритм, який я сам "винайшов", але ніколи не реалізовував. Я припускаю, що у нього також є назва (оскільки щось таке тривіальне не може бути ідеєю лише мене), але я не зміг знайти його серед популярних. Супер вибірка була найближчою.

Ідея полягає в наступному - для кожного пікселя в цільовому зображенні підрахуйте, де він знаходився б на вихідному зображенні. Ймовірно, він би накладав один або кілька інших пікселів. Тоді можна було б розрахувати площі та кольори цих пікселів. Потім, щоб отримати колір цільового пікселя, можна просто обчислити середнє значення цих кольорів, додавши їх площі як "ваги". Отже, якби цільовий піксель покривав 1/3 жовтого вихідного пікселя та 1/4 зеленого вихідного пікселя, я отримав би (1/3 * жовтий + 1/4 * зелений) / (1/3 + 1/4).

Це, природно, було б досить обчислювально, але воно повинно бути якомога ближче до ідеалу, ні?

Чи існує назва цього алгоритму?


1
Ви описуєте, як саме працює наддискретизація. Це не краще, ніж bicubic, оскільки bicubic займає більше пікселів від вихідного зображення в обліковому записі.
homm

2
Я голосую за те, щоб знову відкрити це дуже давнє запитання, оскільки воно є гарним. "Виглядає найкраще" звучить суб'єктивно, але люди, які вивчають це, оцінюють його в достатній мірі, щоб отримати хороші, несуб'єктивні та консенсусні відповіді.
tom10

@ tom10 - Ну, чесно кажучи, я думаю, що варіант Lanczos вже досить хороший для більшості цілей.
Вількс

Відповіді:


76

На жаль, я не можу знайти посилання на оригінальне опитування, але, оскільки голлівудські кінематографісти переходили від фільму до цифрових зображень, цього питання виникало багато, тому хтось (можливо, SMPTE, можливо, ASC) зібрав купу професійних кінематографістів і показав їм кадри які були масштабовані за допомогою різних алгоритмів. Результати полягали в тому, що для цих професіоналів, які дивляться на величезні кінофільми, було консенсусом, що Мітчелл (також відомий як високоякісний Catmull-Rom) є найкращим для масштабування, а sinc - найкращим для зменшення. Але sinc - це теоретичний фільтр, який йде до нескінченності і, отже, не може бути повністю реалізований, тому я не знаю, що вони насправді мали на увазі під словом "sinc". Ймовірно, це стосується усіченої версії sinc. Ланцошє одним з декількох практичних варіантів sinc, який намагається покращити його просто скорочення, і є, мабуть, найкращим вибором за замовчуванням для масштабування нерухомих зображень. Але, як зазвичай, це залежить від зображення та того, що ви хочете: зменшення малюнка лінії для збереження ліній - це, наприклад, випадок, коли ви можете віддати перевагу акценту на збереженні країв, які були б небажаними при зменшенні фотографії квітів.

Є хороший приклад результатів різних алгоритмів у Кембриджі в кольорі .

Люди fxguide зібрали багато інформації про алгоритми масштабування (поряд з багатьма іншими матеріалами про композицію та іншу обробку зображень), на яку варто поглянути. Вони також включають тестові зображення, які можуть бути корисними для проведення власних тестів.

Тепер ImageMagick має великий посібник із передискретизації фільтрів, якщо ви дійсно хочете в нього потрапити.

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


Я хотів би зазначити, що фільтр sinc реалізований без усічення на сигналах з кінцевим ступенем. Якщо припустити, що за межами відомого нам регіону всі вибірки дорівнюють нулю, зайві доданки у формулі інтерполяції Віттейкера – Шеннона зникають, і ми отримуємо кінцеву суму. Це правильна інтерпретація вихідних даних, хоча вона, ймовірно, неправильна (світ не є чорним за межами нашого поля зору). Цей фільтр як і раніше не можна використовувати для аудіо та відео в реальному часі, оскільки він не є причинно-наслідковим, але для використання у зображеннях не має значення.
Тім Сегін,

Я запізнююсь на вечірку, але ось моя думка щодо цього. Існує лише один правильний спосіб зменшити зображення, і це комбінація двох методів. 1) зменшіть масштаб на x2, продовжуйте зменшувати масштаб, поки наступне зменшення не стане меншим за розмір цілі. При кожному масштабуванні кожен новий піксель = в середньому 4 старі пікселі, отже це максимальна кількість інформації, що зберігається. 2) з останнього кроку, зменшеного на 2, зменшіть масштаб до цільового розміру за допомогою BILINEAR інтерполяції. Це важливо, оскільки билинеарний сигнал взагалі не викликає дзвону. 3) (бонус) виконайте масштабування в лінійному просторі (дегама-> зменшення масштабу-> регама).
Alex

@Alex не існує універсально "належного" способу зменшення зображення, оскільки не існує універсального визначення того, що є "важливим" у зображенні, і його слід зберігати в порівнянні з тим, що є "неважливим", і його можна відкинути. Ваш алгоритм може бути чудовим для деяких зображень, але він перетворить чорно-білий малюнок ліній у світло-сіру розмитість.
Old Pro

Ну так, я говорив про фотографії, але я думаю, що це також буде краще обробляти штрихові малюнки. Ви точно знаєте, що дзвону не буде. Мовляв, нуль. Жоден фільтр не може відповідати цьому. Але так, для певних зображень краще робити найближчого сусіда або щось інше, що є більш доречним, ніж універсальний алгоритм.
Алекс

@Alex: більше того, ви не розглядаєте ефекти фільтрації, які має такий алгоритм, як "sinc". Багато знімків, зроблених цифровою камерою, матимуть шум (досить рівномірно розподілений), особливо коли ви робите знімки з високою ізоляцією. Це можна відфільтрувати при зменшенні масштабу зображення.
Невизначено

21

Існує дискретизація Ланцоша, яка є повільнішою, ніж бікубічна, але дає зображення вищої якості.


Чи вже існує реалізація в .NET для цього? Врятував би мені час. :)
Вількс

@ Vilx- github.com/dlemstra/Magick.NET я ним користувався, і він дуже добре працює для ланцо, використовуючи (MagickImage image = new MagickImage (path)) {image.FilterType = ImageMagick.FilterType.Lanczos; image.Resize (145,145); // Збереження зображення як tiff image.Write ("c: /workbackup/jay_Lanczos.png"); }
jayant singh

15

(Бі-) лінійна та (бі-) кубічна передискретизація є не просто потворною, але жахливо некоректною при зменшенні масштабу на коефіцієнт менше 1/2. Вони призведуть до дуже поганих псевдонімів, схожих на те, що ви отримаєте, якщо зменшите показник у 1/2 рази, а потім скористайтеся зниженням вибірки найближчого сусіда.

Особисто я б порекомендував (для області) вибірки усереднення для більшості завдань з зменшення вибірки. Це дуже просто, швидко і майже оптимально. Гауссова передискретизація (з радіусом, вибраним пропорційним зворотній величині коефіцієнта, наприклад, радіус 5 для зменшення дискретизації на 1/5), може дати кращі результати з трохи більшими накладними обчисленнями, і це більш математично обґрунтовано.

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


3
Радіус - це все важливо. Причина того, що бікубік так часто не справляється зі зменшенням масштабу, полягає в тому, що радіус не відрегульований, а для зменшення використовується той самий радіус, який працює для збільшення. Це просто не працює, і в крайньому випадку перетворюється на гірше, ніж найближчий сусід. Якщо радіус правильно відрегульовано, це повинно принести кращі результати, ніж усереднення по площі.
Mark Ransom

4
Для кубічного фільтра абсолютно не властиво нічого, що обмежує його до 4-х зразків, формула чудово працює, якщо розширити його та розділити на суму ваг. Насправді Catmull-Rom схожий на Lanczos-2 і може бути відрегульований таким, що майже ідентичний.
Марк Ренсом

1
@MarkRansom: Визначення кубічного фільтра - це наближення кривої кубічним поліномом, визначеним однозначно будь-якими 4 точками на кривій.
R .. GitHub СТОП ДОПОМОГАЙ ЛЕД

2
Це може бути так, але математиці все одно. Спробуй колись і подивись.
Марк Ренсом

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

7

Я бачив статтю про Slashdot про Швейне різьблення деякий час тому, можливо, варто заглянути.

Вирізання шва - це алгоритм зміни розміру зображення, розроблений Шай Авіданом та Аріелем Шаміром. Цей алгоритм змінює розміри зображення не за допомогою масштабування або обрізання, а за допомогою розумного видалення пікселів із (або додавання пікселів до зображення), які не мають особливого значення.


Я це бачив. Це було не зовсім те, що я мав на увазі, але це, звичайно, хороша ідея, щоб вивчити! Дякую! Чи є цей алгоритм десь загальнодоступним?
Вількс

3
Насправді, різьблення швів перенацілює, а не масштабує. Вони дають різні результати. @Vilx: так, тут є плагін GIMP: liquidrescale.wikidot.com
Can Berk Güder

Ось реалізація dotNET: blogs.msdn.com/mswanson/archive/2007/10/23/…
Craz

Зауважте, що алгоритм перенацілювання різьбового шва пробився до Photoshop 4, я не здивуюся, якщо цей алгоритм має великі патентні тягарі.
Лассе В. Карлсен,

3
Вирізання швів - це та сама ідея, що і масштабування рідини Gimp та масштабування вмісту Photoshop CS4. Це не для масштабування, це для зміни пропорції зображення, не роблячи його розтягнутим.
mk12

4

Описаний вами алгоритм називається лінійною інтерполяцією і є одним із найшвидших алгоритмів, але не найкращий на зображеннях.


Крім того, що OP враховує просторове розташування субпікселів так, як це робить субпіксельний шрифт. Це може бути справді крутим способом отримати трохи роздільної здатності, але також може призвести до дивних ефектів зображення, а також залежить від заданої архітектури субпікселів.
Адам Толлі

Ні, лінійна інтерполяція є різновидом алгоритмів згортки. Описано у справжній супервибірці.
homm

@AdamTolley Я сильно сумніваюся, що субпіксельний АА для звичайних зображень виглядав би навіть прийнятно. Це працює з текстом, тому що є лише два кольори, і навіть наявність іншого кольору, крім білого, є проблемою
RecursiveExceptionException

1
@itzJanuary, я думаю, було б чудово, коли б межові кольори відповідали схемі субпікселів, але це траплялося лише іноді, що в кращому випадку суперечливо корисно і в гіршому порушує основну частоту вибірки пікселів, створюючи дивні перцептивні артефакти
Адам Толлі,

2

Чи існує назва цього алгоритму?

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

Він також може бути використаний для створення проміжного растрового зображення, яке згодом використовується двокубічною інтерполяцією, щоб уникнути згладжування при зменшенні дискретизації більш ніж на 1/2.


-1

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


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