Contours matching - finding contours displacement - image-processing

I found contours on two images with same object and I want to find displacement and rotation of this object. I've tried with rotated bounding boxes of this contours and then its angles and center points but rotations of bounding boxes don't tell about contour rotation correctly because it's the same for angles a+0, a+90, a+180 etc. degrees.
Is it any other good way to find rotation and displacement of contours? Maybe some use of convex hull, convexity defects? I've read in Learning OpenCv about matching contours but it hasn't helped. Could someone give some example?
//edit:
Maybe there is some way to use something similar to freeman chains to this? But I can't figure out algorithm at the moment. Making chain with angles between sequence point and then checking sequence match isn't working good...

If the object has convexity defects then you could choose one defect, make a vector from the centroid of the first contour to the centroid of this defect.
Then you could check the defects in the second contour and match the one that you used before.Again a vector from the centroid of the contour to the centroid of the matched defect.
From this you get 2 segments (vectors) from which you could obtain a displacement and a rotation.

Related

Find straight line segments in image using OpenCV

Using OpenCV's findContours() I have a list of contours in an image. I'm interested only in the straight lines, so if they are too 'squiggly' they should be rejected. The question is how to evaluate how straight each contour is?
I looked at fitLine(), but there doesn't appear to be a goodness-of-fit measure returned. I could evaluate this myself using the returned line.
I looked at arcLength() with the aim to compare this to the bounding rectangle dimensions, but even for somewhat straight lines, the arc length can be relatively long if the contour points are dense.
I could find the convex hull and compare to the bounding rectangle dimensions, but I'd have to analyze the convexity defects.
Is there a moment that would be useful here?
Find the contours as you are doing now
Find the straight lines in the image using HoughLines()
Compute the overlap between the contours and the straight lines
Take two points (with for instance cv::approxPoly) on your contour and compute their absolute distance. Then go through the contour points between the two points and add up all the distances. If the difference between distance over the contour and the absolute distance is bigger than a certain threshold you can reject it.
The function, findContours() already approximated contours with line segments somehow. Each contour is represented by a list of points around it. For your purpose, simply computing the distances of each pair of consecutive points in the contour would give you all line segment lengths.
Here is an example:
c = cnts[0]
#d is the points in contour c shifted by one with wraparound (numpy.roll)
d = np.roll(c, 1, axis=0)
np.linalg.norm(c - d, axis = -1)

Why sift feature is also invariant to planar homography transform

I have read sift features' paper, and I understand why it is rotation invariant.
But I do not understand why does it also invariant to planar homography transform, as my test code shows.
In the homography transform between two images, the change does not only include rotation and scale.
For example, a rectangle may be transformed to other quadrangle with every corner less or larger than 90 degrees. You can image that the shape of the object is changed, but why the feature of the key point still match?
As to the details of the algorithm, when the key point's surrounding pixel changed without rotating the same degree, the keypoint's 128 dimension feature's value will be different when they subtract the keypoint's gradient angle.
Can someone explain why?
As far as I know, the SIFT descriptor is not invariant to a projective transformation (homography). However, it works well enough when the actual homography is sufficiently close to a similarity transformation.
This paper by Mikolajczyk and Schmid proposes an interest point detector, which is affine-invariant. They also make the descriptor affine-invariant by transforming the image patch from which it is computed.

centroid ellipse MSER OPENCV

I am working on an image registration method and I would like to work with region based feature detectors. As representative and because it is already implemented in opencv, i thought of MSER.
I know how to detect the MSER regions.MSER detector gives the MSER regions inside of a vector of points, a contour.I would like to retrieve the centroid of these contours. I could fit a ellipse on them, but then I don't as well how could I retrieve the centroid of these ellipses.
Does someone know if there is an already implemented function that could take care of this task? Or do i have to develop an algorithm?
The reason is that I would like to perform the point correspondence using this centroid points as interesting points.
Thanks
Iván
The centroid of the region can be computed by calculating the mean of all the x values and the mean of all the y values. The resulting (meanX, meanY) point is the region's centroid.

Getting corners from convex points

I have written algorithm to extract the points shown in the image. They form convex shape and I know order of them. How do I extract corners (top 3 and bottom 3) from such points?
I'm using opencv.
if you already have the convex hull of the object, and that hull includes the corner points, then all you need to to do is simplify the hull until it only has 6 points.
There are many ways to simplify polygons, for example you could just use this simple algorithm used in this answer: How to find corner coordinates of a rectangle in an image
do
for each point P on the convex hull:
measure its distance to the line AB _
between the point A before P and the point B after P,
remove the point with the smallest distance
repeat until 6 points left
If you do not know the exact number of points, then you could remove points until the minimum distance rises above a certain threshold
you could also do Ramer-Douglas-Peucker to simplify the polygon, openCV already has that implemented in cv::approxPolyDP.
Just modify the openCV squares sample to use 6 points instead of 4
Instead of trying to directly determine which of your feature points correspond to corners, how about applying an corner detection algorithm on the entire image then looking for which of your feature points appear close to peaks in the corner detector?
I'd suggest starting with a Harris corner detector. The OpenCV implementation is cv::cornerHarris.
Essentially, the Harris algorithm applies both a horizontal and a vertical Sobel filter to the image (or some other approximation of the partial derivatives of the image in the x and y directions).
It then constructs a 2 by 2 structure matrix at each image pixel, looks at the eigenvalues of that matrix, and calls points corners if both eigenvalues are above some threshold.

Detection of pattern of circles using opencv

I have to detect the pattern of 6 circles using opencv. I have detected the circles and their centroids by using thresholding and contour function in opencv.
Now I have to define the relation between these circles in a way that should be invariant to scale and rotation. With this I would be able to detect this pattern in various views. I have to use this pattern for determining the object pose.
How can I achieve scale/rotation invariance? Do you have any reference I could read about it?
To make your pattern invariant toward rotation & scale, you have to normalize the direction and the scale when detecting your pattern. Here is a simple algorithm to achieve this
detect centers and circle size (you say you have already achieved this - good!)
compute the average center using a simple mean. Express all the centers from this mean
find the farthest center using a simple norm (euclidian is good enough)
scale the center position and the circle sizes so that this maximum distance is 1.0
rotate the centers so that coordinates of the farthest one is (1.0, 0)
you're done. You are now the proud owner of a scale/rotation invariant pattern detector!! Congratulations!
Now you can find patterns, transform them as suggested, and compare center position & circle sizes.
It is not entirely clear to me if you need to find the rotation, or merely get rid of it, or detect if the circles actually form the pattern you linked. Either way, the answer is much the same.
I would start by finding the two circles that have only one neighbour. For each circle centroid calculate the distance to the closest two neighbours. If the distances differ in more than say 10%, the centroid belongs to an "end" circle (one of the top ones in your link).
Now that you have found the two end circles, rotate them so that they are horizontal to each other. If the other centroids are now above them, rotate another 180 degrees so that the pattern ends up in the orientation you want.
Now you can calculate the scaling from the average inter-centroid distance.
Hope that helps.
Your question sounds exactly like what the SURF algorithm does. It finds groups of interest and groups them together in a way invarant to rotation and scale, and can find the same object in other pictures.
Just search for OpenCV and SURF.

Resources