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, щоб включати лише пікселі, що відповідають цим діапазонам. Форма з порогом дозволяє виконати операцію «обчислити гістограму лише відповідних пікселів» одним викликом – поширений шаблон, коли застосунок хоче охарактеризувати текстуру вже знайденої ділянки, не обходячи пікселі самостійно.
Гістограма у відтінках сірого з трьома накладеними зведеними вимірюваннями: поріг Отсу (межа, яка найкраще розділяє темний та світлий кластери), середнє та медіана. Кожне вимірювання говорить дещо різне про один і той самий розподіл.¶
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() для отримання зображення, єдина мета якого – бути виміряним. Для безперервно працюючого скрипта виявлення руху така економія накопичується.