Алгоритм для подсчета количества уникальных цветов в изображении

Это довольно поздно в ответ, но для тех, кто ищет это, вы можете сделать следующий код для ручного округления углов ваших изображений.

http: // www .ruibm.com /? p = 184

Это не мой код, но я использовал его, и он отлично работает. Я использовал его в качестве помощника в классе ImageHelper и немного расширил его, чтобы передать количество оперения, которое мне нужно для данного изображения.

Окончательный код выглядит следующим образом:

package com.company.app.utils;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;

public class ImageHelper {
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = pixels;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }
}

Надеюсь, это кому-то поможет!

7
задан Lou Franco 27 September 2008 в 19:30
поделиться

10 ответов

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

Использование Цвета. ToArgb () в хеше вместо цветового объекта, вероятно, был бы хорошей идеей также.

Кроме того, если скорость является главным беспокойством, Вы не хотите использовать функцию как GetPixel (x, y) - вместо этого пытаются обработать блоки за один раз (расположите время в ряд). Если Вы можете, получить указатель на начало памяти изображений и делаете это небезопасный.

14
ответ дан 6 December 2019 в 04:58
поделиться

Никогда не реализовывал что-то вроде этого прежде, но поскольку я вижу его, примитивная реализация:

Для 24-разрядного изображения максимальное количество цветов, которые могло иметь изображение, является минимумом (2^24, пиксельное количество изображения).

Только необходимо записать, считался ли конкретный цвет, не, сколько раз это считалось. Это означает необходимость в 1 бите, чтобы записать, считается ли каждый цвет. Это составляет 2 МБ памяти. Выполните итерации через пиксели, установите соответствующий бит в своей карте набора цветов 2 МБ. В конце выполняют итерации через карту набора цветов, считая биты набора (если Вы удачливы, что у Вас будет инструкция POPCNT помочь в этом).

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

11
ответ дан 6 December 2019 в 04:58
поделиться
var cnt = new HashSet<System.Drawing.Color>();

foreach (Color pixel in image)
    cnt.Add(pixel);

Console.WriteLine("The image has {0} distinct colours.", cnt.Count);

/ РЕДАКТИРОВАНИЕ: поскольку Lou сказал, с помощью .GetArgb() вместо Color само значение могло бы быть немного быстрее из-за пути Color реализации GetHashCode.

4
ответ дан 6 December 2019 в 04:58
поделиться

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

Сначала я опишу случай на 32 бит/пкс, это намного легче:

  • HashSet: Разреженная матрица цветов
  • ImageData: Используйте объект BitmapData непосредственно получить доступ к базовой памяти
  • PixelAccess: Используйте интервал* для ссылки на память как ints, которого можно выполнить итерации через

Поскольку каждое повторение просто делает hashset.add того целого числа. В конце просто видят, сколько ключей находится в HashSet, и это - общее количество цветов. Важно отметить, что изменение размеров HashSet является действительно болезненным (O (n), где n является количеством объектов в наборе), и таким образом, можно хотеть создать довольно размерный HashSet для начала, возможно, что-то как imageHeight*imageWidth/4 было бы хорошо.

В случае на 24 бит/пкс PixelAccess должен быть байтом*, и необходимо выполнить итерации более чем 3 байтов для каждого цвета для построения интервала. Для каждого байта в наборе 3 первых сдвигов разряда налево 8 (один байт) и добавляют его к целому числу. Вам теперь представил Цвет на 24 бит/пкс интервал на 32 бита, остальное все одинаково.

3
ответ дан 6 December 2019 в 04:58
поделиться

У большинства людей здесь есть предложенные решения, которые, вероятно, будут быстры (на самом деле тот, который только использует 2 МБ, вероятно, приемлемо относительно использования памяти и очень быстро; тот с хешем мог бы быть еще быстрее, но он будет определенно использовать больше чем 2 МБ памяти). Программирование всегда является компромиссом между использованием памяти и процессорное время. Можно обычно получать результаты быстрее, если Вы готовы "потратить впустую" больше памяти, или можно получить результаты медленнее путем "траты" большего количества времени вычисления, однако это обычно сейфы Вы большая память.

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

  1. Отсортируйте пиксели в изображении цветом. Можно легко преобразовать каждый пиксель в число на 32 бита, и числа на 32 бита могут сравниться друг с другом, при этом одно число меньше, чем другой, больше или равный. При использовании Quicksort никакое дополнительное пространство памяти не необходимо для сортировки кроме дополнительного стекового пространства. При использовании Shellsort никакая дополнительная память не необходима вообще (хотя Shellsort будет намного медленнее, чем Quicksort).

    международная цифра = (КРАСНЫЙ <<16) + (ЗЕЛЕНЫЙ <<8) + СИНИЙ;

  2. После того как Вы отсортировали пиксели как этот (что означает, что Вы перестроили их в рамках изображения), все пиксели равного цвета всегда друг рядом с другом. Таким образом, можно только однажды выполнить итерации по изображению и посмотреть, как часто цвет изменяется. Например, Вы храните текущий цвет пикселя в (0, 0) и Вы init счетчик со значением 1. Следующий шаг - Вы, переходят в (0, 1). Если это - тот же цвет как прежде, ничто, чтобы сделать, продолжите следующий пиксель (0, 2). Однако, если это не то же, увеличьте счетчик одним и помните цвет того пикселя для следующего повторения.

  3. После того как Вы посмотрели на последний пиксель (и возможно увеличили счетчик снова, если это не было то же как предпоследний пиксель), счетчик содержит количество уникальных цветов.

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

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

6
ответ дан 6 December 2019 в 04:58
поделиться

Вы точно не определили уникальные цвета. Если Вы на самом деле имеете в виду значения действительно уникального кода (в противоположность визуально тому же), то единственное точное решение состоит в том, чтобы на самом деле считать их использованием одного из методов описанный в других ответах.

При поиске визуально схожих цветов это действительно быстро дистиллирует вниз к проблеме отображения палитры, где Вы ищете, говорят что 256 лучших уникальных цветов для использования, чтобы наиболее тесно представить исходное полное динамическое изображение цветового диапазона. Для большинства изображений удивительно, как хороший изображение уменьшило от 24 битов, и до 16 миллионов различных цветов для запуска с могут быть отображены на изображении только с 256 уникальными цветами, когда те 256 цветов хорошо выбраны. Оптимальный выбор тех правильных 256 цветов (для этого примера), как доказывали, был полон NP, но существуют практические решения, которые могут очень приблизиться. Поиск статей парня по имени Shijie Wan и материал основывался на его работе.

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

2
ответ дан 6 December 2019 в 04:58
поделиться

Перед современными видеокартами, когда большинство машин работало в 256 режимах цветовой палитры, это было сферой небольшого количества больших интересов. Пределы на вычислительную мощность и память, наложенную просто вид ограничения, которое могло бы быть полезно для Вас - так поиск на алгоритмах для обработки палитр, вероятно, поднимут что-то вроде использования.

1
ответ дан 6 December 2019 в 04:58
поделиться

Это зависит от того, какие типы изображений Вы хотите проанализировать. Для 24 Растровых изображений Вам будут нужны до 2 МБ памяти (так как в худшем случае необходимо обработать каждый цвет). Для этого битовый массив был бы лучшей идеей (у Вас есть битовый массив на 2 МБ, где каждый бит соответствует цвету). Это было бы хорошим решением для изображений с количеством высококачественного цвета, которое может быть понято в O (#pixels). Для 16 Растровых изображений Вам только были бы нужны 8 КБ для этого битового массива с помощью этой техники.

Однако, если бы у Вас есть изображения с не, много окрашивает, было бы лучше использовать что-то еще. Но затем Вам была бы нужна некоторая проверка для указания, какой алгоритм необходимо использовать...

1
ответ дан 6 December 2019 в 04:58
поделиться

Максимальное количество уникальных цветов в изображении равно числу пикселей, таким образом, это предсказуемо от, очень запускаются процесса. Используя предложенный метод HashSet, Konrad, затем казалось бы, был бы разумным решением, поскольку размер хеша должен быть не больше, чем число пикселей, тогда как использование растрового подхода, предложенного JeeBee, было бы, потребовал 512 МБ для 32 растровых изображений (Если существует Альфа-канал, и это полно решимости способствовать уникальности цвета),

Выполнение подхода HashSet, тем не менее, вероятно, будет хуже, чем выполнение подхода 'бита на цвет' - Вы могли бы хотеть попробовать обоих и сделать некоторые сравнительные тесты, с помощью большого количества изображений differnt

1
ответ дан 6 December 2019 в 04:58
поделиться

Современная популярная реализация цветного квантования использует структуру данных дерева октантов. Отметьте страницы Википедии, содержание довольно хорошо. Дерево октантов имеет преимущество того, чтобы быть столь же ограниченным памятью, как Вы хотите, таким образом, можно выбрать целое изображение и выбрать палитру без большой дополнительной памяти. После того как Вы понимаете понятие, переходите по ссылке к 1996 исходный код статьи в журнале доктора Dobb.

Так как это - вопрос C#, см., что статья May 2003 MSDN Оптимизирует Цветное Квантование для Изображений ASP.NET, которое включает некоторый исходный код.

0
ответ дан 6 December 2019 в 04:58
поделиться
Другие вопросы по тегам:

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