Быстрый способ получения доминирующего цвета изображения

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


Если это имеет значение, это UIImage, снятый с iPhone или iPod touch, который не превышает 5 Мпкс. Причина, по которой она должна быть быстрой, состоит в том, что просто показ индикатора прогресса не имеет особого смысла, поскольку это приложение для людей с плохим зрением или вообще без вида. Поскольку это для мобильного устройства, оно может не занимать очень много памяти (не более 50 МБ).

Ответ 1

Ваш общий подход должен работать, но я бы выделил некоторые детали.

Вместо данного списка цветов создайте несколько цветовых "бункеров" в цветовом спектре для подсчета пикселей. Вот еще один вопрос, который имеет некоторые алгоритмы для этого: Создание цветовых палитров спектра. Сделайте количество бункеров настраиваемым, чтобы вы могли экспериментировать, чтобы получить нужные результаты.

Далее, для каждого пикселя, который вы рассматриваете, вам нужно найти "ближайший" бит для увеличения. Вам нужно будет определить "ближайшее"; см. эту статью о "цветовой разнице": http://en.wikipedia.org/wiki/Color_difference

Для производительности вам не нужно смотреть на каждый пиксель. Так как элементы изображения обычно покрывают большие области (например, небо, трава и т.д.), Вы можете получить желаемый результат, только сэмплируя несколько пикселей. Я бы предположил, что вы можете получить хорошие результаты, отбирающие каждый 10-й пиксель, или даже каждые 100-е. Вы также можете поэкспериментировать с этим фактором.

[Примечание редактора: абзац ниже был отредактирован для комментария Майка Фэрхерста.]

Также можно сделать усреднение пикселей, как в этой демонстрации: jsfiddle.net/MUsT8/