его о libpuzzle libray для php (http://libpuzzle.pureftpd.org/project/libpuzzle) от г-на Франка Дениса. Я пытаюсь понять, как индексировать и хранить данные в моей базе данных mysql. Генерация вектора абсолютно не проблема.
Пример:
# Compute signatures for two images
$cvec1 = puzzle_fill_cvec_from_file('img1.jpg');
$cvec2 = puzzle_fill_cvec_from_file('img2.jpg');
# Compute the distance between both signatures
$d = puzzle_vector_normalized_distance($cvec1, $cvec2);
# Are pictures similar?
if ($d < PUZZLE_CVEC_SIMILARITY_LOWER_THRESHOLD) {
echo "Pictures are looking similar\n";
} else {
echo "Pictures are different, distance=$d\n";
}
Мне все ясно, но теперь, как я могу работать, когда у меня есть большое количество фотографий > 1.000.000? Я вычислил вектор и сохранил его с именем файла в базе данных? Как найти похожие фотографии сейчас? Если я храню каждый вектор в mysql, я должен открыть каждую запись и вычислить расстояние с помощью функции puzzle_vector_normalized_distance. Эти процедуры занимают много времени (открывайте каждую запись в базе данных - поместите ее в функцию,...)
Я прочитал readme из libbay lib и нашел следующее:
Будет ли он работать с базой данных, содержащей миллионы изображений?
Типичная сигнатура изображения требует только 182 байта, используя встроенную функции сжатия/декомпрессии.
Аналогичные подписи имеют одинаковые слова, т.е. идентичные последовательности значения в тех же позициях. Используя составные индексы (слово + позиция), множество возможных аналогичных векторов резко уменьшено, и в большинстве случаев никакое векторное расстояние фактически не требует вычислить.
Индексирование слов и позиций также позволяет легко разделить данных на несколько таблиц и серверов.
Итак, библиотека "Головоломка", безусловно, несовместима с проекты, которые должны индексировать миллионы изображений.
Также я нашел это описание об индексировании:
------------------------ УКАЗАНИЕ ---------------------- -
Как быстро найти похожие изображения, если они миллионы записей?
Оригинальная бумага имеет простой, но эффективный ответ.
Вырезать вектор в словах фиксированной длины. Например, рассмотрим следующий вектор:
[a b c d e f g h я j k l m n o p q r s t u v w x y z]
С длиной слова (K) из 10 вы можете получить следующие слова:
[a b c d e f g h я j], найденный в позиции 0 [b c d e f g h я j k] найденный в позиции 1 [c d e f g h я j k l], найденный в позиции 2 и т.д. до положения N-1
Затем проиндексируйте свой вектор с составным индексом (слово + позиция).
Даже с миллионами изображений K = 10 и N = 100 должно быть достаточно, чтобы имеют очень мало записей, разделяющих один и тот же индекс.
Здесь очень простая схема выборки базы данных:
+-----------------------------+
| signatures |
+-----------------------------+
| sig_id | signature | pic_id |
+--------+-----------+--------+
+--------------------------+
| words |
+--------------------------+
| pos_and_word | fk_sig_id |
+--------------+-----------+
Я бы рекомендовал расщепить по крайней мере таблицу "слов" на несколько таблиц и/или серверов.
По умолчанию (lambas = 9) подписи составляют 544 байта. Чтобы сохранить они могут быть сжаты до 1/3 их оригинальной размера через функцию puzzle_compress_cvec(). Перед использованием они должен быть несжатым с помощью puzzle_uncompress_cvec().
Я думаю, что сжатие является неправильным способом, поэтому я должен распаковать каждый вектор, прежде чем сравнивать его.
Теперь мой вопрос - каким образом обрабатывать миллионы изображений и как их быстро и эффективно сравнивать. Я не могу понять, как "разрезание вектора" должно помочь мне с моей проблемой.
Большое спасибо - может быть, я могу найти здесь кого-то, кто работает с libpuzzle libaray.
Приветствия.