Использование SOLR для вычисления "сходства"/"количества битов" между двумя ulongs
У нас есть база данных изображений, где я вычислил PHASH, используя метод доктора Нила Кравец, реализованный Дэвидом Офтедалом.
Часть примера кода вычисляет разницу между этими значениями:
ulong hash1 = AverageHash(theImage);
ulong hash2 = AverageHash(theOtherImage);
uint BitCount(ulong theNumber)
{
uint count = 0;
for (; theNumber > 0; theNumber >>= 8) {
count += bitCounts[(theNumber & 0xFF)];
}
return count;
}
Console.WriteLine("Similarity: " + ((64 - BitCount(hash1 ^ hash2)) * 100.0) / 64.0 + "%");
Проблема в том, что я знаю только один из этих хэшей и хочу запросить SOLR, чтобы найти другие хэши в порядке сходства.
Несколько заметок:
- Используя SOLR здесь (единственная альтернатива у меня есть HBASE)
- Хотите избежать установки любых пользовательских Java в Solr (рад установить существующий плагин)
- Рад сделать много предварительной обработки в C#
- Рад использовать несколько полей для хранения данных в виде битовой строки, длинной и т. Д.
- Использование SOLRNet в качестве клиента
Отредактируйте, некоторую дополнительную информацию (извинения, я попал в проблему и начал предполагать, что это была широко известная область). Вот прямая загрузка в консоль / пример приложения C#: http://01101001.net/Imghash.zip
Пример вывода этого консольного приложения:
004143737f7f7f7f phash-test-001.jpg
0041417f7f7f7f7f phash-test-002.jpg
Сходство: 95,3125%
1 ответ
Вы можете использовать Solr Fuzzy Search для этого, вам нужно немного прокрутить страницу вниз.
Стандартный синтаксический анализатор запросов Solr поддерживает нечеткие поиски, основанные на алгоритме Levenshtein Distance или Edit Distance. Нечеткие поиски обнаруживают термины, которые похожи на указанный термин, но не обязательно являются точным соответствием. Чтобы выполнить нечеткий поиск, используйте символ тильды ~ в конце одного слова.
Предполагая, что у вас есть схема, как показано ниже, где это поле phash
содержит фаш, который вы рассчитали.
<fields>
<!-- ... all your other fields ... -->
<field name="phash" type="string" indexed="true" stored="true" />
</fields>
Вы можете выполнить запрос как
q=phash:004143737f7f7f7f~0.8&
fl=score,phash
Это вернет все документы, которые имеют PHASH с Levenshtein Distance or Edit Distance
не менее 80%. Вы не получите 95,3125%, которые вы дали в своем вопросе, но 87,5%, поскольку совпадающие / не совпадающие символы учитываются.
Если вы хотите увидеть это значение, вы можете выполнить следующий запрос
q=phash:004143737f7f7f7f~0.8&
fl=score,phash,strdist("0041417f7f7f7f7f", phash, edit)
Это вызов функции для извлечения String Distance с использованием расстояния Levenstein или Edit и выдачи результата, аналогичного
+----------------+---------------------------------------+
|hash |strdist("0041417f7f7f7f7f", hash, edit)|
+----------------+---------------------------------------+
|0041417f7f7f7f7f|1.0 |
+----------------+---------------------------------------+
|004143737f7f7f7f|0.875 |
+----------------+---------------------------------------+
Когда вы хотите уменьшить разрыв между 95.3125%
а также 87,5%
Вы должны хранить PHASH не как шестнадцатеричное значение, а, например, как восьмеричное.