Is there any opencv function for curve fitting?
I have a set of points (cv::points) and my aim is to fit these points to a closed/open curve.
Right now I am taking a pair of points and drawing lines with them, effectively forming a curve.
It's not quite clear from your question whether you want to smooth the curve by adding more points or to summarise it by using fewer points. If it's the latter, perhaps you should consider cv::approxPolyDP, which is documented here and copied below for reference.
I think you are talking function approximation and interpolation.
As I know, there's not a function directly about curve fitting.
If you just want to get the fitting result, you can use Matlab's curve fitting toolbox, where there is a tool named cftool. cftool is a GUI tool, you can specify the input points and the interpolation method and get the result formula.
Related
i am trying to evaluate distortion correction by line fitting algorithm. Now i want to make a decision whether the given image is corrected or not. So should i consider RMSE for overall image, because i get RMSE for each line in image. Please suggest me how to make decision.
Afraid you are doing it all wrong, sorry. The mantra that "a well calibrated camera maps straight lines in the world to straight lines in the image", while true, does not lend itself to a well-posed definition of a metric for the quality of your calibration. You can compute an RMSE on straight lines in various ways, but they are all unprincipled hacks.
You can only define the RMSE error for the entire model of the projection from 3D points to their image. In other words, it only makes sense to speak of RMSE when you are doing bundle adjustment, solving jointly for the pose of the camera, and the linear and nonlinear intrinsic parameters of the lens. This is what you do when you calibrate a camera, or solve a structure-from-motion problem by bundle adjustment.
While it is theoretically true that a perfect estimation of the nonlinear lens distortion parameters "straightens" lines perfectly, it is quite tricky to use just this fact in order to define a metric for the quality of practically estimated distortion parameters. There are several reasons for this, among them:
When you apply a least-squares straight-line fitting algorithm on points obtained by un-distorting with erroneous parameters you are are using a wrong model. Applying the un-distortion function itself to the image of a physical straight 3D line produces a curve in the image which is only straight if the parameters are well estimated. When they aren't, your line fit will be biased, which means that distance between the curve and the straight line it "fits" is not a purely random variable: it depends on where you measure it, and where the curve itself is located in the image.
It is tricky to define a distance between a curve and a straight line that supposedly fits it. How do you choose which point on the line corresponds to a given point on the curve, or viceversa?
A more principled approach would be to define an error measure based on the geometrical curvature of the curve resulting by un-distorting the image of a physical straight line. However, attempting to accurately measure curvature opens a can of worms by itself, since it amounts to estimating (explicitly or not) the first and second derivatives of the curve, which amplifies noise.
So, all in all, either one of your suggestion "works" in the sense that it gives you a number that, if small, is "suggestive" of likely good calibration. However, neither is a "correct" choice, because the basis of what you are trying to measure (and define an error for) is shaky.
I want to find curvature at depth map
Look at the picture
This is example of curvature
Maybe if i represent image as function and take second derivative from it a can find curvatures. But i couldn't to implement it. (I tryed sobel operator from opencv)
Is there way out?
PS Sorry for my writing mistakes. English in not my native language.
That is not a depth map, it is a point cloud (but I assume it is generated from one single depth map z = f(x,y).
What curvature do you want to estimate? Mean, Gaussian, the whole 2nd fundamental form?
See, e.g. here for definitions. Here's a recent reference on fast estimation methods:
I am a newbie to opencv and am trying to implement shape context descriptor outlined in the slide http://www.cs.utexas.edu/~grauman/courses/spring2008/slides/ShapeContexts425.pdf
I found the edge points on the shape using canny edge detector for the first part of step 1. Then I need to calculate the Euclidean distance on each edge point to the other ones. Rather than using for-loops to find the distance between each and every point, is there any opencv function that can do this step more efficiently?
Finding all pairwise distances between the set of points is not a standard operation and I don't think you will find something similar in OpenCV. And it is very easy to compute by hand. Given two points a and b, you can calculate distance between them as cv::norm(a - b), as described here.
You might want to utilize the matchShapes function. However, it operates with image moments, not with shape descriptor you mentioned.
OpenCV has a nice in-built ellipse-fitting algorithm called fitEllipse(const Mat& points)
However, it has some major shortcomings, limiting its usefulness. For example, it already requires selected points, so I already have to do a feature extraction myself. HoughCircles detects circles on a given image, pity there is no HoughEllipses.
The other major shortcoming, which stands in the center of my question, is that it does no provide any metric about how accurate the fitting was. It returns an ellipse which best fits the given points, even if the shape does not even remotely look like an ellipse. Is there a way to get the estimated error from the algorithm? I would like to use it as a threshold to filter out shapes which are not even close to be considered ellipses.
I asked this, because maybe there is a simple solution before I try to reinvent the wheel and write my very own fitEllipse function.
If you don't mind getting your hands dirty, you could actually modify the source code for fitEllipse(). The fitEllipse() function uses least-squares to determine the likely ellipses, and the least-squares solution is a tangible distance metric, which is what you want.
If that is something you're willing to do, it would be a very simple code change. Simply add a float whose value is passed back after the function call, where the float stores the current best least-squares value.
fitEllipse gives you the ellipse as a cv::RotatedRect and so you know the angle of rotation of the ellipse, its center and its two axes.
You can compute the sum of the square of the distances between your points and the ellipse, that sum is the metric you are looking for.
The distance between a point and an ellipse is described here http://www.geometrictools.com/Documentation/DistancePointEllipseEllipsoid.pdf and the code is here http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistPointHyperellipsoid.h
You need to go from OpenCV cv::RotatedRect to Ellipse2 of Geometric Tools Engine and then you can compute the distance.
Why don't you do a findContours() to reduce the memory space required? There's your selected points structure right there. If you want to further simplify you can run a ConvexHull() or ApproxPoly() on that. Fit the ellipse to those points, and then I suppose you can check similarity between the two structures to get some kind of estimate. A difference operator between the two Mats would be a (very) rough estimate?
Depending on the application, you might be able to use CAMShift (or mean shift), which fits an ellipse to a region with similar colors.
I'm just starting to learn OpenCV programming. May I just ask about how can I identify lines and curves in OpenCV? My problem is that I have to identify if the image contains a convex or concave (horizontal or vertical curve) curve, a vertical, diagonal or a horizontal line.
In my code, I used CvSetImageROI to take a particular part of an image, and then I'm trying to identify each according to the said lines/curves.
Are there functions in OpenCV that are available? Thank you very much for the help. By the way, i'm using Linux and C++.
Hough transform http://en.wikipedia.org/wiki/Hough_transform, http://homepages.inf.ed.ac.uk/rbf/HIPR2/hough.htm
is the standard way to do it. In its simple form (as implemented in OpenCV) it can detect lines of arbitray position and angle and line segments.
Look here for an example
http://opencv.itseez.com/modules/imgproc/doc/feature_detection.html?highlight=hough#houghlinesp
For curves, the detection process is a bit more complicated, and you need the general Hough transform It is not yet available in OCV, but you can write it as an exercise or look for a good implementation.
http://en.wikipedia.org/wiki/Generalised_Hough_transform describes it (in short)