Определить фотографии против изображений

Я пытаюсь, учитывая случайное изображение и используя NumPy, определить, является ли это фотография "отрендеренным" изображением (например, картой). Изображения могут быть цветными или черно-белыми, а градиенты на визуализированных изображениях могут легко использовать 0-255, поэтому подсчет цветов не поможет для оттенков серого. Я не могу использовать метаданные EXIF ​​/etc.

Подходы, которые я до сих пор быстро испробовал, ничего не выпрыгивая:

  • Преобразование в оттенки серого, затем просмотр гистограммы
  • 2D БПФ затем смотрит на гистограммы частот на полосу (как RGB и YUV)
  • Рассматривая средства и стандартное отклонение яркости
  • Обнаружение края с использованием фильтров Canny и Sobel
  • Сравнение свойств GLCM для случайных патчей 21x21 от каждого изображения
  • Сжатие изображений в формате JPEG (хорошо для фотографий) или Deflate (иначе PNG) (хорошо для карт) и сравнение битов на пиксель

(не стесняйтесь предложить мне вернуться и посмотреть еще раз)

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

Текущие многообещающие предложения описаны ниже, идеи, которые я еще не рассмотрел:

  • Ни одного не осталось

Есть ли алгоритмы / подходы, на которые я должен обратить внимание?

HSV

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

image_hsv = skimage.color.rgb2hsv(image_rgb)

hue_band, sat_band, val_band = np.squeeze(np.dsplit(image_hsv, 3))

band_hist, _ = np.histogram(hue_band.ravel(), bins=256)
peak_idx = np.signal.argrelmax(band_hist, order=20)[0]

peaks = band_hist[peak_idx]

контрастировать

Изучение контраста кажется немного лучше, рассчитывается с помощью кода ниже. Фотографии, как правило, кажутся <= 130, а карты обычно>= 150. Хотя черно-белые карты имеют очень низкий контраст (например, 11 для изображения ниже):

# image_rgb is a 3D numpy array: [
#                                 [ [r,g,b], [r,g,b], ... ],
#                                 [ [r,g,b], [r,g,b], ... ],
#                                 ...
#                                ]

# these constants from http://en.wikipedia.org/wiki/Relative_luminance
rgb2lum = numpy.array([0.2126, 0.7152, 0.0722])
luminance = numpy.dot(image_rgb, rgb2lum)

# for B&W images, luminance == image_bw already
rms_contrast = numpy.sqrt(numpy.mean(numpy.square(luminance)))

Текущий подход

То, что я в настоящее время пошел с:

  1. Анализирует до 8x 512x512px случайных патчей из изображений, которые все голосуют за результат:
    1. Для изображений RGB конвертируйте патч в цвет HSV
    2. Создание гистограммы (256 бинов) из черно-белых данных или полосы Хюэ (np.histogram())
    3. Подсчитайте непустые ячейки в гистограмме, если менее 100 голосов - это "карта".
    4. Получите пики гистограммы (signal.argrelmax(hist, order=20))
    5. Если максимальный пик составляет>9% от общего количества пикселей в полосе, а максимальный пик> = в 2 раза больше среднего значения пиков, тогда голосование принимается за "карту".
    6. В противном случае голосование будет "фото"
  2. Если 50% голосов от патчей "карта", то результат "карта"

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

Черно-белые изображения все еще немного попали или пропустили.

Примеры изображений

Высококонтрастное цветное фото. Некоторые могут быть довольно передержаны:
Высококонтрастное цветное фото

Низкоконтрастное цветное фото:
Низкоконтрастное цветное фото

Высококонтрастное черно-белое фото. Опять же, некоторые могут быть довольно передержаны:
Высококонтрастное черно-белое фото

Низкоконтрастное черно-белое фото:
Низкоконтрастное черно-белое фото

Низкоконтрастная цветовая карта:
Низкоконтрастная цветная карта

Высококонтрастная карта:
Высококонтрастная карта

Черно-белая карта:
Черно-белая карта

1 ответ

Я согласен, что это может быть немного за рамками SO. Возможно, отправьте его в Cross Validated?

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

Как только вы преобразуете каждое изображение в набор числовых текстурных объектов, вы можете использовать двоичный классификатор, чтобы отделить фотографии от синтетических изображений.

Другие вопросы по тегам