Basically I want to find the pixel location of a small image inside a large image.
I have searched for something similar to this but have had no luck.
It depends on how similar you want the result to match your query image. If you're trying to match corresponding parts of different photorealistic images, take a look at the Feature detection Wikipedia page. What you want to use depends on the transformation you expect one image to undergo to become the other.
That said, if you are looking for an exact pixel-by-pixel match, a brute-force search is probably bad. That can be O(m^2*n^2) for an m*m image used to search within an n*n image. Using better algorithms, it can be improved to O(n^2), linear in the number of pixels. Downsampling both images and doing a hierarchical kind of search might be a good approach.
You could probably use the AForge Framework to do something like this. It offers a variety of image processing tools. Possibly you could use their blob extraction to extracts blobs then compare those blobs to a stored image you have and see if they match.
If the images are pixel-by-pixel equal, you could start by searching for one pixel that has the same color as pixel (0,0) in the small image. Once found, compare each pixel in the area that would be covered by the small image. If there are no differences you found your position. Else start over by searching for the next pixel matching (0,0).
Booyer-Moore search sounds like a solution here if you treat your pixels as characters and are looking for an exact match. Much faster than per pixel searching as well.
Related
I have an image that is a depth heatmap that I've filtered out anything further away than the first 25% of the image.
It looks something like this:
There are two blobs of color in the image, one is my hand (with part of my face behind it), and the other is the desk in the lower left corner. How can I search the image to find these blobs? I would like to be able to draw a rectangle around them if possible.
I can also do this (ignore shades, and filter to black or white):
Pick a random pixel as a seed pixel. This becomes area A. Repeatedly expand A until A doesn't get any bigger. That's your area.
The way to expand A is by looking for neighbor pixels to A, such that they have similar color to at least one neighboring pixel in A.
What "similar color" means to you is somewhat variable. If you can make exactly two colors, as you say in another answer, then "similar" is "equal". Otherwise, "similar" would mean colors that have RGB values or whatnot where each component of the two colors is within a small amount of each other (i.e. 255, 128, 128 is similar to 252, 125, 130).
You can also limit the selected pixels so they must be similar to the seed pixel, but that works better when a human is picking the seed. (I believe this is what is done in Photoshop, for example.)
This can be better than edge detection because you can deal with gradients without filtering them out of existence, and you don't need to process the resulting detected edges into a coherent area. It has the disadvantage that a gradient can go all the way from black to white and it'll register as the same area, but that may be what you want. Also, you have to be careful with the implementation or else it will be too slow.
It might be overkill for what you need, but there's a great wrapper for C# for the OpenCV libraries.
I have successfully used OpenCV in C++ for blob detection, so you might find it useful for what you're trying to do.
http://www.emgu.com/wiki/index.php/Main_Page
and the wiki page on OpenCV:
http://en.wikipedia.org/wiki/OpenCV
Edited to add: Here is a blobs detection library for Emgu in C#. There is even some nice features of ordering the blobs by descending area (useful for filtering out noise).
http://www.emgu.com/forum/viewtopic.php?f=3&t=205
Edit Again:
If Emgu is too heavyweight, Aforge.NET also includes some blob detection methods
http://www.aforgenet.com/framework/
If the image really is only two or more distinct colours (very little blur between colours), it is an easy case for an edge detection algorithm.
You can use something like the code sample from this question : find a color in an image in c#
It will help you find the x/y of specific colors in your image. Then you could use the min x/max x and the min y/max y to draw your rectangles.
Detect object from image based on object color by C#.
To detect a object based on its color, there is an easy algorithm for that. you have to choose a filtering method. Steps normally are:
Take the image
Apply ur filtering
Apply greyscalling
Subtract background and get your objects
Find position of all objects
Mark the objects
First you have to choose a filtering method, there are many filtering method provided for C#. Mainly I prefer AForge filters, for this purpose they have few filter:
ColorFiltering
ChannelFiltering
HSLFiltering
YCbCrFiltering
EuclideanColorFiltering
My favorite is EuclideanColorFiltering. It is easy and simple. For information about other filters you can visit link below. You have to download AForge dll for apply these in your code.
More information about the exact steps can be found here: Link
At the moment I've got an database with over 100.000 images, they ain't the same size or anything like that but I want to make the following for my compagny:
I insert/upload an image and the system returns the image which is most likely the same. I don't know what algorithm to use but it needs to be fast. I can pre-process all the other images and put some info in the database which I use for the comparison.
Now what I want to know what the fastest way is to compare the images (with a good chance of being the same image). And what data I should save into the database (I could probably figure this one out myself if I got the algorithm).
It shouldn't take more then 5 minutes to compare the uploaded image to all the images in the database.
Thanks in advance!
Julian
Look at www.tineye.com, they have some kind of algorithm that I'm looking for. Guessing they use a very complex one, I just need one that does same thing but with lesser rate of succes.
The way I would do it is I'd generate a really small (say.. 1/50 of the original image size) image from every image you're comparing against, and store the thumbnail image path along with the original size in the database. I'd keep the thumbnails as uncompressed bmp's for speed and loss-free-ness (I just made that word up!), since they're so small anyway.
To compare your new image against the other ones, shrink it down by the same amount and compare it against the others pixel by pixel, with a certain threshold (say.. 10% difference from the original).
If it passes this test, you can do a full blown pixel by pixel compare against the original image.
edit: I just want to mention that I went down the probabilistic way before too. It worked OK, but building the meta data for the images took forever, and there were a lot of false positives. Instinctively, I think that calculating local averages for each grid rectangle of your image (which is what shrinking your image down does) would give similar, if not better results.
The best way for comparison is convert image to gray scale format and compare intensity of gray color. Its the fastest way used in real-time systems.
Also if you want to achieve higher qaullity and use colored images - use CIE 1994 or CIE 2000 as color difference formula
We're currently creating a simple application for image manipulation in Silverlight, and we've hit a bit of a snag. We want users to be able to select an area of an image (either by drawing a freehand line around their chosen area or by creating a polygon around it), and then be able to apply effects to the pixels within that selection.
Creating a selection of images is easy enough, but we want a really fast algorithm for deciding which pixels should be manipulated (ie. something to detect which pixels are within the user's selection).
We've thought of three possibilities so far, but we're sure that there must be a really efficient and quick way of doing this that's better than these.
1. Pixel by pixel.
We just go through every pixel in an image and check whether it's within the user selection. Obviously this is far too slow!
2. Using a Line Crossing Algorithim.
The type of thing seen here.
3. Flood Fill.
Select the pixels along the path of the selection and then perform a flood fill within that selection. This might work fine.
This must a problem that's commonly solved, so we're guessing there's a ton more solutions that we've not even thought of.
What would you recommend?
Flood fill algorithm is a good choice.
Take a look at this implementation:
Queue-Linear Flood Fill: A Fast Flood Fill Algorithm
You should be able to use your polygon to create a clipping path. The mini-language for describing polygons for Silverlight is quiet well documented.
Alter the pixels on a copy of your image (all pixels is usually easy to modify than some pixels), then use the clipping path to render only the desired area of the changes back to the original image (probably using an extra buffer bitmap for the result).
Hope this helps. Just throwing the ideas out and see if any stick :)
How can we identify that a given image is blur or how much percent is it blur in C#? Is there any API available for that? Or any algorithm that can be helpful in that?
Thanks!
You could perform a 2D-FFT and search the frequency coefficients for a value over a certain threshold (to elimate false-positives from rounding/edge errors). A blurred image will never have high frequency coefficients (large X/Y values in frequency-space).
If you want to compare with a certain blurring algorithm, run a single pixel through a 2D-FFT and check further images to see if they have frequency components outside the range of the reference FFT. This means you can use the same algorithm regardless of what type of blurring algorithm is used (box blur, gaussian, etc)
For a very specific problem (finding blurred photos shot to an ancient book), I set up this script, based on ImageMagick:
https://gist.github.com/888239
Given a blurred bitmap alone, you probably can't.
Given the original bitmap and the blurred bitmap you could compare the two pixel by pixel and use a simple difference to tell you how much it is blurred.
Given that I'm guessing you don't have the original image, it might be worthing looking at performing some kind of edge detection on the blurred image.
This Paper suggests a method using Harr Wavelet Transform, but as other posters have said, this is a fairly complex subject.
Although, I am posting this answer after 8-9 years after asking the question. At that time, I resolved this problem by applying blur on image and then comparing with the original one.
The idea is, when we apply blur on a non-blurry image and then compare them, the difference in images is very high. But when we apply blur on a blurry image, the difference in images is almost 10%.
In this way, we resolved our problem of identifying blur images and the results were quite good.
Results were published in following conference paper:
Creating digital life stories through activity recognition with image filtering (2010)
Err ... do you have the original image? What you ask is not a simple thing to do, though ... if its even possible
This is just a bit of a random though but you might be able to do it by fourier transforming the "blurred" and the original image and seeing if you can get something that has a very similar frequency profiles by progressively low pass filtering the original image in the frequency domain. Testing for "similarity" would be fairly complex in itself though.
At some long-ago Flash conferences I recall seeing a demo of a Flash app that had a color picker. Based on the user's color choice the app would show the user a set of images within the approximate range of that color: a bunch of mostly red images, a bunch of mostly blue images, etc.
I'm looking for two things:
1) A link to a demo of this sort of app, ideally a Flash app
2) ActionScript or C# code that describes how to pick a bunch of images that fall within a color range.
I know how to extract the aggregate/average RGB from individual images and persist this info to a database. I need to know how exactly to select out images within a certain range of color tolerance. Could this be done purely using SQL and a knowledge of the alphanumeric assignments of RGB color codes, or is there a better way?
I could not find any sample code, but found an article that gives a high-level explanation of their process (from this other page about Flickr's feature to search for images with similar colors). Apparently, Google also lets you do this with their image search (but I don't know if that is from metadata tags or actual color matching).
Now to the actual answer:
Instead of just storing the average or aggregate color for an image, you will need to store a "color signature" of the image.
My first (educated guess) idea would entail these steps:
Generate the histogram for each color band from the image
Generate some factors that describe each histogram curve (mean, variance, std-dev, etc? -- these factors will make up your digital signature of your image)
Store those factors in your database (and each of these factors would have an index in the DB)
Then, you would take your input (either a color, range of colors, or source image), run your histogram algorithm against that source, and search for matches to your computed factors.
The Flickr Hacks solution I cite in the comments is the best I've found: it involves resizing the image to 1x1 pixels using common algorithms which gives you an average color for the entire image. Clever.
You can use a set of descriptors for each image, then match those.
There's some great work here on it.. for C#.
http://savvash.blogspot.com/p/compact-composite-descriptors.html
Also check out the free img(Rummager) tool.. which can do what you want(ie find images matched by colour).