0

I have the bit set of images(about 100 thousand) that are encoded (using a neural network) into a 512-bit vector. For example:

https://image1.png => [0,1,0,0,0, ... 1] // size = 512 bit
https://image2.png => [1,1,1,0,0, ... 0] // size = 512 bit
https://image3.png => [0,0,1,1,0, ... 1] // size = 512 bit

The task is to find very quickly from a set of similar images by the image (binary vector) sent by the user. I found a possible solution with Hamming distances, but I'm not sure about its speed with my set of images.

I would like to know if someone has encountered such a problem and knows what is better to use in this situation?

Christophe
  • 68,716
  • 7
  • 72
  • 138
QuickDzen
  • 247
  • 1
  • 11
  • 1
    Are you sure that similar bit vectors map to similar images ? eg If the bit-vectors were produced by a cryptographic hash function (for example) this would not be true. – Richard Critten Jan 24 '21 at 16:56
  • Yes, I used a neural network for these purposes – QuickDzen Jan 25 '21 at 06:24
  • @QuickDzen can you clarify what kind of neural net (multilayer perceptron, convolutive NN, etc...)? Do the bits correspond to characteristics which the NN has learnt (i.e. does someone know what every bit corresponds to)? – Christophe Jan 25 '21 at 12:50

2 Answers2

2

Since you have binary vectors, moreover of identical size, the similarity determination is greatly simplified. For two images, you just need to:

  • XOR the two vectors: two identical positions will result in 0, two different positions will result in 1.
  • count the number of bits in the result and you have the number of different positions. You can do this easily in python or in C++ (depending on your C++ encoding, you may use bitset::count(), or some kind of optimized algorithms on an array of integers, or the built-in non-portable alternative of your favourite compiler)

This kind of similarity check is extremely efficient. You just need to compare the bit-count to a similarity thershold you'd define (e.g.: more than x bits difference means not sufficiently similar).

Exemple:

Image 1: [0,1,0,0,0, ... 1]
Image 2: [1,1,1,0,0, ... 0]
XOR      [1,0,1,0,0, ... 1]
bitcount ---> 3 differences (or more depending on ...)

Note: If you prefer your threshold to be defined in terms of identical positions rather than different ones, substract the bitcount from 512 (or more generally, negate the result before counting the bits).

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • It's a very good solution! But I have the bit set of images(about 100 thousand) and using XOR for each record will be very slow. Maybe you should sort this data somehow, and then apply XOR to some of them? – QuickDzen Jan 25 '21 at 06:24
  • @QuickDzen The problem is that sorting works well for exact matches. If any bit is allowed to change, sorting will be of no use. The best strategy will depend on the similarity requirements. If a very very close similarity, you could generate the potential candidates and search for the all the candidates in a b-tree. If some bits are not allowed to change you can have a sort on those bits and compare a limited set. Another idea could be to compress the 512 bits into say a group of 128 bits or less, and compare compressed forms with a stronger similarity requirement to limit full search – Christophe Jan 25 '21 at 16:49
1

It depends on the context of the images. However, one similarity measure is the sorensen-dice coefficient which is defined by s(img_i , img_j) = 2 (img_i . img_j) /(|img_i|^2 + |img_j|^2). You can find more details about it here.

OmG
  • 18,337
  • 10
  • 57
  • 90
  • It's a not bad solution! But I have the bit set of images(about 100 thousand) and using XOR for each record will be very slow. Maybe you should sort this data somehow, and then apply sorensen-dice coefficient to some of them? – QuickDzen Jan 25 '21 at 06:27