layout algorithm for tightly-packed image thumbnails - algorithm

I'm working on an image gallery and I'd like to tightly pack the image thumbnails. The thumbnails are:
different aspect ratios
available at the same source resolution (longest edge 256 pixels)
I'd like to come up with an optimal solution (will probably have to be a heuristic) that allowed me to balance:
the padding between each thumbnail (preferably constant)
the consistency of thumbnail size (preferably all the same size)
the amount of each image that gets cropped for the display (preferably none)
the proximity of images consistent with their sort order (preferably sort-neighbours will be near one another in the grid)
I think this is a variant of the rectangle packing problem.
I've found some good references: Fast Optimizing Rectangle Packing Algorithm for Building CSS Sprites
But I wanted to check with the experts to see if anyone knows of:
any established algorithms that are available publicly,
any open source libraries that implement them or
any other mathematical references or guidance that might help me produce something as good as: http://labs.tineye.com/multicolr#colors=4b669e;weights=100;

I have come up with something like this (now also with code on github)
https://mendrik.github.io/diorama/
I should add that the order will be random, and the sizes try to be uniform, but for me it was more important to fill out the entire space rather than keep the sizes consistent. You can resize the browser window to see how it works.
If your height is not fixed, there are several other options, mostly knapsack or partitioning algorithms. 2d bin backing will leave you with gaps or wont find solutions that always fit all images.
my algorithm has almost no cropping and fits always all images into the given space, provided there are enough combinations to do so. the less images the more cropping obviously.

Related

Algorithm to pack N rectangles into a larger one

I am writing a (JavaScript) thumbnail generator and this bit of the project involves placing the N thumbnails in regular rows and columns within a larger target space, including a border around the outside and "visually pleasing" borders between each thumbnail.
Each thumbnail is large and already scaled to turn it into a thumbnail so one approach is to change the size of each thumbnail to help fulfil the packing conditions.
Each thumbnail is of an identical size. The number of thumbnails could be anywhere from a small number (4??) to something around 100.
I have been looking for some ideas and there seem to be plenty of example code for algorithms that pack as many rectangles of different sizes into the densest possible configuration - but I haven't come across anything similar to what I am trying to do.
If anyone can point me at some code or even an algorithm, I'd be very grateful.

Resources & approaches for detecting content-aware fill

How would one approach the problem of telling apart images (and highlighting areas) that have been content-aware filled?
Positive class image (original image without edits):
Negative class image (Tampered image with insignia removed):
I understand that this can be quite meaningfully tackled by training a segmentation CNN network. Is there a working solution that I haven't been able to find or an approach that in relatively simple to implement.
These images are samples from a codebase that throws Runtime errors.
I am no expert on this, but as far as I know structural image manipulation algorithms like Photoshop's content aware fill (which is based on the PatchMatch Algorithm) are dividing an image up into so-called patches defined by a common intensity statistic. The manipulation is then carried out by replacing the target patch by a source patch with statistics matching the adjacent patches as well as possible (minimizing some distance metric).
Therefore, in a forged image you would find cloned regions, e.g. patches with identical or almost identical intensity distributions. To detect this, my naive approach would be to split the image up in many small subimages and use each one as a filter mask to be cross-correlated with the full image. I would expect authentic images to show only one more or less clear global maximum. A forged image would potentially produce two or more "global" maxima having a similar height.
But there seems to be a whole bunch of people having released some open source code for forgery detection, most probably using smarter approaches then mine -> Github topic: Fogery detection.

Using a TreeMap with images

For representing most popular artists from EchoNest API, I've been trying to set-up Silverlight Toolkit's TreeMap using images, their TreeItemDefinition.ValueBinding being defined as the area of the image.
While it mostly fills up the space when the image stretch is set to 'Fill' :
When setting image stretch to 'Uniform' a lot of blank spaces remain :
On this post, image carving is suggested : Treemapping with a given aspect ratio
How can I know which images should be carved and at what dimensions they should be carved if possible at all ?
Is this problem solvable without human intervention for a good result ?
I don't think there is a way to know which images should be carved and at what dimensions they should be carved. An ok-ish euristic might be to check if the mean energy of an image is > a certain threshold (this can be refined to check only blocks of every image, and combining the result later: if the image has blocks without details/energy, it can be carved, at least in that section).
What i think would be better is to apply seam carving to the already composed image: that will try to carve out the white outlines (adding "artificial" energy to the patches of images might lead to even better results, preserving more the shapes of each image). This paper might be of use to check out other image resizing methods too.

Pack images into a larger image

There are images (literally, PNG files), they come in different sizes and need to be put together into a larger image, so that (1) they don’t overlap, and (2) the amount of unused pixels is minimal.
Can someone point me in the right direction? I can imagine that packing rectangles is nothing new, but honestly, I cannot find neither an implementation nor an algorithm for this.
This is one algorithm: Fast optimizing rectangle packing algorithm for building CSS sprites. The article includes an explanation and C# code. It also links to a paper that might be interesting.

How can I measure the similarity between two images? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
I would like to compare a screenshot of one application (could be a Web page) with a previously taken screenshot to determine whether the application is displaying itself correctly. I don't want an exact match comparison, because the aspect could be slightly different (in the case of a Web app, depending on the browser, some element could be at a slightly different location). It should give a measure of how similar are the screenshots.
Is there a library / tool that already does that? How would you implement it?
This depends entirely on how smart you want the algorithm to be.
For instance, here are some issues:
cropped images vs. an uncropped image
images with a text added vs. another without
mirrored images
The easiest and simplest algorithm I've seen for this is just to do the following steps to each image:
scale to something small, like 64x64 or 32x32, disregard aspect ratio, use a combining scaling algorithm instead of nearest pixel
scale the color ranges so that the darkest is black and lightest is white
rotate and flip the image so that the lighest color is top left, and then top-right is next darker, bottom-left is next darker (as far as possible of course)
Edit A combining scaling algorithm is one that when scaling 10 pixels down to one will do it using a function that takes the color of all those 10 pixels and combines them into one. Can be done with algorithms like averaging, mean-value, or more complex ones like bicubic splines.
Then calculate the mean distance pixel-by-pixel between the two images.
To look up a possible match in a database, store the pixel colors as individual columns in the database, index a bunch of them (but not all, unless you use a very small image), and do a query that uses a range for each pixel value, ie. every image where the pixel in the small image is between -5 and +5 of the image you want to look up.
This is easy to implement, and fairly fast to run, but of course won't handle most advanced differences. For that you need much more advanced algorithms.
The 'classic' way of measuring this is to break the image up into some canonical number of sections (say a 10x10 grid) and then computing a histogram of RGB values inside of each cell and compare corresponding histograms. This type of algorithm is preferred because of both its simplicity and it's invariance to scaling and (small!) translation.
Use a normalised colour histogram. (Read the section on applications here), they are commonly used in image retrieval/matching systems and are a standard way of matching images that is very reliable, relatively fast and very easy to implement.
Essentially a colour histogram will capture the colour distribution of the image. This can then be compared with another image to see if the colour distributions match.
This type of matching is pretty resiliant to scaling (once the histogram is normalised), and rotation/shifting/movement etc.
Avoid pixel-by-pixel comparisons as if the image is rotated/shifted slightly it may lead to a large difference being reported.
Histograms would be straightforward to generate yourself (assuming you can get access to pixel values), but if you don't feel like it, the OpenCV library is a great resource for doing this kind of stuff. Here is a powerpoint presentation that shows you how to create a histogram using OpenCV.
Don't video encoding algorithms like MPEG compute the difference between each frame of a video so they can just encode the delta? You might look into how video encoding algorithms compute those frame differences.
Look at this open source image search application http://www.semanticmetadata.net/lire/. It describes several image similarity algorighms, three of which are from the MPEG-7 standard: ScalableColor, ColorLayout, EdgeHistogram and Auto Color Correlogram.
You could use a pure mathematical approach of O(n^2), but it will be useful only if you are certain that there's no offset or something like that. (Although that if you have a few objects with homogeneous coloring it will still work pretty well.)
Anyway, the idea is the compute the normalized dot-product of the two matrices.
C = sum(Pij*Qij)^2/(sum(Pij^2)*sum(Qij^2)).
This formula is actually the "cosine" of the angle between the matrices (wierd).
The bigger the similarity (lets say Pij=Qij), C will be 1, and if they're completely different, lets say for every i,j Qij = 1 (avoiding zero-division), Pij = 255, then for size nxn, the bigger n will be, the closer to zero we'll get. (By rough calculation: C=1/n^2).
You'll need pattern recognition for that. To determine small differences between two images, Hopfield nets work fairly well and are quite easy to implement. I don't know any available implementations, though.
A ruby solution can be found here
From the readme:
Phashion is a Ruby wrapper around the pHash library, "perceptual hash", which detects duplicate and near duplicate multimedia files
How to measure similarity between two images entirely depends on what you would like to measure, for example: contrast, brightness, modality, noise... and then choose the best suitable similarity measure there is for you. You can choose from MAD (mean absolute difference), MSD (mean squared difference) which are good for measuring brightness...there is also available CR (correlation coefficient) which is good in representing correlation between two images. You could also choose from histogram based similarity measures like SDH (standard deviation of difference image histogram) or multimodality similarity measures like MI (mutual information) or NMI (normalized mutual information).
Because this similarity measures cost much in time, it is advised to scale images down before applying these measures on them.
I wonder (and I'm really just throwing the idea out there to be shot down) if something could be derived by subtracting one image from the other, and then compressing the resulting image as a jpeg of gif, and taking the file size as a measure of similarity.
If you had two identical images, you'd get a white box, which would compress really well. The more the images differed, the more complex it would be to represent, and hence the less compressible.
Probably not an ideal test, and probably much slower than necessary, but it might work as a quick and dirty implementation.
You might look at the code for the open source tool findimagedupes, though it appears to have been written in perl, so I can't say how easy it will be to parse...
Reading the findimagedupes page that I liked, I see that there is a C++ implementation of the same algorithm. Presumably this will be easier to understand.
And it appears you can also use gqview.
Well, not to answer your question directly, but I have seen this happen. Microsoft recently launched a tool called PhotoSynth which does something very similar to determine overlapping areas in a large number of pictures (which could be of different aspect ratios).
I wonder if they have any available libraries or code snippets on their blog.
to expand on Vaibhav's note, hugin is an open-source 'autostitcher' which should have some insight on the problem.
There's software for content-based image retrieval, which does (partially) what you need. All references and explanations are linked from the project site and there's also a short text book (Kindle): LIRE
You can use Siamese Network to see if the two images are similar or dissimilar following this tutorial. This tutorial cluster the similar images whereas you can use L2 distance to measure the similarity of two images.
Beyond Compare has pixel-by-pixel comparison for images, e.g.,
If this is something you will be doing on an occasional basis and doesn't need automating, you can do it in an image editor that supports layers, such as Photoshop or Paint Shop Pro (probably GIMP or Paint.Net too, but I'm not sure about those). Open both screen shots, and put one as a layer on top of the other. Change the layer blending mode to Difference, and everything that's the same between the two will become black. You can move the top layer around to minimize any alignment differences.
Well a really base-level method to use could go through every pixel colour and compare it with the corresponding pixel colour on the second image - but that's a probably a very very slow solution.

Resources