Perceptual Image Hashing
bertolami.com
bertolami.com
The examples given here were all predicted to have 95%+ similarity, but it seems to me that given this dataset, I could be reasonably convinced that it just assumes all images are reasonably similar. In other words, the author provides no counter-examples that demonstrate that the algorithm can detect dissimilar images, such as a photo of a car and a clipart of pizza. I would expect that to have very low similarity, and given the algorithm's demonstrated ability to discern between similar and dissimilar images, I would be more convinced of perceptual image hashing as a viable technique.
In this case, we are not looking at a model training, we are just evaluating the outcome of a (static) algorithm. On the other hand, in the context of ML you should try to include as much information as possible in your training dataset. This is a concept that comes by in many fields, some of them just tangentially related to machine learning (e.g. excitation signals for system identification, speaking both in terms of frequency domain and differential equations).
tl;dr: there is no "training set" to speak in the presented article - hence, concepts such as overfitting and information content (of the training set) do not quite apply here.
The algorithm presented here can be summarized as "Take the low-frequency DCT components of the luminance channel, quantized down to one bit". Hashing is a very misleading term for what you get from it: In particular, it doesn't have anything like the uniform coverage of the output space you would expect from a hash function, as almost all encountered images exist in a very small range of hashes. Also, the bits in the hash are not all created equal; assuming you encode them in a zig-zag pattern truncation is equivalent to a low-pass filter, so if you want to make the hash different sizes while matching on the same image elements you'll want to alter the quantization amount, not the output DCT size (this is directly equivalent to what JPEG does, which uses a fixed DCT size but lossily quantizes the information in it to varying degrees for different compression quality settings). Experiment with different quantization techniques; you don't have to treat every bit in the output the same.
This technique is only suitable for a small subset of the image files that you will encounter in the real world: it's mostly unsuitable for anything but photographs and photograph-like images (3d renders, paintings, etc.) Many classes of image have no useful distinguishing information in the low-frequency luminance space, such as screenshots, pictures of text, line drawings, many forms of graph and diagram, most "clip art" style drawings, pictures that include layout elements in the image file (like most of the meme/sucessories/demotivator format pictures you'll see on imageboards). Of course, an image with a flat or heavily compressed luminance channel will yield no information at all.
You don't have to do anything special to match flipped images, as you should be using (iirc) DCT-II that has the same output for a mirror image. It's insensitive to scaling and mild translation.
For debugging purposes, note that the transformation performed is lossy but easily reversible: you can undo all the steps but quantization to generate a 'stereotype' image of a particular hash value and its neighbors. There is no more information available to the matching algorithm than you can see with your own eyes with the round-trip conversion, so if the round-tripped image preserves important distinguishing detail the matching will work and if it turns the image into a meaningless grey smear you'll get tons of false positive matches.
http://hzqtc.github.io/2013/04/image-duplication-detection.h...
http://www.hackerfactor.com/blog/?/archives/432-Looks-Like-I...
Best practices for engineering is always to see what else is out there, so to assume the author hasn't conducted a review of the field might be read as rudeness or snark.
Many developers, even when they do compare and contrast their own work as they develop it, don't write up the results or list their peer projects, so it's otherwise not an unfair question to ask.
I'm trying to give benefit of the doubt here actually.
I've actually been working in this domain for the last week or so and DCT-based hashes are quite accurate, but slow as hell. Average hashes (aHash) or Delta Hashes (dHash) are much faster and rather good at weeding out large numbers of images. A mix of ideas is usually a good idea.
The implication is that there's no single 'perfect' classifier for a problem, engineers have used this notion for many years having multiple systems vote for fail-proof operations.
libpHash's implementation is slightly more sophisticated (and slower) as it adds a box filter over the image before downscaling and uses the median of the AC coefficients rather than mean for computing the hash bits. It also offers a few alternative hashing methods.
(Tweet summary of the article. I'm becoming increasingly fascinated by hash functions. I'm finding all important this tension between abstraction/correlation/perception & groundedness/volatility/identification.)
To my mind, an ~n-to-1 mapping would actually be a bit more like idealistic Platonic classifying than Wittgensteinian perception (~"we spin perceptual threads by twisting n attributes like fiber on fiber. And the strength of the thread does not reside in the fact that some 1 fiber runs through its whole length, but in the overlapping of the fibers.").
What do you think? :)
http://www.cs.toronto.edu/~rsalakhu/papers/semantic_final.pd...
The idea is that you could hash one billion objects, and do a very fast lookup of similar objects.
There is later academic work that refines this approach. For example, here is work applying it to image search: http://www.cs.utexas.edu/~grauman/temp/GraumanFergus_Hashing...
You can consider this a variant of Locality-Sensitive Hashing, where the hash function is specifically induced through a machine learning technique.
[1] http://en.wikipedia.org/wiki/Acoustic_fingerprint
Or would you be hashing the content, the language, the words used, the meaning of the words?
Stylometry is the study of written style. It's used forensically to see if two texts were written the same, to identify anonymous/pseudonymous authors, and there's "adversarial stylometry," which is intentionally changing a writing style to make it look like someone else wrote something.
This deck seems to summarize a lot of these points and issues, but offers no "stylometric hash" solution: http://wiki.uni.lu/mine/docs/RDPresentation.ppt
Plagiarism detection is another forum that might do these sorts of analyses. How many metaphors do you have to change, and synonyms do you have to replace, before it's an original work, or would it always still hash nearby?
Textometry tries to make texts more analyzable. Wordprints or stylometric fingerprints, seem to turn up more results than "hash".
I'll provide some examples of input and output. These examples happen to contain no linefeeds.
Suppose:
Hello, World! --> 65a8e27d8879283831b664bd8b7f0ad4
Then I want something like: Hello, Worlds! --> 65a8e27d8879283831b664bd8b7f4ad4
...Rather than what md5 currently provides: Hello, Worlds! --> d0478649ad1c15f0e623846c3e26ebeb
Basically, I love hashes and I use them all the time, but for many purposes I am only accidentally using the cryptographic features and in fact I would sometimes find it nice if similar inputs had similar outputs.Said differently: I'd like a hashing algorithm where the Levenshtein distance between any given two outputs correlates with the Levenshtein distance between the corresponding inputs.
I can imagine lots of uses for such a tool. ...But I can't imagine how it could be possible to make one: files (or strings) vary in length, for one thing, but a good hash does not! Of course, I couldn't imagine md5 before I saw it in action, either.
Text -> topic_id.
Do you (or anyone else) have time to describe this code in English or pseudocode?
I'll start.
Let there be a function called hash which takes a
string named str and an integer named
length_of_hash (which defaults to 20).
Slice the string (str) into length_of_hash equally-sized
pieces?
Take numeric value of each character (of each slice??)
and do.. something to it, something involving
modulo 256, unless it's zero. Save all the
results.
Express each numeric result as hexidecimal and append
all those together. Return it, probably.
Clearly there are bugs in the translation. :)Example, with a hash length of 4: "helloworld" => [104, 101, 108, 108, 111, 119, 111, 114, 108, 100] => [[104, 101, 108, 108], [111,119,111,114], [108, 100]] => [67, 64, 219, 222] => "4340dbde"
So if one character is different in the string, only one hex value in the output will vary too. However, a flaw of the plan is that changes spaced out at an interval that matches your hash "length" will only affect one hex value in the output, but you run into the pigeonhole principle if you want a hash of limited size to have the same or similar Levenshtein distance as the potential inputs, but I suspect there are far smarter solutions :-)
My first idea would be to rotate it by something that's halfway between the steps used. Say, 360/32 degrees. How does that compare?
Also: because it discards the high frequency data one should be able to construct something like this: http://cvcl.mit.edu/hybrid/CatDogHybrid.jpg - where to us at a close distance it looks like one thing but to this it looks like something else.
If getting close enough results in unsightly blotches on the image, reduce the power of the low frequency luminance channel across the board, which will mask the changes by making the unmodified high frequency components more noticeable. That looks like what's being done in the catdog image, at least.
You could increase the saturation as well, as this fingerprinting system ignores color.
I have worked with image feature extraction in the past. Although using DCT coefficients has been used as a way to analyze texture features, the idea idea of generating the hash (step 5) seems to be new.
I am curious however on why you are discarding color information. Usually for reverse image search this kind of information can be quite useful.