5.12. Двійкове порогування

Багато конвеєрів обробки зображень зводяться до запитання про кожен піксель: чи знаходиться ця яскравість у діапазоні, що означає «передній план»? Чи достатньо цей колір близький до червоного, щоб бути маркером, який відстежує застосунок? Чи є цей піксель частиною набору кандидатів, на який має дивитися наступний етап конвеєра? Порогування — це операція, яка перетворює ці запитання на двійкову відповідь у кожній позиції — увімкнено, якщо піксель відповідає умові, вимкнено, якщо ні — і зводить усе зображення до маски, з якою може працювати решта конвеєра.

5.12.1. Метод binary

Метод binary() виконує цю класифікацію для кожного пікселя за один виклик. Він приймає список діапазонів порогів — умов, яким піксель може відповідати, щоб вважатися «увімкненим» — і перезаписує зображення так, щоб кожен піксель, що відповідає хоча б одному діапазону, набував максимального значення для формату, а кожен піксель, що не відповідає, — нуля. Результатом є двійкова маска, яку решта конвеєра може використовувати безпосередньо.

У найпростішій формі список порогів містить один діапазон, і виклик повертає маску пікселів у цьому діапазоні:

img.binary([(120, 255)])

Саме форма списку робить binary потужним. Конвеєр, що хоче відстежувати два кольорові маркери або діапазон яскравості плюс окремий пік насиченості, передає обидва діапазони в одному списку і отримує єдину вихідну маску, що охоплює всі збіги.

A horizontal grayscale gradient at the top labelled "input -- pixel values from 0 to 255". Below it, an inclusive threshold range from lo to hi is marked with brackets along the gradient, enclosing the range of brightness values that count as matches. A binary output bar at the bottom shows white inside the lo-to-hi range and black outside it.

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

5.12.2. Кортеж для відтінків сірого

Для зображення у відтінках сірого кожен елемент у списку порогів є двоелементним кортежем (lo, hi), що описує включний діапазон яскравості. Пікселі зі значеннями між lo та hi (включно) є збігами; все за межами цього діапазону — ні. Типові патерни прості:

  • (0, 60) відповідає темним пікселям — усьому від чорного до темно-сірого.

  • (180, 255) відповідає яскравим пікселям — усьому від світло-сірого до білого.

  • (100, 160) відповідає пікселям середньо-сірого — смузі в середині діапазону яскравості.

Порядок двох значень усередині кортежу не має значення; метод міняє їх місцями внутрішньо, якщо lo більше за hi, тому (60, 0) працює так само, як (0, 60).

5.12.3. Кортеж LAB для кольору

Для зображення RGB565 кожен елемент є шестиелементним кортежем (l_lo, l_hi, a_lo, a_hi, b_lo, b_hi), що описує включний діапазон у кольоровому просторі LAB, а не безпосередньо в червоному, зеленому та синьому. Пороги — L (яскравість), A (хроматична вісь від зеленого до червоного) і B (хроматична вісь від синього до жовтого) — кожен порівнюється зі значенням пікселя у відповідному каналі.

Причина використання LAB замість безпосереднього порогування RGB полягає у властивості, навколо якої проектувався кольоровий простір LAB: LAB відокремлює яскравість від хроматики. Два пікселі, що показують однаковий колір, але при різній яскравості, матимуть різні значення L, але приблизно однакові значення A і B. Це розділення дозволяє діапазонам порогів описувати колір за його положенням на осях A і B, а діапазон L залишати широким для прийняття цього кольору при будь-якій яскравості від тіні до світла. Поріг на основі RGB не може цього зробити — будь-яка зміна освітлення одночасно зміщує всі три значення R, G, B, і трекер, побудований на RGB-порогах, ламається при першій появі хмари перед сонцем.

Практичний патерн: обирайте діапазони A і B, що описують колір, який відстежує застосунок, і залишайте діапазон L широким — часто (0, 100) для прийняття будь-якої яскравості — якщо тільки застосунок спеціально не потребує порогування також і за яскравістю.

Для кортежів з менш ніж шістьма значеннями відсутні компоненти за замовчуванням мають максимальний діапазон (відсутні обмеження для цієї осі). Двоелементний кортеж (l_lo, l_hi) у списку порогів RGB565 тому порогує лише за яскравістю і відповідає будь-якому кольору.

Примітка

Дійсно широкий діапазон L має пастку на нижньому кінці. Коли яскравість наближається до нуля, кожен колір зближується з чорним, а значення A і B стискаються до нуля і починають домінуватися шумом — тому темні пікселі можуть потрапляти в діапазони A і B та виявлятися як цільовий колір. Якщо чорні ділянки сцени засвічуються як збіги, підвищіть l_lo, доки вони не зникнуть.

5.12.4. Прапорці

Три іменовані аргументи керують виводом:

  • invert=True інвертує результат. Кожен піксель, який би збігся, стає нулем, а кожен піксель, який би був нулем, набуває максимального значення. Корисно, коли природний спосіб описати передній план — це те, чим він не є.

  • zero=True змінює режим роботи: відповідні пікселі обнуляються, а невідповідні зберігають свої початкові значення. Використовуйте це, коли мета полягає в стиранні відповідних пікселів із зображення, а не у зведенні зображення до їхньої двійкової маски.

  • to_bitmap=True повертає результат як BINARY зображення замість перезапису існуючого формату джерела. Результат з одним бітом на піксель — це саме те, що безпосередньо приймають наступні аргументи маски, і перетворення часто знижує тиск на пам’ять від використання маски повного формату.

Маска та ROI дотримуються тієї ж угоди, що й решта поверхні: прямокутник roi обмежує операцію підобластю, а зображення mask обмежує її довільним шаблоном позицій.

5.12.5. За замовчуванням — на місці

Як і арифметичні операції, binary за замовчуванням виконується на місці: пікселі вихідного зображення перезаписуються двійковим результатом, і початкові значення втрачаються після виклику. Форма to_bitmap=True є альтернативою, коли джерело потрібно зберегти, а вихід має бути щойно виділеним BINARY зображенням. Форма copy=True також приймається для результату в тому самому форматі на новому буфері.