5.18. Гістограми та статистика

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

Відправною точкою для майже кожного вимірювання є гістограма.

5.18.1. Гістограма

Гістограма зображення – це підрахунок кількості пікселів, що мають кожне можливе значення яскравості. Для зображення у відтінках сірого це список лічильників, індексованих значеннями від 0 до 255. Для кольорового зображення – три такі списки, по одному на канал.

get_histogram() обчислює одну:

h = img.get_histogram()

Повернутий об’єкт є результатом histogram, який надає доступ до списків бінів по каналах і кілька запитів вищого рівня. Лічильники бінів нормалізовані так, що їхня сума дорівнює 1.0 – гістограма описує профіль розподілу, а не абсолютну кількість пікселів, що робить вимірювання порівнянними для зображень різних розмірів.

Для зображень у відтінках сірого гістограма має один канал бінів, доступний як h.bins() (або еквівалентно h[0]). Для зображень RGB565 гістограма обчислюється у колірному просторі LAB, представленому на сторінці бінарної порогової обробки, з трьома каналами бінів, доступними як h.l_bins(), h.a_bins(), h.b_bins() (або h[0], h[1], h[2]). LAB – той самий вибір, що використовують методи порогової обробки та відстеження; гістограми узгоджуються з порогами щодо простору, в якому вимірюється колір.

5.18.2. Біни та кількість бінів

За замовчуванням гістограма має один бін на кожне можливе значення пікселя – 256 бінів для 8-бітного каналу. Іноді це більша роздільна здатність, ніж потребує застосунок. Класифікатор, якому важливий лише грубий профіль розподілу, може краще працювати з меншою кількістю бінів – 32 або навіть 8 – що як пришвидшує роботу, так і дає чистіший результат при наявності шуму. Ключове слово bins (та відповідні l_bins, a_bins, b_bins для кольору) задає кількість:

h = img.get_histogram(bins=32)

Область інтересу (ROI) та обмеження за порогом працюють так само, як і в кожному іншому методі вимірювання. Передайте roi, щоб обмежити гістограму прямокутником пікселів; передайте список thresholds, щоб включати лише пікселі, що відповідають цим діапазонам. Форма з порогом дозволяє виконати операцію «обчислити гістограму лише відповідних пікселів» одним викликом – поширений шаблон, коли застосунок хоче охарактеризувати текстуру вже знайденої ділянки, не обходячи пікселі самостійно.

A grayscale histogram drawn as a row of bars across the brightness range 0 to 255. The distribution has two peaks -- a smaller dark peak and a larger bright peak -- separated by a clear valley. Three vertical lines are overlaid: the Otsu threshold in the valley, the mean shifted toward the larger bright peak, and the median further right where cumulative pixel count reaches one-half.

Гістограма у відтінках сірого з трьома накладеними зведеними вимірюваннями: поріг Отсу (межа, яка найкраще розділяє темний та світлий кластери), середнє та медіана. Кожне вимірювання говорить дещо різне про один і той самий розподіл.

5.18.3. Статистика

Гістограма – це опис поширеності кожного значення; статистика – це числові зведення, отримані з неї. Об’єкт statistics, повернутий get_statistics(), містить стандартний набір:

  • mean – середнє арифметичне значень пікселів.

  • median – значення, нижче якого знаходиться половина пікселів.

  • mode – найпоширеніше окреме значення.

  • stdev – стандартне відхилення, міра розкиду навколо середнього.

  • min та max – яскравіше та темніше значення пікселів із присутніх.

  • lq та uq – нижня та верхня квартильні межі.

Для зображення RGB565 відповідні форми по каналах (l_mean, a_median, b_mode тощо) надають ті самі вимірювання канал за каналом.

Більшість цих чисел використовуються у конкретних контекстах. mean та stdev разом дають оцінку шуму: сцена, яка має бути рівномірною, має малий stdev, тоді як шумний датчик дає тій самій сцені більший stdev. min та max дають контраст зображення: чим ближчі вони, тим рівніша сцена; чим далі одне від одного, тим більший динамічний діапазон є у алгоритму. median є надійним центром, коли розподіл має викиди (кілька дуже яскравих пікселів не зміщують медіану так, як вони зміщують середнє). mode – найпоширеніше одиничне значення, корисне для знаходження рівня тла зображення, фон якого займає більшість пікселів.

get_statistics() виконує прохід гістограми внутрішньо і потім підсумовує її; передача тих самих аргументів thresholds та roi, що й для попередньо обчисленої гістограми, дає статистику для тієї самої множини пікселів.

5.18.4. Перцентилі та пошук за CDF

Об’єкт histogram надає метод get_percentile(), що перетворює дробове число на значення пікселя – значення, нижче якого лежить запитана частка пікселів. h.get_percentile(0.5) є медіаною; h.get_percentile(0.05) та h.get_percentile(0.95) разом дають надійний мінімум/максимум, який ігнорує нижні та верхні 5% як викиди.

Це форма, яку застосунок використовує, коли хоче охарактеризувати діапазон значень пікселів, не дозволяючи кільком стороннім світлим або темним пікселям спотворити відповідь. Надійний мінімум/максимум з 5-го та 95-го перцентилів також є природнім вхідним даним для проходу розтягування контрасту – порепіксельне перетворення, яке охоплює розділ тональних корекцій.

5.18.5. Метод Отсу

Гістограми відповідають на ще одне питання, варте окремого розгляду: якщо пікселі зображення розбиваються на «темний» та «світлий» кластери, що є межею між ними? Сторінка порогової обробки вже назвала механізм за його результатом – єдиний глобальний поріг, який застосунок може передати до binary() – але відклала пояснення як. Як – це метод Отсу, і він живе на гістограмі.

Інтуїція: зображення з чітко вираженим переднім планом та тлом має два кластери у своїй гістограмі яскравості, з западом між ними. Правильне місце для порогової обробки – дно западу – значення, де два кластери найкраще розділені. Метод Отсу перебирає кожну можливу межу та вибирає ту, де дисперсії всередині кластерів є найменшими (що рівнозначно тому, що міжкластерна дисперсія є найбільшою), і результат – оптимальний бінарний поділ для розподілу конкретного зображення.

Об’єкт histogram надає доступ до Отсу через get_threshold:

h = img.get_histogram()
t = h.get_threshold()

Повернутий об’єкт threshold має атрибути value (для відтінків сірого) або l_value / a_value / b_value (для кольору), що містять обрану межу. Передача результату назад до binary() дає самоналаштовуваний глобальний поріг, межу якого вибирає саме зображення:

img.binary([(t.value, 255)])

Цей шаблон не вирішує проблему нерівномірного освітлення, яку вирішує адаптивний поріг на основі фільтрів; він вирішує питання «яке значення обрати як межу?» коли глобальна порогова обробка вже є правильним підходом. Для сцени, де розрізнення переднього плану та тла чітко визначене, значення, яке вибирає Отсу, зазвичай відрізняється на кілька одиниць від того, що людина обрала б на погляд.

5.18.6. Обчислення на різницевому зображенні

Корисна деталь щодо get_histogram() та get_statistics(): обидва приймають ключове слово difference, яке отримує інший Image і обчислює гістограму (або статистику) порепіксельної різниці між джерелом та цим зображенням, не виділяючи окреме різницеве зображення. Це дешевий спосіб запитати «наскільки змінилася сцена порівняно з опорним кадром?» без оплати явного виклику difference() для отримання зображення, єдина мета якого – бути виміряним. Для безперервно працюючого скрипта виявлення руху така економія накопичується.