Алгоритм grayscale на delphi, блог шарахова а

Перетворити кольорове зображення в чорно-біле (відтінки сірого) можна дуже швидко, витративши 3 такту CPU на піксель.

У типі TColor червоний колір зберігається в молодшому байті, далі зелений, за ним синій. Вони можуть бути вилучені за допомогою наступних операторів:

Добре відома формула для обчислення яскравості кольорового зображення по інтенсивності колірних складових:

або в целочисленной арифметиці:

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

Здавалося б, все просто. Але якщо запрограмувати алгоритм в лоб, то виявиться, що перетворення зображення розміром 800x600 з дозволом 32bpp займає більше секунди:

Спробуємо прискорити обчислення нового кольору пікселя. Звернемо увагу на те, що фактично обчислення яскравості пікселя в процедурі Grayscale1 проводиться в байті з номером 1, який потім зсувається в молодший байт (байт номер 0). Все це вимагає попереднього переміщення значень колірних складових в молодший байт. Якщо ж обчислення яскравості виконувати в старшому байті (байт номер 3), то можна обійтися без попереднього зсуву:

Зауважимо також, що множення синьою і червоною складових можна поєднати. При цьому в двох молодших байтах буде додатково обчислено твір Blue * 77, яке не матиме впливу на результат через подальше зрушення:

Крім того, можна обійтися без виділення зеленої складової, і помножити на відповідний їй ваговий коефіцієнт всі кольори, а червону і зелену складові потім помножити на менший коефіцієнт:

І, нарешті, логічне множення на константу $ 00FFFFFF зайве, тому що при множенні старшого байта Color на (150 * 256) все одно буде отримано нуль. Після чергового спрощення отримуємо:

В результаті процедура перетворення стала в півтора-два рази швидше. Повністю вона тепер виглядає наступним чином:

Якщо розгорнути цикл, то можна отримати прискорення ще приблизно в 1.25 рази:

Нижче результати експериментів зведені в таблицю. Для вимірі продуктивності використовувався фоновий малюнок 'Безмятежность.bmp' розміром 800x600 з Windows XP. Всі процедури, за винятком першої, викликалися в циклі 4000 разів.

Швидкість роботи початкової реалізації перевищена в 3000-4000 разів. При цьому процесорам E6850 і i5-2300 треба було всього 3 такту на обробку одного пікселя.

Схожі статті