PHP: Как отличить черно-белое изображение от цветного?

Даны два изображения. С точки зрения человека одно цветное, а другое черно-белое. Нужно отличить их по признаку цветности с помощью PHP/GD2.


Единственная найденная мною функция определения цветности называется imageistruecolor, но проблема в том, что оба изображения имеют полноцветную палитру и результат выполнения функции одинаков — сравнение не удается.


Нашел предложение обходить все пиксели изображения и определять цвет каждого из них с помощью ImageColorAt. Наверное, это вариант, но не хочется (если изображение большое — обход займет много времени, если предварительно его уменьшать — неэффективно тратим ресурсы на преобразовании).


Может я что-то упустил и есть «зеленые» решения?
  • Вопрос задан
  • 4512 просмотров
Пригласить эксперта
Ответы на вопрос 11
Alex_EXEcuter
@Alex_EXEcuter
Отресайзить в один пиксель, посмотреть его цвет.
Если я правильно это себе представляю — этот пиксель будет иметь усредненный цвет всей картинки.

Файлы в разных форматах или каком-то определенном?
Ответ написан
@holivar
Уточните, вам нужно именно черно-белое изображение, монохромное, или визуально выглядящее чернобелым/монохромным. И в определенном формате или произвольном. Потому как в форматах с потерей качества при сжатии (например, JPEG) чернобелого изображения не будет, даже если оно на взгляд таким кажется
,
а цветное может визуально выглядить монохромным.

Перебор по пикселям точно не подойдет
Ответ написан
metamorph
@metamorph
Разблюрить с чудовищным радиусом и глянуть на любой пиксель.
Ответ написан
@Serator
А если разделить изображение на квадраты и в каждом проверить выборочно n пикселей? Чем больше пикселей проверить, тем точнее результат.
Ответ написан
@vril
Как вариант — можно использовать приближенный «метод монте-карло»: брать n случайных пикселей, проверяя равенство значений всех цветовых каналов. Чем больше число проб — тем большая вероятность, что изображение — грей-скейл.

Естественно, что при первом же цветном пикселе — возвращать негативный результат.

Результат будет не на 100% точный, зато относительно быстрый.
Ответ написан
azproduction
@azproduction
1. Алгоритм для грей-скейл онли.
1.1. Имеем формулу получения вероятности, что пиксель черно-белый Sij=(Rij+Gij+Bij)/3; Pij = 1 — (|Sij-Rij| + |Sij-Gij| + |Sij-Bij|)/765;
1.2. Устанавливаем итоговую вероятность Т = 1. Начинаем сканировать картинку по сетке с шагом в 1-50 пикселей либо случайно несколько пикселей; чем больше мы просканируем тем правдоподобнее наша вероятность. Для каждого из сканируемых пикселей находим Pij; T = T * Pij; Если итоговая вероятность упала ниже 0.9, то останавливаем сканирование и говорим, что картика не черно-белая, если доходит до конца, то говорим, что черно-белая.
2. Алгоритм с получением палитры.
2.1. Пробегаем по картинке собираем все цвета если цветов больше 500 картинка не черно-белая, если менее, то находим вероятность родства цветов по тону, исходя из вероятности говорим, что картинка ч/б или сепия и т.п.
Ответ написан
Комментировать
Dunadan
@Dunadan
Немножко неясно: под «черно-белым» имеется ввиду именно битовая картина (с двумя цветами) или же оттенки серого?
Ответ написан
sl4mmer
@sl4mmer
ImageColorAt — норм вариант. На среднего размера картинках (500на500 например) скорость обработки хорошая(я как то делал для галлереи преобразование изображения в оттенки серого), но для экономии ресурсов можно, действительно, как предлагали выше перебирать не все пиксели, а допустим каждый пятый в длину в высоту (это к примеру).
Ответ написан
Комментировать
Anonym
@Anonym
Программирую немного )
Первое, что приходит в голову: сделать его еще раз черно-белым и сравнить с оригиналом. В идеале, «дважды черно-белое» изображение должно быть таким же как и «единожды черно-белое».
Ответ написан
@gro
>Единственная найденная мною функция определения цветности называется imageistruecolor, но проблема в том, что оба изображения имеют полноцветную палитру и результат выполнения функции одинаков — сравнение не удается.

проверить палитру?
Ответ написан
taliban
@taliban
php программист
Если нет серьезной прям задачи то можете обойтись ресайзом (допустим 10х10) + ImageColorAt и перебором всех цветов, тогда Вам не грозят большие затраты если картинка большая, но так можно и упустить цвет если мало цветных областей. Но если Ваши цветные картинки четко цветные а монохромные четко монохромные этот способ поможет не плохо.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽