Как определить, является ли изображение фотографией, рисунком или линией? - PullRequest
21 голосов
/ 20 февраля 2012

Как лучше всего определить тип изображения? rwong's ответ на этот вопрос предполагает, что Google разбивает изображения на следующие группы:

  • Фото - непрерывный тон
  • Картинка - плавное затенение
  • Рисование линии - битонал

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

Спасибо!


Обновление:

Я попробовал уникальный метод подсчета цветов, который tyjkenn упоминается в комментарии, и, похоже, он работает примерно в 90% случаев, которые я пробовал. В частности, черно-белые фотографии трудно правильно определить, используя только уникальный подсчет цветов.

Получение гистограммы изображения и подсчет только одного взгляда не похоже на приемлемый вариант. Например, это изображение имеет только два пика:
image

Here are two more images I've checked out:
image
image

Ответы [ 4 ]

4 голосов
/ 20 февраля 2012

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

3 голосов
/ 31 декабря 2014

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

1) Тип MIME или расширение файла

PNG - это обычно картинки или рисунки, а JPEG - это в основном фотографии.

2) Прозрачность

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

from PIL import Image
img = Image.open('test.png')
transparency = False
if img.mode in ('RGBA', 'RGBa', 'LA') or (img.mode == 'P' and 'transparency' in img.info):
    if img.mode != 'RGBA': img = img.convert('RGBA')
    transparency = any(px for px in img.getdata() if px[3] < 220)

print 'Transparency:', transparency

3) Распределение цветов

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

from PIL import Image
img = Image.open('test.jpg')
img.thumbnail((200, 200), Image.ANTIALIAS)
w, h = img.size
print sum(x[0] for x in sorted(img.convert('RGB').getcolors(w*h), key=lambda x: x[0], reverse=True)[:10])/float((w*h))

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

4) Обнаружение острых краев с помощью FFT

Острые края приводят к высоким частотам в спектре Фурье.И, как правило, такие функции чаще встречаются на чертежах (другой фрагмент кода Python):

from PIL import Image
import numpy as np
img = Image.open('test.jpg').convert('L')
values = abs(numpy.fft.fft2(numpy.asarray(img.convert('L')))).flatten().tolist()
high_values = [x for x in values if x > 10000]
high_values_ratio = 100*(float(len(high_values))/len(values))
print high_values_ratio

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

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

3 голосов
/ 21 февраля 2012

Эта проблема может быть решена путем классификации изображений, и это, вероятно, решение этой проблемы от Google. По сути, вам нужно (i) получить набор изображений, помеченных на 3 категории: фото, картинки и рисование линий; (ii) извлекать элементы из этих изображений; (iii) использовать функции изображения и метку для обучения классификатора.

Функция извлечения:

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

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

Существует также ряд других алгоритмов извлечения признаков , которые можно использовать.

Обучение классификатора:

После фазы извлечения объекта мы будем иметь для каждого изображения вектор числовых значений (назовем его вектором изображения) и его кортеж. Это подходящий вход для обучения классификатора. Что касается классификатора, можно рассмотреть нейронные сети , SVM и другие .

Классификация:

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

1 голос
/ 23 февраля 2012

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

Фотография - естественные края будут иметь различные интенсивности, и это меньшевероятно, что будет много параллельных ребер.

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

Рисование линий - синтетические линии, вероятно, имеют очень постоянную ширину.Преобразование ширины обводки может помочь вам определить удары.(Один из основных принципов заключается в том, чтобы находить градиенты краев, которые «указывают» друг на друга.) Гистограмма силы краев может иметь только один сильный пик.

...