how to connect points after identifying them in cvgoodfeaturesTotrack - opencv

I want to identify an object and draw a shape around it ...
I used previously the color identification but wasn't a good option since color change dramatically from place to place .. so I though why not identifying objects by features such as edges .. and I did that using this function in openCV
cvgoodfeaturesTotrack
it returns the (x,y)-coordinates of the points .. now I want to connect those points.. well not all of them but the one who are close to each other to draw a shape around the different objects. Any ideas ?

I don't think there is a free lunch in this case. You are trying to reconstruct a polygon if you only know the corner points of the polygon. There is no unique solution to this problem: you can draw all sorts of polygons through the corners. If you are certain the shape you are after is convex, then you can construct the convex span of the corner points, but the result will be horrible if you include any corners that were not part of the original object.
It seems to me that detecting corners is not the way to segment an object that is more or less delimited by lines. You probably want to try an edge detector instead, or a proper segmentation technique such as watershed.

Related

Detect if polygon has intersecting lines (bowtie)

I'm looking for a way to detect if a set of points/coordinates have any intersecting lines.
A little setup, I'm drawing a polygon using UIBezierPath on an overlay to a map. This all works. I'm able to reduce the map points down using a point reducing algorithm, and I'm left with a simple looking polygon that renders on my map just fine. FWIW, I'm using Google Maps SDK.
My problem is that it is possible for the user to draw a polygon with self intersecting lines (which is a problem for what I am doing). I need to be able to do one of 3 things.
Remove the intersecting points in the array. (Clip off the bow tie pieces)
Detect if my points have this bow tie (I'll just tell them to redraw a new polygon)
If possible (which I don't think it is), prevent the path from drawing the bow tie in the first place.
I mostly see the bow tie when the polygon self closes and the end point is slightly underlapping the start point. So when the polygon closes and renders into map coordinates on the map, I get a tiny bow tie that messes with an internal API.
Is there anything out there that will work using map coordinates? I've seen some fixes for regular CGPoints, but nothing that will take map coordinates. I would prefer to do this check on my polygon after it has gone through my reducer as it leaves many less points to check. Performance is an issue, and would prefer not to iterate over hundreds of points directly coming off the UIBezierPath. Any help would be appreciated.
I don't know about the Google Maps SDK or the UIBezierPath. I assume that you are given a polygon in the 2D plane and you would like to automatically detect where the polygon intersects itself (if it does).
Perhaps the easiest way to do this is checking all pairs of edges whether they intersect or not. You can check this in O(n2) time where n is the number of edges, as there are n*(n-1)/2 pairs of edges. For a given pair of edges, here are the details how to do it:
How to check if two given line segments intersect?
Nothing extraordinary but the details do require attention.
A more sophisticated algorithm is the plane sweep algorithm:
Line segment intersection, starting at slide 25
Line Segment Intersection Using a Sweep Line Algorithm

Collision detection for rotating images

I want to be able to tell when 2 images collide (not just their frames). But here is the catch: the images are rotating.
So I know how to find whether a pixel in an image is transparent or not but that wont help in this scenario because it will only find the location in the frame relative to a non-rotated image.
Also I have gone as far as trying hit boxes but even those wont work because I can't find a way to detect the collision of UIViews that are contained in different subviews.
Is what I am trying to do even possible?
Thanks in advance
I don't know how you would go about checking for pixel collision on a rotated image. That would be hard. I think you would have to render the rotated image into a context, then fetch pixels from the context to check for transparency. That would be dreadfully slow.
I would suggest a different approach. Come up with a path that maps the bounds of your irregular image. You could then use CGPathContainsPoint to check to see if a set of points is contained in the path (That method takes a transform, which you would use to describe the rotation of your image's path.)
Even then though you're going to have performance problems, since you would have to call that method for a large number of points from the other image to determine if they intersect.
I propose you a simple strategy to solve that, based on looking for rectangles intersections.
The key for that is to create a simplified representation of your images with a set of rectangles laid out properly as bounding boxes of the different part of you image (like you would build your image with legos). For better performance use a small set of rectangles (a few big legos), for better precision use a biggest number of rectangles to precisely follow the image outline.
Your problem becomes equivalent to finding an intersection between rectangles. Or to be more precise to find wether at least one vertex of the rectangles of object A is inside at least one rectangle of object B (CGRectContainsPoint) or if rect intersects (CGRectIntersectsRect).
If you prefer the points lookup, you should define your rectangles by their 4 vertices then it is easy when you rotate your image to apply the same affine transform (use CGPointApplyAffineTransform) to your rectangle vertices to have the coordinates of your points after rotation. But of course you can lookup for frame intersections and represent you rectangle using the standard CGRect structure.
You could also use a CGPath (as explained in another answer below) instead of a set of rectangles and look for any vertex inside other path using CGPathContainsPoint. That would give the same result actually but probably the rectangles approach is faster in many cases.
The only trick is to take one of the objects as a reference axis. Imagine you are on object A and you only see B moving around you. Then if you have to rotate A you need to make an axis transform to always have B transform relatively to A and not to the screen or any other reference. If your transforms are only rotation around the object centre then rotating A by n radians is equivalent to rotating B by -n radians.
Then just loop through your vertices defining object A and find if one is inside a rectangle of object A.
You will probably need to investigate a bit to achieve that but at least you have some clues on how to solve that.

how to manage countor bounding rect in opencv

I have been testing background subtraction using gaussian state model. I am using opencv
2.1.0. I can generate binary image of foreground of the scene. Now all I want to do is Draw
countour bounding rectangle to highlight the moving object. I have used cvCountourBoundingRect
to obtain the rectangle covering countour. The issue I am facing is in case of multiple
countour, sometime nearby rectangle overlaps. Here, can anyone suggest me to prevent
overlapping of rectangle? In ideal case, two rectangle should not be overlapped. It rather
should be draw a bigger rectagle which covers all two rectangles.
Any suggetion will be greatful.
There's no ready possibility to do this in OpenCV. But actually the algorithm is very easy:
Cycle through all rectangles and check if two rectangles overlap each other. This topic will be useful: Determine if two rectangles overlap each other?
For every overlapped pair of rectangles create rectangle that contains both of them. To do this you should select one corner from first rectangle and another corner from second rectangle and these two corners will create rectangle for you. I don't think that it's a hard task - just simple math.

Shape/Pattern Matching Approach in Computer Vision

I am currently facing a, in my opinion, rather common problem which should be quite easy to solve but so far all my approached have failed so I am turning to you for help.
I think the problem is explained best with some illustrations. I have some Patterns like these two:
I also have an Image like (probably better, because the photo this one originated from was quite poorly lit) this:
(Note how the Template was scaled to kinda fit the size of the image)
The ultimate goal is a tool which determines whether the user shows a thumb up/thumbs down gesture and also some angles in between. So I want to match the patterns against the image and see which one resembles the picture the most (or to be more precise, the angle the hand is showing). I know the direction in which the thumb is showing in the pattern, so if i find the pattern which looks identical I also have the angle.
I am working with OpenCV (with Python Bindings) and already tried cvMatchTemplate and MatchShapes but so far its not really working reliably.
I can only guess why MatchTemplate failed but I think that a smaller pattern with a smaller white are fits fully into the white area of a picture thus creating the best matching factor although its obvious that they dont really look the same.
Are there some Methods hidden in OpenCV I havent found yet or is there a known algorithm for those kinds of problem I should reimplement?
Happy New Year.
A few simple techniques could work:
After binarization and segmentation, find Feret's diameter of the blob (a.k.a. the farthest distance between points, or the major axis).
Find the convex hull of the point set, flood fill it, and treat it as a connected region. Subtract the original image with the thumb. The difference will be the area between the thumb and fist, and the position of that area relative to the center of mass should give you an indication of rotation.
Use a watershed algorithm on the distances of each point to the blob edge. This can help identify the connected thin region (the thumb).
Fit the largest circle (or largest inscribed polygon) within the blob. Dilate this circle or polygon until some fraction of its edge overlaps the background. Subtract this dilated figure from the original image; only the thumb will remain.
If the size of the hand is consistent (or relatively consistent), then you could also perform N morphological erode operations until the thumb disappears, then N dilate operations to grow the fist back to its original approximate size. Subtract this fist-only blob from the original blob to get the thumb blob. Then uses the thumb blob direction (Feret's diameter) and/or center of mass relative to the fist blob center of mass to determine direction.
Techniques to find critical points (regions of strong direction change) are trickier. At the simplest, you might also use corner detectors and then check the distance from one corner to another to identify the place when the inner edge of the thumb meets the fist.
For more complex methods, look into papers about shape decomposition by authors such as Kimia, Siddiqi, and Xiaofing Mi.
MatchTemplate seems like a good fit for the problem you describe. In what way is it failing for you? If you are actually masking the thumbs-up/thumbs-down/thumbs-in-between signs as nicely as you show in your sample image then you have already done the most difficult part.
MatchTemplate does not include rotation and scaling in the search space, so you should generate more templates from your reference image at all rotations you'd like to detect, and you should scale your templates to match the general size of the found thumbs up/thumbs down signs.
[edit]
The result array for MatchTemplate contains an integer value that specifies how well the fit of template in image is at that location. If you use CV_TM_SQDIFF then the lowest value in the result array is the location of best fit, if you use CV_TM_CCORR or CV_TM_CCOEFF then it is the highest value. If your scaled and rotated template images all have the same number of white pixels then you can compare the value of best fit you find for all different template images, and the template image that has the best fit overall is the one you want to select.
There are tons of rotation/scaling independent detection functions that could conceivably help you, but normalizing your problem to work with MatchTemplate is by far the easiest.
For the more advanced stuff, check out SIFT, Haar feature based classifiers, or one of the others available in OpenCV
I think you can get excellent results if you just compute the two points that have the furthest shortest path going through white. The direction in which the thumb is pointing is just the direction of the line that joins the two points.
You can do this easily by sampling points on the white area and using Floyd-Warshall.

Sprite pixel parsing to determine Vector

Given an image that can contain any variety of solid color images, what is the best method for parsing the image at a given point and then determining the slope (or Vector if you prefer) of that area?
Being new to XNA development, I feel there must be an established method for doing this sort of thing but I have Googled this issue for awhile now.
By way of example, I have mocked up a quick image to demonstrate what I am trying to do. The white portion of the image (where the labels are shown) would be transparent pixels. The "ground" would be a RenderTarget2D or Texture2D object that will provide the Color array of pixels.
Example
What you are looking for is the tangent, which is 90 degrees to the normal (which is more commonly used). These two terms should assist you in your searching.
This is trivial if you've got the polygon outline data. If all you have is an image, then you have to come up with a way to convert it into a polygon.
It may not be entirely suitable for your problem, but the first place I would go is the Farseer Physics Engine, which has a "texture to polygon" feature you could possibly reuse.
If you are using the terrain as some kind of "ground", you can possibly cheat a bit by looking at the adjacent column of pixels and using that to determine the ground slope at that exact point. Kind of like what Lemmings and Worms do.
If you make that determination at the boundary between each pixel, you can get gradients of rise:run between two pixels horizontally. Usually you just break it into categories: so flat (1:1), 45 degrees (2:1) or too steep (>3:1). With a more complicated algorithm, that looks outwards to more columns, you can get better resolution.

Resources