Reputation: 10701
I'm working on a photographic mosaic algorithm. There are 4 steps involved:
The whole process is relatively straightforward, however Step 2 involves comparing n images with m segments, with n >> m. This is by far the most time intensive step.
Here is the process I go through for each segment-candidate pair:
Bitmap
created with Graphics.DrawImage(Image, Rectangle, Rectangle, GraphicsUnit)
, I convert the bitmap data into red, green, and blue int[,]
matrices for the segment of the original image. I use the LockBits()
method instead of the GetPixel()
method as it is vastly faster. To reduce computation time, these matrices are only about 3x3 or 5x5 rather than the full dimensions of the original segment.int[,]
matrices.cost = 0
, I add the magnitude of the difference of the red, green, and blue values of the source and candidate image segments to the cost. The sum of these absolute differences is the assignment cost.In reality, I check each candidate image with all 16 RotateFlipType
transformations, so there are 16*n*m comparisons needed, where n = the number of segments and m = the number of placement regions.
I'm wondering whether I can perhaps do an FFT of each image and rather than comparing each pixel, I compare the low frequency components only, as the high frequency components will not substantially affect the output. On the other hand a lot of the overhead such as getting the sub-images and converting them to matrices are still there, and my gut tells me a spectral comparison will be slower than basic comparison of 25 int
values.
Upvotes: 0
Views: 902
Reputation: 51845
At first I would do a huge speed up by
create info for each image like:
average color, r/g/b histograms I think 8 or 16 points per channel will suffice. You can add any other info (darkest/brightest color,...) but it should be rotation/flip invariant
index sort the images by average color
limit the R,G,B to few bits only like 4 ... and create single integer number from it like
col=R+(G<<4)+(B<<8);
and finally index sort used images by this number
comparison
so binary search the index sorted images (if you create table of indexes per each reduced color then this will be also reduced to O(1)
) and find only images with close or equal average color as your segment.
Then find closest matches to histogram from these and then apply all you have only on those images...
The histogram comparison can be done by correlation coefficient or by any distance,or statistical deviation ...
As for the FFT part of your question I think it is more or less already answered by comments. Yes you can use it but I think it is an overkill for this. The overhead is huge but you can rescale images to low resolution and use FFT on that or just compare low res images only instead
[Notes]
Also using HSV instead of RGB could improve visual similarity
Upvotes: 2