Pyramid match kernel , partitioning the feature space - computer-vision

I am trying to implement the pyramid match kernel , and now I am stuck in a point .
I understand i need to partition the feature space into increasing larger bins , so that at higher levels multiple points[feature vectors] will map to a single bin. What I cant seem to figure out is what is how to partition a feature space. I understood the case where the feature vectors are 1 or 2 dimensional , but how to partition a d dimensional feature space.
I understand the question is vague , But I just dont know where else to ask.

i may be wrong here, but I guess the intuition is to quantize the feature space. So, you could basically do bag of words with different code book sizes (128,64,32...) and use their kernel to compute similarity between 2 images.

Related

Implementing Dynamic time warping for image matching

Let's say I have 2 images containing the Word "CAT" but with different sizes and i want to apply DTW to check that both images have the same words.
i used the code implemented here
http://bytefish.de/blog/dynamic_time_warping/
but the problem is that i only have 2 vectors and when these vectors have elements more than 800 the program crashes
so my question is:
Is it efficient to take the whole picture and put it into a vector and apply DTW for these 2 vectors ?
or shall I divide the pictures into slices(windows) and compare these slices with each others ? and in this case what if an image has 15 slice and the other has only 10 slices , how can i compare between them ?
finally if there's any source that explain implementing DTW for image matching please pass it to me.

Declarative Data Mining: Frequent Itemset Tiling

For a course in my Computer Science studies, I have to come up with a set of constraints and a score-definition to find a tiling for frequent itemset mining. The matrix with the data consists of ones and zeroes.
My task is to come up with a set of constraints for the tiling (having a fixed amount of tiles), and a score-function that needs to be maximized. Since I started working out a solution that allows overlapping tiles, I tried to find a score-function to calculate the total "area" of all tiles. Bear in mind that the score function has to be evaluated for every possible solution, so I can't simply go over the total matrix (which contains about 100k elements) and see if it is part of a tile.
However, I only took into account overlap between only 2 tiles, and came up with the following:
TotalArea = Sum_a_in_Tiles(Area(a)) - Sum_a/b_in_tiles(Overlap(a,b))
Silly me, I didn't consider a possible overlap between 3 tiles. My question is the following:
Is it possible to come up with a generic score-function for n tiles, considering only area per tile and area per overlap between 2 (or more) tiles, and if so, how would I program it?
I could provide some code, but then again it has to be programmed in some obscure language called Comet :(

Algorithm and data structure to find and store superpixels' neighborhood in C++

I have an image, holding results of segmentation, like this one.
I need to build a graph of neighborhood of patches, colored in different colors.
As a result I'd like a structure, representing the following
Here numbers represent separate patches, and lines represent patches' neighborhood.
Currently I cannot figure out where to start, which keywords to google.
Could anyone suggest anything useful?
Image is stored in OpenCV's cv::Mat class, as for graph, I plan to use Boost.Graph library.
So, please, give me some links to code samples and algorithms, or keywords.
Thanks.
Update.
After a coffee-break and some discussions, the following has come to my mind.
Build a large lattice graph, where each node corresponds to each image pixel, and links connect 8 or 4 neighbors.
Label each graph node with a corresponding pixel value.
Try to merge somehow nodes with the same label.
My another problem is that I'm not familiar with the BGL (but the book is on the way :)).
So, what do you think about this solution?
Update2
Probably, this link can help.
However, the solution is still not found.
You could solve it like that:
Define regions (your numbers in the graph)
make a 2D array which stores the region number
start at (0/0) and set it to 1 (region number)
set the whole region as 1 using floodfill algorithm or something.
during floodfill you probably encounter coordinates which have different color. store those inside a queue. start filling from those coordinates and increment region number if your previous fill is done.
.
Make links between regions
iterate through your 2D array.
if you have neighbouring numbers, store the number pair (probably in a sorted manner, you also have to check whether the pair already exists or not). You only have to check the element below, right and the one diagonal to the right, if you advance from left to right.
Though I have to admit I don't know a thing about this topic.. just my simple idea..
You could use BFS to mark regions.
To expose cv::Mat to BGL you should write a lot of code. I think writeing your own bfs is much more simplier.
Than you for every two negbours write their marks to std::set<std::pair<mark_t, mark_t>>.
And than build graph from that.
I think that if your color patches are that random, you will probably need a brute force algorithm to do what you want. An idea could be:
Do a first brute force pass. This has to identify all the patches. For example, make a matrix A of the same size as the image, and initialize it to 0. For each pixel which is still zero, start from it and mark it as a new patch, and try a brute force approach to find the whole extent of the patch. Each matrix cell will then have a value equal to the number of the patch it is in it.
The patch numbers have to be 2^N, for example 1, 2, 4, 8, ...
Make another matrix B of the size of the image, but each cell holds two values. This will represent the connection between pixels. For each cell of matrix B, the first value will be the absolute difference between the patch number in the pixel and the patch number of an adjacent pixel. First value is difference with the pixel below, second with the pixel to the left.
Pick all unique values in matrix B, you have all the connections possible.
This works because each difference between patches number is unique. For example, if in B you end up with numbers 3, 6, 7 it will mean that there are contacts between patches (4,1), (8,2) and (8,1). Value 0 of course means that there are two pixels in the same patch next to each other, so you just ignore them.

Select all points in a matrix within 30m of another point

So if you look at my other posts, it's no surprise I'm building a robot that can collect data in a forest, and stick it on a map. We have algorithms that can detect tree centers and trunk diameters and can stick them on a cartesian XY plane.
We're planning to use certain 'key' trees as natural landmarks for localizing the robot, using triangulation and trilateration among other methods, but programming this and keeping data straight and efficient is getting difficult using just Matlab.
Is there a technique for sub-setting an array or matrix of points? Say I have 1000 trees stored over 1km (1000m), is there a way to say, select only points within 30m radius of my current location and work only with those?
I would just use a GIS, but I'm doing this in Matlab and I'm unaware of any GIS plugins for Matlab.
I forgot to mention, this code is going online, meaning it's going on a robot for real-time execution. I don't know if, as the map grows to several miles, using a different data structure will help or if calculating every distance to a random point is what a spatial database is going to do anyway.
I'm thinking of mirroring the array of trees, into two arrays, one sorted by X and the other by Y. Then bubble sorting to determine the 30m range in that. I do the same for both arrays, X and Y, and then have a third cross link table that will select the individual values. But I don't know, what that's called, how to program that and I'm sure someone already has so I don't want to reinvent the wheel.
Cartesian Plane
GIS
You are looking for a spatial database like a quadtree or a kd-tree. I found two kd-tree implementations here and here, but didn't find any quadtree implementations for Matlab.
The simple solution of calculating all the distances and scanning through seems to run almost instantaneously:
lim = 1;
num_trees = 1000;
trees = randn(num_trees,2); %# list of trees as Nx2 matrix
cur = randn(1,2); %# current point as 1x2 vector
dists = hypot(trees(:,1) - cur(1), trees(:,2) - cur(2)); %# distance from all trees to current point
nearby = tree_ary((dists <= lim),:); %# find the nearby trees, pull them from the original matrix
On a 1.2 GHz machine, I can process 1 million trees (1 MTree?) in < 0.4 seconds.
Are you running the Matlab code directly on the robot? Are you using the Real-Time Workshop or something? If you need to translate this to C, you can replace hypot with sqr(trees[i].x - pos.x) + sqr(trees[i].y - pos.y), and replace the limit check with < lim^2. If you really only need to deal with 1 KTree, I don't know that it's worth your while to implement a more complicated data structure.
You can transform you cartesian coordinates into polar coordinates with CART2POL. Then selecting points inside certain radius will be strait-forward.
[THETA,RHO] = cart2pol(X-X0,Y-Y0);
selected = RHO < 30;
where X0, Y0 are coordinates of the current location.
My guess is that trees are distributed roughly evenly through the forest. If that is the case, simply use 30x30 (or 15x15) grid blocks as hash keys into an closed hash table. Look up the keys for all blocks intersecting the search circle, and check all hash entries starting at that key until one is flagged as the last in its "bucket."
0---------10---------20---------30--------40---------50----- address # line
(0,0) (0,30) (0,60) (30,0) (30,30) (30,60) hash key values
(1,3) (10,15) (3,46) (24,9.) (23,65.) (15,55.) tree coordinates + "." flag
For example, to get the trees in (0,0)…(30,30), map (0,0) to the address 0 and read entries (1,3), (10,15), reject (3,46) because it's out of bounds, read (24,9), and stop because it's flagged as the last tree in that sector.
To get trees in (0,60)…(30,90), map (0,60) to address 20. Skip (24, 9), read (23, 65), and stop as it's last.
This will be quite memory efficient as it avoids storing pointers, which would otherwise be of considerable size relative to the actual data. Nevertheless, closed hashing requires leaving some empty space.
The illustration isn't "to scale" as in reality there would be space for several entries between the hash key markers. So you shouldn't have to skip any entries unless there are more trees than average in a local preceding sector.
This does use hash collisions to your advantage, so it's not as random as a hash function typically is. (Not every entry corresponds to a distinct hash value.) However, as dense sections of forest will often be adjacent, you should randomize the mapping of sectors to "buckets," so a given dense sector will hopefully overflow into a less dense one, or the next, or the next.
Additionally, there is the issue of empty sectors and terminating iteration. You could insert a dummy tree into each sector to mark it as empty, or some other simple hack.
Sorry for the long explanation. This kind of thing is simpler to implement than to document. But the performance and the footprint can be excellent.
Use some sort of spatially partitioned data structure. A simple solution would be to simply create a 2d array of lists containing all objects within a 30m x 30m region. Worst case is then that you only need to compare against the objects in four of those lists.
Plenty of more complex (and potentially beneficial) solutions could also be used - something like bi-trees are a bit more complex to implement (not by much though), but could get more optimum performance (especially in cases where the density of objects varies considerably).
You could look at the voronoi diagram support in matlab:
http://www.mathworks.com/access/helpdesk/help/techdoc/ref/voronoi.html
If you base the voronoi polygons on your key trees, and cluster the neighbouring trees into those polygons, that would partition your search space by proximity (finding the enclosing polygon for a given non-key point is fast), but ultimately you're going to get down to computing key to non-key distances by pythagoras or trig and comparing them.
For a few thousand points (trees) brute force might be fast enough if you have a reasonable processor on board. Compute the distance of every other tree from tree n, then select those within 30'. This is the same as having all trees in the same voronoi polygon.
Its been a few years since I worked in GIS but I found the following useful: 'Computational Geometry In C' Joseph O Rourke, ISBN 0-521-44592-2 Paperback.

Finding the spread of each cluster from Kmeans

I'm trying to detect how well an input vector fits a given cluster centre. I can find the best match quite easily (the centre with the minimum euclidean distance to the input vector is the best), however, I now need to work how good a match that is.
To do this I need to find the spread (standard deviation?) of the vectors which build up the centroid, then see if the distance from my input vector to the centre is less than the spread. If it's more than the spread than I should be able to say that I have no clusters to fit it (given that the best doesn't fit the input vector well).
I'm not sure how to find the spread per cluster. I have all the centre vectors, and all the training vectors are labelled with their closest cluster, I just can't quite fathom exactly what I need to do to get the spread.
I hope that's clear? If not I'll try to reword it!
TIA
Ian
Use the distance function and calculate the distance from your center point to each labeled point, then figure out the mean of those distances. That should give you the standard deviation.
If you switch to using a different algorithm, such as Mixture of Gaussians, you get the spread (e.g., std. deviation) as part of the model (clustering result).
http://home.deib.polimi.it/matteucc/Clustering/tutorial_html/mixture.html
http://en.wikipedia.org/wiki/Mixture_model