h3Line function throws LineUndefinedException - uber-api

I want to calculate index of the h3 cells between (-39.08, -57.01) and (-38.05, -58.16) but it throws LineUndefinedException.
In the documentation it says
This function may fail to find the line between two indexes, for example if they are very far apart. It may also fail when finding distances for indexes on opposite sides of a pentagon.
I think that it throws the exception because of the latter case. Is there workaround to calculate those cell indexes?
Code:
public static void main(String[] args) {
try {
H3Core h3Core = H3Core.newInstance();
long p1 = h3Core.geoToH3(-39.08, -57.01, 8);
long p2 = h3Core.geoToH3(-38.05, -58.16, 8);
List<Long> line = h3Core.h3Line(p1, p2);
} catch (Exception e) {
e.printStackTrace();
}
}
Exception:
com.uber.h3core.exceptions.LineUndefinedException: Could not compute line size between cells
at com.uber.h3core.H3Core.h3Line(H3Core.java:630)

You have hit one of the edge cases H3 does not handle (yet), points on opposite sides of a pentagon:
The image above shows the edges of the icosahedron the H3 grid is based on. Pentagons are located at the vertexes of the icosahedron, and your points cross these edges in a way that makes it harder to compute the grid path.
The correct workaround here, which we eventually intend to implement in the library, is to find the intersection points between the great arc linking the two points and the icosahedron edges. To do this, you'd need the icosahedron geometry, which is available in the H3 lib but slightly hard to extract. There's a version here which has a bunch of unnecessary intermediate points in each edge (to facilitate rendering great arcs correctly on web maps), but which should work. The basic algorithm is:
Find all intersection points along the great arc between point A and point B.
For each point, find the H3 index.
Find the h3Line between each segment, e.g. h3Line(cellA, cellIntersection1), h3Line(cellIntersection1, cellIntersection2), and so on.
Combine the lines, dropping duplicate indexes.
There is likely an easier option here, which is to do the same thing but instead of calculating indexes just sample along the great arc. In this particular case, it looks like you probably could just take the center of the great arc and calculate h3Line twice, but in some cases you'd need more samples.

Related

Why do MSER results have overlapping pixels

First, I'm using opencv MSER via matlab via 2 different methods:
Through the matlab's detectMSERFeatures function. This seems to call the
opencv MSER (via the call to ocvExtractMSER in the detectMSERFeatures function)
Through a more direct approach: opencv 3.0 wrapper/matlab bindings found in https://github.com/kyamagu/mexopencv
Either way, I can get back lists of lists of pixels (aka regions) that I imagine are a translation of the opencv MSER::detectRegions 2nd arg, "std::vector< std::vector< Point > > &msers"
The result can end up a list of multiple regions each region with its own set of points. However, the points of the regions are not mutually exclusive. In fact, they typically, for my data in which the foreground is typically roundish blobs, tend to all be part of the same single connected component. This is true even if the blob doesn't even have any holes (I might understand if the regions corresponded to contours and the blob had holes).
I'm assuming that this many-region-to-one mapping of regions to even a solid blob is due to opencv's MSER, in its native C++(?) implementation, doing the same but I confess I haven't verified that (but I surely don't understand it.)
So, does anybody know why MSER would yield multiple overlapping regions for a single solid connected component? Is there any sense to choosing one and if so how? (Right now I just combine them all)
EDIT - I tried an image with one blob which then I replicated to have a single image where the left half was the same as the right (each half being the same, each with the same blob). MSER returned 9 lists/regions all corresponding to the two blobs. So, I wold have to do connected component analysis just to figure out which subsets of the regions belonged to what blob and so apparently there can't be any straightforward way to choose a particular subset of the returned regions that would give the best representation of the two blobs (if such a thing was even sensible if you knew there was just one blob as per my last pre-edit question)
The picture below was made by plotting all 4 regions (lists of points) returned for my single blob image. The overlay was created by:
obj = cv.MSER('MinArea',20,'MaxArea',3000,'Delta',2.5);
[chains, bboxes] = obj.detectRegions(Region8b)
a=cellfun(#(x) cat(1,x{:}),chains,'UniformOutput',false) % get rid of extra layer of cells that detectRegions seems to give it.
% b=cat(1,a{:}); % all the regions points in a single list. Not used here.
ptsstrs={'rx','wo','cd','k.'};
for k=1:4
plot(a{k}(:,1),a{k}(:,2),ptsstrs{k},'MarkerSize',15);
end
So, you can see they overlap but there also seems to be an order to it where I think each subsequent region/list is a superset of the list before it.
"The MSER detector incrementally steps through the intensity range of the input image to detect stable regions. The ThresholdDelta parameter determines the number of increments the detector tests for stability. " This from Matlab help. It's reasonable that you find overlap and subsets. Apparently, the region changes as the algorithm moves up or down in intensity.

Hashing a graph to find duplicates (including rotated and reflected versions)

I am making a game that involves solving a path through graphs. Depending on the size of the graph this can take a little while so I want to cache my results.
This has me looking for an algorithm to hash a graph to find duplicates.
This is straightforward for exact copies of a graph, I simply use the node positions relative to the top corner. It becomes quite a bit more complicated for rotated or even reflected graphs. I suspect this isn't a new problem, but I'm unsure of what the terminology for it is?
My specific case is on a grid, so a node (if present) will always be connected to its four neighbors, north, south, east and west. In my current implementation each node stores an array of its adjacent nodes.
Suggestions for further reading or even complete algorithms are much appreciated.
My current hashing implementation starts at the first found node in the graph which depends on how i iterate over the playfield, then notes the position of all nodes relative to it. The base graph will have a hash that might be something like: 0:1,0:2,1:2,1:3,-1:1,
I suggest you do this:
Make a function to generate a hash for any graph, position-independent. It sounds like you already have this.
When you first generate the pathfinding solution for a graph, cache it by the hash for that graph...
...Then also generate the 7 other unique forms of that graph (rotated 90deg; rotated 270deg; flipped x; flipped y; flipped x & y; flipped along one diagonal axis; flipped along the other diagonal axis). You can of course generate these using simple vector/matrix transformations. For each of these 7 transformed graphs, you also generate that graph's hash, and cache the same pathfinding solution (which you first apply the same transform to, so the solution maps appropriately to the new graph configuration).
You're done. Later your code will look up the pathfinding solution for a graph, and even if it's an alternate (rotated, flipped) form of the graph you found the earlier solution for, the cache already contains the correct solution.
I spent some time this morning thinking about this and I think this is probably the most optimal solution. But I'll share the other over-analyzed versions of the solution that I was also thinking about...
I was considering the fact that what you really needed was a function that would take a graph G, and return the "canonical version" of G (which I'll call G'), AND the transform matrix required to convert G to G'. (It seemed like you would need the transform so you could apply it to the pathfinding data and get the correct path for G, since you would have just stored the pathfinding data for G'.) You could, of course, look up pathfinding data for G', apply the transform matrix to it, and have your pathfinding solution.
The problem is that I don't think there's any unambiguous and performant way to determine a "canonical version" of G, because it means you have to recognize all 8 variants of G and always pick the same one as G' based on some criteria. I thought I could do something clever by looking at each axis of the graph, counting the number of points along each row/column in that axis, and then rotating/flipping to put the more imbalanced half of the axis always in the top-or-left... in other words, if you pass in "d", "q", "b", "d", "p", etc. shapes, you would always get back the "p" shape (where the imbalance is towards the top-left). This would have the nice property that it should recognize when the graph was symmetrical along a given axis, and not bother to distinguish between the flipped versions on that axis, since they were the same.
So basically I just took the row-by-row/column-by-column point counts, counting the points in each half of the shape, and then rotating/flipping until the count is higher in the top-left. (Note that it doesn't matter that the count would sometimes be the same for different shapes, because all the function was concerned with was transforming the shape into a single canonical version out of all the different possible permutations.)
Where it fell down for me was deciding which axis was which in the canonical case - basically handling the case of whether to invert along the diagonal axis. Once again, for shapes that are symmetrical about a diagonal axis, the function should recognize this and not care; for any other case, it should have a criteria for saying "the axis of the shape that has the property [???] is, in the canonical version, the x axis of the shape, while the other axis will be the y axis". And without this kind of criteria, you can't distinguish two graphs that are flipped about the diagonal axis (e.g. "p" versus "σ"/sigma). The criteria I was trying to use was again "imbalance", but this turned out to be harder and harder to determine, at least the way I was approaching it. (Maybe I should have just applied the technique I was using for the x/y axes to the diagonal axes? I haven't thought through how that would work.) If you wanted to go with such a solution, you'd either need to solve this problem I failed to solve, or else give up on worrying about treating versions that are flipped about the diagonal axis as equivalent.
Although I was trying to focus on solutions that just involved calculating simple sums, I realized that even this kind of summing is going to end up being somewhat expensive to do (especially on large graphs) at runtime in pathfinding code (which needs to be as performant as possible, and which is the real point of your problem). In other words I realized that we were probably both overthinking it. You're much better off just taking a slight hit on the initial caching side and then having lightning-fast lookups based on the graph's position-independent hash, which also seems like a pretty foolproof solution as well.
Based on the twitter conversation, let me rephrase the problem (I hope I got it right):
How to compare graphs (planar, on a grid) that are treated as invariant under 90deg rotations and reflection. Bonus points if it uses hashes.
I don't have a full answer for you, but a few ideas that might be helpful:
Divide the problem into subproblems that are independently solvable. That would make
How to compare the graphs given the invariance conditions
How to transform them into a canonical basis
How to hash this canonical basis subject to tradeoffs (speed, size, collisions, ...)
You could try to solve 1 and 2 in a singe step. A naive geometric approach could be as follows:
For rotation invariance, you could try to count the edges in each direction and rotate the graph so that the major direction always point to the right. If there is no main direction you could see the graph as a point cloud of its vertices and use Eigenvectors and Priciple Compoment Analysis (PCA) to obtain the main direction and rotate it accordingly.
I don't have a smart solution for the reflection problem. My brute force way would be to just create the reflected graph all the time. Say you have a graph g and the reflected graph r(g). If you want to know if some other graph h == g you have to answer h == g || h == r(g).
Now onto the hashing:
For the hashing you probably have to trade off speed, size and collisions. If you just use the string of edges, you are high on speed and size and low on collisions. If you just take this string and apply some generic string hasher to it, you get different results.
If you use a short hash, with more frequent collisions, you can get achieve a rather small cost for comparing non matching graphs. The cost for matching graphs is a bit higher then, as you have to do a full comparison to see if they actually match.
Hope this makes some kind of sense...
best, Simon
update: another thought on the rotation problem if the edges don't give a clear winner: Compute the center of mass of the vertices and see to which side of the center of the bounding box it falls. Rotate accordingly.

Identify Lobed and bumps of Leaves

I need some help, I have to make a project about leaves.
I want to make it by MATLAB.
my input is an image of one leaf (with a white background) and I need to know two things about the leaf:
1) find the lobed leaf (the pixels of each lobed leaf):
Lay the leaf on a table or work space where you can examine it.
Look at the leaf you are trying to identify. If the leaf looks like it has fingers, these are considered lobes. There can be
anywhere from two to many lobes on a leaf.
Distinguish pinnate leaves from palmate leaves by looking at the veins on the underside of the leaf. If the veins all come from
the same place at the base of the leaf it is considered palmately
lobed. If they are formed at various places on the leaf from one
centre line, the leaf is pinnately lobed.
Identify the type of leaf by using a leaf dictionary.
2) find approximately the number of bumps of the leaf:
in other words, find the "swollen points" of each leaf.
these are examples of leaves:
I've found some leaves examples in here.
Here is my attempt to solve the problem.
In the images that I've found, the background is completely black. If it is not so in your images, you should use Otsu's thresholding method.
I assumed that there can be only 3 types of leaves, according to your image:
The idea is to do blob analysis. I use the morphological operation of opening, to separate the leaves. If there is only one blob after the opening, I assume it is not compound. If the leaves are not compound, I analyze the solidity of the blobs. Non-solid enough means they are lobed.
Here are some examples:
function IdentifyLeaf(dirName,fileName)
figure();
im = imread(fullfile(dirName,fileName));
subplot(1,3,1); imshow(im);
% thresh = graythresh( im(:,:,2));
imBw = im(:,:,2) > 0;
subplot(1,3,2);imshow(imBw);
radiusOfStrel = round( size(im,1)/20 ) ;
imBwOpened = imopen(imBw,strel('disk',radiusOfStrel));
subplot(1,3,3);imshow(imBwOpened);
rpOpened = regionprops(imBwOpened,'Area');
if numel(rpOpened)>1
title('Pinnately Compound');
else
rp = regionprops(imBw,'Area','Solidity');
%Leave only largest blob
area = [rp.Area];
[~,maxIndex] = max(area);
rp = rp(maxIndex);
if rp.Solidity < 0.9
title('Pinnately Lobed');
else
title('Pinnately Veined');
end
end
end
I would approach this problem by converting it from 2d to 1d by scanning in a vector the perimeter of the leaf using "right hand on the wall" -algorithm.
From that data, I presume, one can find a dominant axis of symmetry (e.g. fitting a line); the distance of the perimeter would be calculated from that axis and then one could simply use a threshold+filtering to find local maxima and minima to reveal the number lobes/fingers... The histogram of distance could differentiate between pinnately lobed and pinnately compound leaves.
Another single metrics to check the curvature of the perimeter (from two extreme points) would be http://en.wikipedia.org/wiki/Sinuosity
Recognizing veins is unfortunately a complete different topic.

How do I optimize point-to-circle matching?

I have a table that contains a bunch of Earth coordinates (latitude/longitude) and associated radii. I also have a table containing a bunch of points that I want to match with those circles, and vice versa. Both are dynamic; that is, a new circle or a new point can be added or deleted at any time. When either is added, I want to be able to match the new circle or point with all applicable points or circles, respectively.
I currently have a PostgreSQL module containing a C function to find the distance between two points on earth given their coordinates, and it seems to work. The problem is scalability. In order for it to do its thing, the function currently has to scan the whole table and do some trigonometric calculations against each row. Both tables are indexed by latitude and longitude, but the function can't use them. It has to do its thing before we know whether the two things match. New information may be posted as often as several times a second, and checking every point every time is starting to become quite unwieldy.
I've looked at PostgreSQL's geometric types, but they seem more suited to rectangular coordinates than to points on a sphere.
How can I arrange/optimize/filter/precalculate this data to make the matching faster and lighten the load?
You haven't mentioned PostGIS - why have you ruled that out as a possibility?
http://postgis.refractions.net/documentation/manual-2.0/PostGIS_Special_Functions_Index.html#PostGIS_GeographyFunctions
Thinking out loud a bit here... you have a point (lat/long) and a radius, and you want to find all extisting point-radii combinations that may overlap? (or some thing like that...)
Seems you might be able to store a few more bits of information Along with those numbers that could help you rule out others that are nowhere close during your query... This might avoid a lot of trig operations.
Example, with point x,y and radius r, you could easily calculate a range a feasible lat/long (squarish area) that could be used to help rule it out if needless calculations against another point.
You could then store the max and min lat and long along with that point in the database. Then, before running your trig on every row, you could Filter your results to eliminate points obviously out of bounds.
If I undestand you correctly then my first idea would be to cache some data and eliminate most of the checking.
Like imagine your circle is actually a box and it has 4 sides
you could store the base coordinates of those lines much like you have lines (a mesh) on a real map. So you store east, west, north, south edge of each circle
If you get your coordinate and its outside of that box you can be sure it won't be inside the circle either since the box is bigger than the circle.
If it isn't then you have to check like you do now. But I guess you can eliminate most of the steps already.

How can I get all points in CGPath curve or quad curve

I have made a quad curve path using the method CGPathAddQuadCurveToPoint. I got the path perfectly. But, I want to know all the coordinate points which are participated in the path.
Is there a way to retrieve all the coordinate points in a path?
If not do u have any other solution for retrieving all the points in a curve mathematically.
Thanks in advance,
Vamshi
You can do this using the wykobi C++ library routine for cubic bezier curves. Wykobi's library supports quadratic Bezier curves also.
Of course as someone pointed out you don't want all the points (although not impossible, it would just take infinite time :). Wykobi makes it easy to get a certain number of points -- if your start, c1, c2, and end points (where c1, c2 are the control points) are exactly the same as the ones given to CGContextAddCurveToPoint then the points will lie perfectly on the line drawn by core graphics -- so you can do things like draw a pattern at several points on the path.
See: http://www.codeproject.com/Articles/22568/Computational-Geometry-C-and-Wykobi
Also, after I started using wykobi I heard that there is a similar, maybe even better library that is part of Boost, but have not checked it out yet.
I created a C++ Class WPoint as a bridge between wykobi points and CGPoints (C++ fun!). Here's some code (without WPoint, but you can imagine that it is exactly the same layout as a CGPoint so if you do the right cast you can convert easily.
NSMutableArray* result = [[NSMutableArray alloc] init];
wykobi::cubic_bezier<CGFloat,2> bezier;
bezier[0] = (WPoint)p1; // start point, in CG we did a CGMoveToPoint
bezier[1] = (WPoint)b1i; // control 1
bezier[2] = (WPoint)b2i; // control 2
bezier[3] = (WPoint)p2; // end point
std::vector<WPoint> point_list;
int numPoints = p2.dist(p3) * pointDensity;
// *** here's the magic ***
wykobi::generate_bezier(bezier,std::back_inserter(point_list), numPoints);
for (int i=0; i<numPoints; i++) {
CGPoint p = (CGPoint)(point_list[i]);
[result addObject:[NSValue valueWithCGPoint:p]];
}
// result has your points!
Here's a link to the Boost geometry library:
http://www.boost.org/doc/libs/1_47_0/libs/geometry/doc/html/geometry/introduction.html
Use CGContextSetLineDash
The purpose of this function is to create a dashed line, but You can use it to get smaller segments.
starting point of each segment can be treated as points.
CGSize bbSize = CGPathGetBoundingBox(path).size;
UIGraphicsBeginImageContext(bbSize);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx, 1.0);
CGContextAddPath(ctx, path);
CGContextSetLineDash(ctx, phase, lengths, count);
CGContextReplacePathWithStrokedPath(ctx);
result = CGContextCopyPath(ctx);
UIGraphicsEndImageContext();
If you want to work on the moveto, lineto, and curveto elements of the path, use CGPathApply. You pass this a pointer to a function in your program, and it calls that function once per element of the path.
Unfortunately, there's no way to just ask for each element like there is with AppKit's NSBezierPath. The function is the only way.
If you want to determine every pixel intersected by the path, too bad—that's not practical, and I can't even think of why you'd want that information. Some contexts, such as PDF contexts, don't even have pixels; in those cases, any question involving pixels is a non sequitur.
A quadratic curve is just that -- a curve. It's impossible to get a list of all of the points on it because there are infinitely many points, and it's not a simple line segment.
See Getting Information about Quartz Paths for a list of the functions you can use to query a CGPath object. Unfortunately, it seems like the most useful information you're going to get is with CGPathContainsPoint(), which only tells you if a given point is contained within the area of the path.
If not do u have any other solution for retrieving all the points in a curve mathematically.
What do you need them for, i.e. what problem are you trying to solve? If it is to intersect two curves, you can do this mathematically. Just set the two curve equations equal to each other and solve for the unknown.
I guess you're after something equivalent to the Java2D FlatteningPathIterator class. For example Java2D's path.getPathIterator(null, 1.0) returns an iterator of only 'lineTo' segments even if the original path had curveTo and quadTo, the double argument controls the 'flatness', giving you an easy way to calculate any point on the curve.
I'm searching for the same thing in Cocoa, but have found nothing. If you find a solution please let me know.
There are curve implmentations around (e.g. http://sourceforge.net/projects/curves/) that could be ported, but there's always a risk that if you don't use the same algorithm as Cocoa then there could be errors between your interpolation and the stroked NSBezierPath/CGPath.