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

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


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


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


Может я что-то упустил и есть «зеленые» решения?
  • Вопрос задан
  • 4547 просмотров
Пригласить эксперта
Ответы на вопрос 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 и перебором всех цветов, тогда Вам не грозят большие затраты если картинка большая, но так можно и упустить цвет если мало цветных областей. Но если Ваши цветные картинки четко цветные а монохромные четко монохромные этот способ поможет не плохо.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы