What mean-stat-equation should I use when I have an image with N-number sample-size of selections?
I have a unique problem for which i was hoping to get some advice, so that i don't miss out on anything.
The Problem: To find the most favored/liked/important area on an image based on user selection of areas in different selection ratios.
Scenario: Consider an Image of a dog, and hundreds of users selecting area over this image in various resolutions, the obvious area of focus in most selections will be the area containing the dog. I can record the x1,x2,y1,y2 co-ordinates and put them into a db, now if i want to automatically generate versions of this image in a set of resolutions i should be able to recognize the area with the max attraction of the users.
The methods i think could work are:
Find the average center point of all selections and base the selection in that. - Very simple but would not be as accurate.
Use some algorithm like K Means or EM Clustering but i don't know which one would be best suited.
Looking forward to some brilliant solution to my problem
More info on the problem:
The Actual image will be most probably be a 1024x768 image, and the selections made on it will be of the most common mobile phone resolutions. The objective is to automatically generate mobile phone wallpapers by intelligent learning based on user selections.
I believe that you have two distinct problems identified above:
ONE: Identification of Points
For this, you will need to develop some sort of heuristic for identifying whether a point should be considered or not.
I believe you mentioned that hundreds of users will be selection locations over this image? Hundreds may be a lot of points to cluster. Consider excluding outliers (by removing points which do not have a certain number of neighbors within a particular distance)
Anything you can do to reduce your dataset will be helpful.
TWO: Clustering of Points
I believe that K Means Clustering would be best suited for this particular problem.
LINK
Your particular problem seems to closely mirror the standard Cartesian coordinate clustering examples used in explaining this algorithm.
What you're trying to do appears to be NP-Hard, but should be satisfied by the classical approximations.
Once clustered, you can take an average of the points within that cluster for a rather accurate approximation.
In Addition:
You dataset sounds like it will already be tightly clustered. (i.e. Most people will pick the dog's face, not the side of it's torso.) You need to be aware of local minima. LINK These can really throw a wrench into your algorithm. Especially with a small number of clusters. Be aware that you may need a bit of dynamic programming to combat this. You can usually introduce some variance into your algorithm, allowing the average points to "pop out" of these local minima. Local Minima/Maxima
Hope this helps!
I think you might be able to approach your problem in a different way. If you have not heard of Seam Carving then I suggest you check it out, because the data you have available to use is perfectly suited to it. The idea is that instead of cropping an image to resize it, you can instead remove paths of pixels that are not necessarily in a straight line. This allows you to resize an image while retaining more of the 'interesting' information.
Ordinarily you choose paths of least energy, where energy here is some measurement of how much the hue/intensity changes along the path. This will fail when you have regions of an image that are very important (like a dog's face), but where the energy of those regions is not necessarily very high. Since you have user data indicating what parts of the image are very important you can make sure to carve around those regions of the image by explicitly adding a little energy to a pixel every time someone selects a region with that pixel.
This video shows seam carving in action, it's cool to watch even if you don't think you'll use this. I think it's worth trying, though, I've used it before for some interesting resizing applications, and it's actually pretty easy to implement.
Related
I'm trying to work on an algorithm that will morph one "shape" into another "shape". Both shapes are arbitrary, and may even have smaller, disjointed shapes too.
The basic idea I have so far is as follows: locate the edges of the shape, place points all along those edges, then do the same with the target image, then move the points to their targets.
Here's an illustration:
I just don't know where to start. The image above is a simplification, actual use case has more complex shapes/outlines. My main problem is: How do I handle disjoint shapes? The best I can come up with is to figure out the closest point between the two pieces, and join them together as part of the path. But how would I implement this?
I don't have any code yet, I'm still at the planning phase for this. I guess what I'm asking for is if anyone can link me to any resources that may help, or give any pointers. Searching Google has yielded some interesting morph algorithms, but they all deal with full images and involve breaking the image into pieces to reshape them, which is not what I'm looking for.
Note that this will be used in JavaScript, but could be precomputed in PHP instead if it's easier.
It's best to break the problem into multiple smaller problems which can be solved independently. That way you also own independent functionalities after solving this problem, which can be added to some global module collection.
First we need to figure out which pixel in the from_shape goes to which pixel in the to_shape. We can figure that out with the following method:
Place to_shape over from_shape.
For every pixel in from_shape, find its closest to_shape pixel.
Every pixel in a shape must have a unique id, that id can be for instance, its xy location.
Now you can record each unique pixel in from_shape, and which unique pixel it goes to in to_shape.
Delete the overlapped shapes and go back to the original ones,
just now each pixel in from_shape knows its destination in to_shape.
We also need to know which 'siblings' each pixel has.
A sibling is a pixel that lies right next to another pixel.
To find it, go to a given pixel, collect all pixels in radius one from it, all of them which are black.. are the from-pixel's siblings. This information is necessary to keep the shape as a single unit when the pixels travel to their destination. Skipping the siblings would substantially speed up and simplify the morph, but without them the shape might become fragmented during morph. Might wanna begin with a siblingless version, see how that goes.
And finally we implement the morph:
There is morph_time_duration.
For each pixel in from_shape, find the distance to it's destination in to_shape.
That distance, divided by morph_time_duration, is the speed of the pixel during the morph.
Also, the angle towards destination is the angle to travel in.
So now you have speed and angle.
So at each frame in the morphing procedure, a given from_pixel now knows which direction to travel in, speed, and it also knows its siblings. So in each frame just draw the pixel in its new location, after having traveled at its speed in its direction. And then draw a line to all of that pixels siblings.
And that will display your morph.
I've found a demonstration (using Raphael.js) of outline morphing and motion tweening in JavaScript, showing how Raphael.js can be used to morph one curve into another curve.
Also, this related question (about shape tweening in JavaScript) may contain some answers that are relevant to this question.
The MorpherJS library may also be suitable for this purpose. Some demonstrations of outline morphing with MorpherJS can be found here.
Doing that wont be very easy, but I can give you a couple of starting points. If you want a plain javascript implementation a great starting point would be:
http://raphaeljs.com/animation.html
which is doing exactly what you want. So you can check what methods are invoked and browse through the library source for those methods to see the implementation.
If you instead need to morph 2 images in PHP, I would suggest you use some sort of an extension and not do that in plain PHP. Here is an example using ImageMagick to do it:
http://www.fmwconcepts.com/imagemagick/shapemorph2/index.php
If you want to know more about the internals of it:
http://web.mit.edu/manoli/www/ecimorph/ecimorph.html#algo
Hope one of those helps.
The short answer, if you're trying to roll your own, it's not a straightforward task. There's plenty of math out there on these topics that perform these very transformations (the most common you're find deal with the most common shapes, obviously), but that may or may not be accessible to you and it won't be as easy to figure out how to do the non-standard transformations.
If you're just looking for a logical approach, here's where I'd start (not having done the math in years, and not having studied the inner workings of the graphics libraries linked):
Choose a distance, measured in whatever units make sense, pixels perhaps.
Identify each continuous edge in each shape. Pick an arbitrary point on one edge for each shape (say, on a plane where (0,0) represents the upper left corner, the edge point on each shape closest to (0,0)), and align your separate shapes on that point. For the purposes of your transformation, that point will remain static and all other points will conform to it.
If your shape has two or more distinct edges, order them by perimeter length. Consider the shorter lengths to be subordinate to the longer lengths. Use a similar process as in step 2 to pick an arbitrary point to connect these two edges together.
At each of your chosen points, count points around your edges at the interval of the distance you selected in step 1.
(left as an exercise for the reader) conform your points on your disparate edges together and into the target shape, aligning, reducing or adding points on the edges as necessary.
Alternatively, you could select an arbitrary number of points instead of an arbitrary distance, and just spread them appropriately along the edges at whatever distance they will fit, and then conform those points together.
Just throwing some ideas out there, I don't honestly know how deep the problem goes.
I run a website with thousands of user-contributed photos on it. What I'd like is a script to help me weed out poor photos from good photos. Obviously this isn't 100% possible, but it should be possible to determine if an image has no discernable focussed area? I think?
I did a bit of googling and couldn't find much on the subject.
I've written a very simple script that iterates over the pixels, and sums the difference in brightness between neighbouring pixels. This gives a high value for sharp contrasty images, and a low value for blurred/out of focus images. It's far from ideal though, as if there's a perfectly focussed small subject in the frame, and a nice bokeh background, it'll give a low value.
So I think what I want is a script that can determine if a part of an image is well-focussed, and if none is then to alert me?
Any bright ideas? Am I wasting my time?
I'd be interested in any code that can determine other sorts of "bad" photos too - too dark, too light, too flat, that sort of thing.
Too dark and too light are easy - calculate a colour average as you iterate through every pixel.
For your focus issue, I think you're going to run into a lot of problems with this one. I would strongly recommend looking up kernel convolution, as I have a sinking feeling that you'll need it. This allows you to perform more complex operations on pixels based on neighbors - and is how most Photoshop filters are done!
Once you've got the maths background to do it, what I would do is to convert your image to an array of unique values (as opposed to RGB) representing brightness. From there, use an edge-finder kernel (Sobel operator should do the trick) and find the edges. Once that is done, iterate over again, mapping the bits with no edge, and calculate the largest square area without an edge from this. It is probably the least CPU-intensive solution, though not the most esoteric.
Is there a reliable way of detecting noise or artifacts in an image, consisting of text and images (page from a PDF file), while not harming the text or "real" pictures. Only removing the noise, specks, blotches, etc.?
In general, there is no reliable, non-destructive way -- this would mean to ask a computer program to "magically" know what's noise and what is not. However, there are methods that get close in practice.
One commonly applied method which is reasonably simple and often not very destructive is a small radius (3-5) median filter. A median filter is good at finding scratches or "wrong pixel" noise.
Another noise reducing method would be a bilateral filter, which in layman terms is basically a blur that respects features.
Yet another method to detect and filter noise would be akin to the technique Pixar used in their "wavelet noise" algorithm:
downsample the image (e.g. by one mip level, a.k.a. 1/2 in every direction)
subtract the downsampled image from the original (implicitly upsampling again)
what remains, the difference, is what couldn't be represented in the lower resolution image, thus noise
There's no statistical way which would exactly remove noise, you can use Super Resolution GANs though, make a sythetic data and train your model for noisy to clean images.
I have many files of a same picture in various resolution, suitable for every devices like mobile, pc, psp etc. Now I am trying to display only unique pictures in the page, but I dont know how to. I could have avoided this if I maintained a database at the first place, but I didn't. And I need your help detecting the largest unique pictures.
Install gd2 and lib puzzle in your server.
Lib puzzle is astonishing and easy to play with it. Check this snippet
<?php
# 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";
}
# Compress the signatures for database storage
$compress_cvec1 = puzzle_compress_cvec($cvec1);
$compress_cvec2 = puzzle_compress_cvec($cvec2);
Well, even thou there are quite a few algorithms to do that, i believe it would still be faster to do that manually. Download all the images feed them into something like windows live photo gallery or any other software which could match similar images.
This will take you few hours, but implementing image matching algorithm could take far more. After that you could spend extra time on amending your current system to store everything in a DB.
Fix cause of the problem, not it's symptoms.
Firstly, your problem has hardly anything to do with PHP, so I have removed that tag and added more relevant tags.
Smartly doing it will not require NxN comparisions. You can use lots of heuristics, but first I would like to ask you:
Are all the copies of one image exact resize of each other (is there some cropping done - matching cropped images to the original could be more difficult and time consuming)?
Are all images generated (resized) using the same tool?
What about parameters you have used to resize? For example, are all pictures for displaying on PSP in the same resolution?
What is your estimate of how many unique images you have (i.e, how many copies of each picture there might be - on an average)?
Do you have any kind of categorization already done. For example, are all mobile images in separate folder (or of different resolution than the PC images)? This alone could reduce the number of comparisons a lot, even if you do brute force otherwise.
A very top level hint on why you don't need NxN comparisions: you can devise many different approximate hashes (for example, the distribution of high/low frequency jpeg coefficients) and group "potentially" similar images together. This can reduce the number of comparisions required by 10-100 times or even more depending on the quality of heuristic used and the data set. The hashing can even be done on parts of images. 30000 is not a very large number if you use right techniques.
You should check which of the 2 images is the smallest, take the size of that and then compare only the pixels within the rectangle size.
I'm trying to find something, preferably F/OSS, that can generate a Google Maps overlay from KML and/or KMZ data.
We've got an event site we're working on that needed to accommodate ~16,000 place markers last year and will likely have at least that many again this year. Last year, the company that had done the site just fed the KML data directly to the gMaps API and let it place all of the markers client side. Obviously, that became a performance nightmare and tended to make older browsers "freeze" (or at least appear frozen for several minutes at a time).
Ideally this server side script would take the KML, the map's lat/lon center, and the map zoom level and appropriately merge all of the visible place markers into a single GIF or PNG overlay.
Any guidance or recommendations on this would be greatly appreciated.
UPDATE 10/8/2008 - Most of the information I've come across here and other places would seem to indicate that lessening the number of points on the map is the way to go (i.e. using one marker to represent several when viewing from a higher altitude/zoom level). While that's probably a good approach in some cases, it won't work here. We're looking for the visual impact of a US map with many thousand markers on it. One option I've explored is a service called PushPin, which when fed (presumably) KML will create, server side, an overlay that has all of the visible points (based on center lat/lon and zoom level) rendered onto a single image, so instead of performing several thousand DOM manipulations client side, we merge all of those markers into a single image server side and do a single DOM manipulation on the client end. The PushPin service is really slick and would definitely work if not for the associated costs. We're really looking for something F/OSS that we could run server side to generate that overlay ourselves.
You may want to look into something like Geoserver or Mapserver. They are Google map clones, and a lot more.
You could generate an overlay that you like, and Geoserver(I think mapserver does as well) can give you KML, PDF, png, and other output to mix your maps, or you could generate the whole map by yourself, but that takes time.
Not sure why you want to go to a GIF/PNG overlay, you can do this directly in KML. I'm assuming that most of your performance problem was being caused by points outside the user's current view, i.e. the user is looking at New York but you have points in Los Angeles that are wasting memory because they aren't visible. If you really have 16,000 points that are all visible at once for a typical then yes you'll need to pursue a different strategy.
If the above applies, the procedure would be as follows:
Determine the center & extent of the map
Given that you should be able to calculate the lat/long of the upper left and lower right corners of the map.
Iterate through your database of points and check each location against the two corners. Longitude needs to be greater (signed!) than the upper left longitude and less than the lower right longitude. Latitude needs to be less than the upper left latitude (signed!) and greater than the lower right latitude. Just simple comparisons, no fancy calculations required here.
Output the matching points to a temporary KML for the user.
You can feed KML directly into Google Maps and let it map it, or you can use the Javascript maps API to load the points via KML.
It might not solve your exact problem here, but for related issues you might also look into the Google Static Maps API. This allows you to create a static image file with placemarkers on it that will load very quickly, but won't have the interactivity of a regular Google map. Because of the way the API is designed, however, it can't handle anywhere near 16,000 points either so you'd still have to filter down to the view.
I don't know how fare you are with your project but maybe you can take a look at GeoDjango? This modified Django release includes all kinds of tools to store locations; convert coordinates and display maps, the easy way. Offcourse you need some Python experience and a server to run it on, but once you've got the hang of Django it works fast and good.
If you just want a solution for your problem try grouping your results at lower zoom levels, a good example of this implementation can be found here.
This is a tough one. You can use custom tilesets with Google Maps, but you still need some way to generate the tiles (other than manually).
I'm afraid that's all I've got =/
OpenLayers is a great javascript frontend to multiple mapping services or your own map servers. Version 2.7 was just released, which adds some pretty amazing features and controls.