Проверка последовательности изображений

Проблема

Определение проблемы

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

Скажем, у меня есть последовательность изображений, например:

http://img514.imageshack.us/img514/5440/60372aeba8595eda.gif

Если увиден, я хочу увидеть связанный с ним идентификатор, если нет - он будет проанализирован и добавлен как новый экземпляр последовательности изображений, который был замечен. У меня есть об этом довольно долгое время, и я признаю, что это может быть трудной проблемой. Кажется, мне сложно с этим справиться, может ли кто-нибудь помочь (на С#)?

Ограничения и использование

Я не, пытаюсь воссоздать систему обнаружения авторских прав, например, систему идентификаторов контента, реализованную Youtube (Маргарет Гулд Стюарт в TED (ссылка)). Последовательность изображений можно рассматривать как файл (.gif), но это не так, и нет прямого способа получить двоичный файл. Подобный метод можно использовать, чтобы избежать дублирования в "базе данных обмена изображениями", но это не то, что я пытаюсь сделать.

Мое усилие

Размытие по Гауссу

Функция Mathematica для генерации гауссовских размытых ядер:

getKernel[L_] := Transpose[{L}].{L}/(Total[Total[Transpose[{L}].{L}]])
getVKernel[L_] := L/Total[L]

alt textalt textalt text Оказывается, что гораздо эффективнее использовать 2 прохода векторного ядра, а затем матричное ядро. Thy основаны на Треугольник Паскаля неровные строки:

{1d/4, 1d/2, 1d/4}
{1d/16, 1d/4, 3d/8, 1d/4, 1d/16}
{1d/64, 3d/32, 15d/64, 5d/16, 15d/64, 3d/32, 1d/64}

Ввод данных, хеширование, оттенки серого и лайтбоксирование

Пример исходных бит, которые могут быть полезны:

  • Лайтбокс вокруг известного прямоугольника: FrameX
  • Использование MD5CryptoServiceProvider для получения хэша md5 содержимого внутри известного прямоугольника atm.
  • Использование ColorMatrix для изображения в оттенках серого

Пример источника

Пример источника (GUI; code)

Получить текущий контент внутри определенного прямоугольника.

        private Bitmap getContentBitmap() {
            Rectangle r = f.r;
            Bitmap hc = new Bitmap(r.Width, r.Height);
            using (Graphics gf = Graphics.FromImage(hc)) {
                gf.CopyFromScreen(r.Left, r.Top, 0, 0, //
                    new Size(r.Width, r.Height), CopyPixelOperation.SourceCopy);
            }
            return hc;
        }

Получить хэш-метку md5 растрового изображения.

        private byte[] getBitmapHash(Bitmap hc) {
            return md5.ComputeHash(c.ConvertTo(hc, typeof(byte[])) as byte[]);
        }

Получить оттенки серого изображения.

        public static Bitmap getGrayscale(Bitmap hc){
            Bitmap result = new Bitmap(hc.Width, hc.Height);
            ColorMatrix colorMatrix = new ColorMatrix(new float[][]{   
                new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0.5f,0.5f,0.5f,0,0},
                new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0,0,0,1,0,0},
                new float[]{0,0,0,0,1,0}, new float[]{0,0,0,0,0,1}});

            using (Graphics g = Graphics.FromImage(result)) {
                ImageAttributes attributes = new ImageAttributes();
                attributes.SetColorMatrix(colorMatrix);
                g.DrawImage(hc, new Rectangle(0, 0, hc.Width, hc.Height),
                   0, 0, hc.Width, hc.Height, GraphicsUnit.Pixel, attributes);
            }
            return result;
        }

Ответ 1

Я думаю, у вас есть несколько проблем с этим:

  • Не все последовательности изображений [видео] равны [но многие похожи]
  • Откуда берутся ваши данные?
  • Как вы будете представлять данные, связанные с вашими просмотрами?
  • Размер данных

Проблема №1:

Многие изображения могут незначительно отличаться при сжатии, маркировке воды, отсутствующих кадрах и добавлении клипов. Я бы предложил опробовать видео. Например, вы можете захотеть рассмотреть выборку небольших фрагментов изображений в видео. Кроме того, чтобы избежать шумных образов и проблем с алгоритмами сжатия с меньшим сжатием. Возможно, вы захотите рассмотреть сериализацию выбранных фреймов и сделать гауссовское размытие. [Guassian, потому что его "более естественный" (короткий ответ)]. Когда у вас будет достаточно суб-образцов, где у вас есть хорошая уверенность в сходстве с видео, сохраните его в базе данных. С образцами вы можете хэш их или сохранить их, чтобы сделать% сходства позже.

Проблема № 2

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

Проблема № 3

Использование чего-то типа Postgres [если есть много объектов большого размера], или SQLLite настоятельно рекомендуется для индексирования, хранения и вызова прошлых метаданных.

Проблема № 4

Размер данных будет иметь огромное определение при вызове, выборке, запросе базы данных и т.д.

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

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

Ответ 2

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

Оппортунистическая прагматика во мне сделала бы шаг назад, посмотрит на общую картину и посмотрит, есть ли другой способ решить проблему. Например, если вы создаете какое-то "сообщество обмена изображениями" и хотите избежать дубликатов в базе данных, вы можете сделать простой md5 в файле (анимированные gif в Интернете, как правило, всегда одинаковы, редко бывает, что люди изменяют их).

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

Ответ 3

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

В первом случае просто возьмите любой тип хэша файла и используйте его (потому что файл будет идентичен на двоичном уровне.

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

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

  • Делайте гауссовское размытие, которое вы уже делаете.
  • Разделите каждое изображение на несколько прямоугольников одинакового размера (вам нужно будет проверить наилучшее число, но я предлагаю начать с 9.
  • Для каждого прямоугольника в каждом кадре вычислите полноцветную гистограмму, затем найдите самый встречный цвет в этом прямоугольнике. Это дает вам 9 * 20 = 180 номеров. Это "отпечаток пальца" этого фильма.
  • Найдите наиболее похожие отпечатки пальцев в своей базе данных, если они достаточно похожи, вы уже знаете об этом, иначе вы этого не сделаете.

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

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

Ответ 4

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