init - 初始化项目
This commit is contained in:
@@ -0,0 +1,252 @@
|
||||
Contour Features {#tutorial_js_contour_features}
|
||||
================
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
- To find the different features of contours, like area, perimeter, centroid, bounding box etc
|
||||
- You will learn plenty of functions related to contours.
|
||||
|
||||
1. Moments
|
||||
----------
|
||||
|
||||
Image moments help you to calculate some features like center of mass of the object, area of the
|
||||
object etc. Check out the wikipedia page on [Image
|
||||
Moments](http://en.wikipedia.org/wiki/Image_moment)
|
||||
|
||||
We use the function: **cv.moments (array, binaryImage = false)**
|
||||
@param array raster image (single-channel, 8-bit or floating-point 2D array) or an array ( 1×N or N×1 ) of 2D points.
|
||||
@param binaryImage if it is true, all non-zero image pixels are treated as 1's. The parameter is used for images only.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contour_features_moments.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
From this moments, you can extract useful data like area, centroid etc. Centroid is given by the
|
||||
relations, \f$C_x = \frac{M_{10}}{M_{00}}\f$ and \f$C_y = \frac{M_{01}}{M_{00}}\f$. This can be done as
|
||||
follows:
|
||||
@code{.js}
|
||||
let cx = M.m10/M.m00
|
||||
let cy = M.m01/M.m00
|
||||
@endcode
|
||||
|
||||
2. Contour Area
|
||||
---------------
|
||||
|
||||
Contour area is given by the function **cv.contourArea()** or from moments, **M['m00']**.
|
||||
|
||||
We use the function: **cv.contourArea (contour, oriented = false)**
|
||||
@param contour input vector of 2D points (contour vertices)
|
||||
@param oriented oriented area flag. If it is true, the function returns a signed area value, depending on the contour orientation (clockwise or counter-clockwise). Using this feature you can determine orientation of a contour by taking the sign of an area. By default, the parameter is false, which means that the absolute value is returned.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contour_features_area.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
3. Contour Perimeter
|
||||
--------------------
|
||||
|
||||
It is also called arc length. It can be found out using **cv.arcLength()** function.
|
||||
|
||||
We use the function: **cv.arcLength (curve, closed)**
|
||||
@param curve input vector of 2D points.
|
||||
@param closed flag indicating whether the curve is closed or not.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contour_features_perimeter.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
4. Contour Approximation
|
||||
------------------------
|
||||
|
||||
It approximates a contour shape to another shape with less number of vertices depending upon the
|
||||
precision we specify. It is an implementation of [Douglas-Peucker
|
||||
algorithm](http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm). Check the wikipedia page
|
||||
for algorithm and demonstration.
|
||||
|
||||
We use the function: **cv.approxPolyDP (curve, approxCurve, epsilon, closed)**
|
||||
@param curve input vector of 2D points stored in cv.Mat.
|
||||
@param approxCurve result of the approximation. The type should match the type of the input curve.
|
||||
@param epsilon parameter specifying the approximation accuracy. This is the maximum distance between the original curve and its approximation.
|
||||
@param closed If true, the approximated curve is closed (its first and last vertices are connected). Otherwise, it is not closed.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contour_features_approxPolyDP.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
5. Convex Hull
|
||||
--------------
|
||||
|
||||
Convex Hull will look similar to contour approximation, but it is not (Both may provide same results
|
||||
in some cases). Here, **cv.convexHull()** function checks a curve for convexity defects and
|
||||
corrects it. Generally speaking, convex curves are the curves which are always bulged out, or
|
||||
at-least flat. And if it is bulged inside, it is called convexity defects. For example, check the
|
||||
below image of hand. Red line shows the convex hull of hand. The double-sided arrow marks shows the
|
||||
convexity defects, which are the local maximum deviations of hull from contours.
|
||||
|
||||

|
||||
|
||||
We use the function: **cv.convexHull (points, hull, clockwise = false, returnPoints = true)**
|
||||
@param points input 2D point set.
|
||||
@param hull output convex hull.
|
||||
@param clockwise orientation flag. If it is true, the output convex hull is oriented clockwise. Otherwise, it is oriented counter-clockwise. The assumed coordinate system has its X axis pointing to the right, and its Y axis pointing upwards.
|
||||
@param returnPoints operation flag. In case of a matrix, when the flag is true, the function returns convex hull points. Otherwise, it returns indices of the convex hull points.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contour_features_convexHull.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
6. Checking Convexity
|
||||
---------------------
|
||||
|
||||
There is a function to check if a curve is convex or not, **cv.isContourConvex()**. It just return
|
||||
whether True or False. Not a big deal.
|
||||
|
||||
@code{.js}
|
||||
cv.isContourConvex(cnt);
|
||||
@endcode
|
||||
|
||||
7. Bounding Rectangle
|
||||
---------------------
|
||||
|
||||
There are two types of bounding rectangles.
|
||||
|
||||
### 7.a. Straight Bounding Rectangle
|
||||
|
||||
It is a straight rectangle, it doesn't consider the rotation of the object. So area of the bounding
|
||||
rectangle won't be minimum.
|
||||
|
||||
We use the function: **cv.boundingRect (points)**
|
||||
@param points input 2D point set.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contour_features_boundingRect.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
### 7.b. Rotated Rectangle
|
||||
|
||||
Here, bounding rectangle is drawn with minimum area, so it considers the rotation also.
|
||||
|
||||
We use the function: **cv.minAreaRect (points)**
|
||||
@param points input 2D point set.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contour_features_minAreaRect.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
8. Minimum Enclosing Circle
|
||||
---------------------------
|
||||
|
||||
Next we find the circumcircle of an object using the function **cv.minEnclosingCircle()**. It is a
|
||||
circle which completely covers the object with minimum area.
|
||||
|
||||
We use the functions: **cv.minEnclosingCircle (points)**
|
||||
@param points input 2D point set.
|
||||
|
||||
**cv.circle (img, center, radius, color, thickness = 1, lineType = cv.LINE_8, shift = 0)**
|
||||
@param img image where the circle is drawn.
|
||||
@param center center of the circle.
|
||||
@param radius radius of the circle.
|
||||
@param color circle color.
|
||||
@param thickness thickness of the circle outline, if positive. Negative thickness means that a filled circle is to be drawn.
|
||||
@param lineType type of the circle boundary.
|
||||
@param shift number of fractional bits in the coordinates of the center and in the radius value.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contour_features_minEnclosingCircle.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
9. Fitting an Ellipse
|
||||
---------------------
|
||||
|
||||
Next one is to fit an ellipse to an object. It returns the rotated rectangle in which the ellipse is
|
||||
inscribed.
|
||||
We use the functions: **cv.fitEllipse (points)**
|
||||
@param points input 2D point set.
|
||||
|
||||
**cv.ellipse1 (img, box, color, thickness = 1, lineType = cv.LINE_8)**
|
||||
@param img image.
|
||||
@param box alternative ellipse representation via RotatedRect. This means that the function draws an ellipse inscribed in the rotated rectangle.
|
||||
@param color ellipse color.
|
||||
@param thickness thickness of the ellipse arc outline, if positive. Otherwise, this indicates that a filled ellipse sector is to be drawn.
|
||||
@param lineType type of the ellipse boundary.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contour_features_fitEllipse.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
10. Fitting a Line
|
||||
------------------
|
||||
|
||||
Similarly we can fit a line to a set of points. We can approximate a straight line to it.
|
||||
|
||||
We use the functions: **cv.fitLine (points, line, distType, param, reps, aeps)**
|
||||
@param points input 2D point set.
|
||||
@param line output line parameters. It should be a Mat of 4 elements[vx, vy, x0, y0], where [vx, vy] is a normalized vector collinear to the line and [x0, y0] is a point on the line.
|
||||
@param distType distance used by the M-estimator(see cv.DistanceTypes).
|
||||
@param param numerical parameter ( C ) for some types of distances. If it is 0, an optimal value is chosen.
|
||||
@param reps sufficient accuracy for the radius (distance between the coordinate origin and the line).
|
||||
@param aeps sufficient accuracy for the angle. 0.01 would be a good default value for reps and aeps.
|
||||
|
||||
**cv.line (img, pt1, pt2, color, thickness = 1, lineType = cv.LINE_8, shift = 0)**
|
||||
@param img image.
|
||||
@param pt1 first point of the line segment.
|
||||
@param pt2 second point of the line segment.
|
||||
@param color line color.
|
||||
@param thickness line thickness.
|
||||
@param lineType type of the line,.
|
||||
@param shift number of fractional bits in the point coordinates.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contour_features_fitLine.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
@@ -0,0 +1,110 @@
|
||||
Contour Properties {#tutorial_js_contour_properties}
|
||||
==================
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
- Here we will learn to extract some frequently used properties of objects like Solidity, Equivalent
|
||||
Diameter, Mask image, Mean Intensity etc.
|
||||
|
||||
1. Aspect Ratio
|
||||
---------------
|
||||
|
||||
It is the ratio of width to height of bounding rect of the object.
|
||||
|
||||
\f[Aspect \; Ratio = \frac{Width}{Height}\f]
|
||||
@code{.js}
|
||||
let rect = cv.boundingRect(cnt);
|
||||
let aspectRatio = rect.width / rect.height;
|
||||
@endcode
|
||||
|
||||
2. Extent
|
||||
---------
|
||||
|
||||
Extent is the ratio of contour area to bounding rectangle area.
|
||||
|
||||
\f[Extent = \frac{Object \; Area}{Bounding \; Rectangle \; Area}\f]
|
||||
@code{.js}
|
||||
let area = cv.contourArea(cnt, false);
|
||||
let rect = cv.boundingRect(cnt));
|
||||
let rectArea = rect.width * rect.height;
|
||||
let extent = area / rectArea;
|
||||
@endcode
|
||||
|
||||
3. Solidity
|
||||
-----------
|
||||
|
||||
Solidity is the ratio of contour area to its convex hull area.
|
||||
|
||||
\f[Solidity = \frac{Contour \; Area}{Convex \; Hull \; Area}\f]
|
||||
@code{.js}
|
||||
let area = cv.contourArea(cnt, false);
|
||||
cv.convexHull(cnt, hull, false, true);
|
||||
let hullArea = cv.contourArea(hull, false);
|
||||
let solidity = area / hullArea;
|
||||
@endcode
|
||||
|
||||
4. Equivalent Diameter
|
||||
----------------------
|
||||
|
||||
Equivalent Diameter is the diameter of the circle whose area is same as the contour area.
|
||||
|
||||
\f[Equivalent \; Diameter = \sqrt{\frac{4 \times Contour \; Area}{\pi}}\f]
|
||||
@code{.js}
|
||||
let area = cv.contourArea(cnt, false);
|
||||
let equiDiameter = Math.sqrt(4 * area / Math.PI);
|
||||
@endcode
|
||||
|
||||
5. Orientation
|
||||
--------------
|
||||
|
||||
Orientation is the angle at which object is directed. Following method also gives the Major Axis and
|
||||
Minor Axis lengths.
|
||||
@code{.js}
|
||||
let rotatedRect = cv.fitEllipse(cnt);
|
||||
let angle = rotatedRect.angle;
|
||||
@endcode
|
||||
|
||||
6. Mask and Pixel Points
|
||||
------------------------
|
||||
|
||||
In some cases, we may need all the points which comprises that object.
|
||||
|
||||
We use the function: **cv.transpose (src, dst)**
|
||||
@param src input array.
|
||||
@param dst output array of the same type as src.
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contour_properties_transpose.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
7. Maximum Value, Minimum Value and their locations
|
||||
---------------------------------------------------
|
||||
|
||||
We use the function: **cv.minMaxLoc(src, mask)**
|
||||
@param src input single-channel array.
|
||||
@param mask optional mask used to select a sub-array.
|
||||
|
||||
@code{.js}
|
||||
let result = cv.minMaxLoc(src, mask);
|
||||
let minVal = result.minVal;
|
||||
let maxVal = result.maxVal;
|
||||
let minLoc = result.minLoc;
|
||||
let maxLoc = result.maxLoc;
|
||||
@endcode
|
||||
|
||||
8. Mean Color or Mean Intensity
|
||||
-------------------------------
|
||||
|
||||
Here, we can find the average color of an object. Or it can be average intensity of the object in
|
||||
grayscale mode. We again use the same mask to do it.
|
||||
|
||||
We use the function: **cv.mean (src, mask)**
|
||||
@param src input array that should have from 1 to 4 channels so that the result can be stored in Scalar.
|
||||
@param mask optional operation mask.
|
||||
|
||||
@code{.js}
|
||||
let average = cv.mean(src, mask);
|
||||
@endcode
|
||||
@@ -0,0 +1,72 @@
|
||||
Contours : Getting Started {#tutorial_js_contours_begin}
|
||||
==========================
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
- Understand what contours are.
|
||||
- Learn to find contours, draw contours etc
|
||||
- You will learn these functions : **cv.findContours()**, **cv.drawContours()**
|
||||
|
||||
What are contours?
|
||||
------------------
|
||||
|
||||
Contours can be explained simply as a curve joining all the continuous points (along the boundary),
|
||||
having same color or intensity. The contours are a useful tool for shape analysis and object
|
||||
detection and recognition.
|
||||
|
||||
- For better accuracy, use binary images. So before finding contours, apply threshold or canny
|
||||
edge detection.
|
||||
- Since opencv 3.2 source image is not modified by this function.
|
||||
- In OpenCV, finding contours is like finding white object from black background. So remember,
|
||||
object to be found should be white and background should be black.
|
||||
|
||||
How to draw the contours?
|
||||
-------------------------
|
||||
|
||||
To draw the contours, cv.drawContours function is used. It can also be used to draw any shape
|
||||
provided you have its boundary points.
|
||||
|
||||
We use the functions: **cv.findContours (image, contours, hierarchy, mode, method, offset = new cv.Point(0, 0))**
|
||||
@param image source, an 8-bit single-channel image. Non-zero pixels are treated as 1's. Zero pixels remain 0's, so the image is treated as binary.
|
||||
@param contours detected contours.
|
||||
@param hierarchy containing information about the image topology. It has as many elements as the number of contours.
|
||||
@param mode contour retrieval mode(see cv.RetrievalModes).
|
||||
@param method contour approximation method(see cv.ContourApproximationModes).
|
||||
@param offset optional offset by which every contour point is shifted. This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image context.
|
||||
|
||||
**cv.drawContours (image, contours, contourIdx, color, thickness = 1, lineType = cv.LINE_8, hierarchy = new cv.Mat(), maxLevel = INT_MAX, offset = new cv.Point(0, 0))**
|
||||
@param image destination image.
|
||||
@param contours all the input contours.
|
||||
@param contourIdx parameter indicating a contour to draw. If it is negative, all the contours are drawn.
|
||||
@param color color of the contours.
|
||||
@param thickness thickness of lines the contours are drawn with. If it is negative, the contour interiors are drawn.
|
||||
@param lineType line connectivity(see cv.LineTypes).
|
||||
@param hierarchy optional information about hierarchy. It is only needed if you want to draw only some of the contours(see maxLevel).
|
||||
|
||||
@param maxLevel maximal level for drawn contours. If it is 0, only the specified contour is drawn. If it is 1, the function draws the contour(s) and all the nested contours. If it is 2, the function draws the contours, all the nested contours, all the nested-to-nested contours, and so on. This parameter is only taken into account when there is hierarchy available.
|
||||
@param offset optional contour shift parameter.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contours_begin_contours.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
Contour Approximation Method
|
||||
============================
|
||||
|
||||
This is the fifth argument in cv.findContours function. What does it denote actually?
|
||||
|
||||
Above, we told that contours are the boundaries of a shape with same intensity. It stores the (x,y)
|
||||
coordinates of the boundary of a shape. But does it store all the coordinates ? That is specified by
|
||||
this contour approximation method.
|
||||
|
||||
If you pass cv.ContourApproximationModes.CHAIN_APPROX_NONE.value, all the boundary points are stored. But actually do we need all
|
||||
the points? For eg, you found the contour of a straight line. Do you need all the points on the line
|
||||
to represent that line? No, we need just two end points of that line. This is what
|
||||
cv.CHAIN_APPROX_SIMPLE does. It removes all redundant points and compresses the contour, thereby
|
||||
saving memory.
|
||||
@@ -0,0 +1,158 @@
|
||||
Contours Hierarchy {#tutorial_js_contours_hierarchy}
|
||||
==================
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
- This time, we learn about the hierarchy of contours, i.e. the parent-child relationship in Contours.
|
||||
|
||||
Theory
|
||||
------
|
||||
|
||||
In the last few articles on contours, we have worked with several functions related to contours
|
||||
provided by OpenCV. But when we found the contours in image using **cv.findContours()** function,
|
||||
we have passed an argument, **Contour Retrieval Mode**. We usually passed **cv.RETR_LIST** or
|
||||
**cv.RETR_TREE** and it worked nice. But what does it actually mean ?
|
||||
|
||||
Also, in the output, we got three arrays, first is the image, second is our contours, and one more
|
||||
output which we named as **hierarchy** (Please checkout the codes in previous articles). But we
|
||||
never used this hierarchy anywhere. Then what is this hierarchy and what is it for ? What is its
|
||||
relationship with the previous mentioned function argument ?
|
||||
|
||||
That is what we are going to deal in this article.
|
||||
|
||||
### What is Hierarchy?
|
||||
|
||||
Normally we use the **cv.findContours()** function to detect objects in an image, right ? Sometimes
|
||||
objects are in different locations. But in some cases, some shapes are inside other shapes. Just
|
||||
like nested figures. In this case, we call outer one as **parent** and inner one as **child**. This
|
||||
way, contours in an image has some relationship to each other. And we can specify how one contour is
|
||||
connected to each other, like, is it child of some other contour, or is it a parent etc.
|
||||
Representation of this relationship is called the **Hierarchy**.
|
||||
|
||||
Consider an example image below :
|
||||
|
||||

|
||||
|
||||
In this image, there are a few shapes which I have numbered from **0-5**. *2 and 2a* denotes the
|
||||
external and internal contours of the outermost box.
|
||||
|
||||
Here, contours 0,1,2 are **external or outermost**. We can say, they are in **hierarchy-0** or
|
||||
simply they are in **same hierarchy level**.
|
||||
|
||||
Next comes **contour-2a**. It can be considered as a **child of contour-2** (or in opposite way,
|
||||
contour-2 is parent of contour-2a). So let it be in **hierarchy-1**. Similarly contour-3 is child of
|
||||
contour-2a and it comes in next hierarchy. Finally contours 4,5 are the children of contour-3a, and
|
||||
they come in the last hierarchy level. From the way I numbered the boxes, I would say contour-4 is
|
||||
the first child of contour-3a (It can be contour-5 also).
|
||||
|
||||
I mentioned these things to understand terms like **same hierarchy level**, **external contour**,
|
||||
**child contour**, **parent contour**, **first child** etc. Now let's get into OpenCV.
|
||||
|
||||
### Hierarchy Representation in OpenCV
|
||||
|
||||
So each contour has its own information regarding what hierarchy it is, who is its child, who is its
|
||||
parent etc. OpenCV represents it as an array of four values : **[Next, Previous, First_Child,
|
||||
Parent]**
|
||||
|
||||
<center>*"Next denotes next contour at the same hierarchical level."*</center>
|
||||
|
||||
For eg, take contour-0 in our picture. Who is next contour in its same level ? It is contour-1. So
|
||||
simply put Next = 1. Similarly for Contour-1, next is contour-2. So Next = 2.
|
||||
|
||||
What about contour-2? There is no next contour in the same level. So simply, put Next = -1. What
|
||||
about contour-4? It is in same level with contour-5. So its next contour is contour-5, so Next = 5.
|
||||
|
||||
<center>*"Previous denotes previous contour at the same hierarchical level."*</center>
|
||||
|
||||
It is same as above. Previous contour of contour-1 is contour-0 in the same level. Similarly for
|
||||
contour-2, it is contour-1. And for contour-0, there is no previous, so put it as -1.
|
||||
|
||||
<center>*"First_Child denotes its first child contour."*</center>
|
||||
|
||||
There is no need of any explanation. For contour-2, child is contour-2a. So it gets the
|
||||
corresponding index value of contour-2a. What about contour-3a? It has two children. But we take
|
||||
only first child. And it is contour-4. So First_Child = 4 for contour-3a.
|
||||
|
||||
<center>*"Parent denotes index of its parent contour."*</center>
|
||||
|
||||
It is just opposite of **First_Child**. Both for contour-4 and contour-5, parent contour is
|
||||
contour-3a. For contour-3a, it is contour-3 and so on.
|
||||
|
||||
@note If there is no child or parent, that field is taken as -1
|
||||
|
||||
So now we know about the hierarchy style used in OpenCV, we can check into Contour Retrieval Modes
|
||||
in OpenCV with the help of same image given above. ie what do flags like cv.RETR_LIST,
|
||||
cv.RETR_TREE, cv.RETR_CCOMP, cv.RETR_EXTERNAL etc mean?
|
||||
|
||||
Contour Retrieval Mode
|
||||
----------------------
|
||||
|
||||
### 1. RETR_LIST
|
||||
|
||||
This is the simplest of the four flags (from explanation point of view). It simply retrieves all the
|
||||
contours, but doesn't create any parent-child relationship. **Parents and kids are equal under this
|
||||
rule, and they are just contours**. ie they all belongs to same hierarchy level.
|
||||
|
||||
So here, 3rd and 4th term in hierarchy array is always -1. But obviously, Next and Previous terms
|
||||
will have their corresponding values.
|
||||
|
||||
### 2. RETR_EXTERNAL
|
||||
|
||||
If you use this flag, it returns only extreme outer flags. All child contours are left behind. **We
|
||||
can say, under this law, Only the eldest in every family is taken care of. It doesn't care about
|
||||
other members of the family)**.
|
||||
|
||||
|
||||
### 3. RETR_CCOMP
|
||||
|
||||
This flag retrieves all the contours and arranges them to a 2-level hierarchy. ie external contours
|
||||
of the object (ie its boundary) are placed in hierarchy-1. And the contours of holes inside object
|
||||
(if any) is placed in hierarchy-2. If any object inside it, its contour is placed again in
|
||||
hierarchy-1 only. And its hole in hierarchy-2 and so on.
|
||||
|
||||
Just consider the image of a "big white zero" on a black background. Outer circle of zero belongs to
|
||||
first hierarchy, and inner circle of zero belongs to second hierarchy.
|
||||
|
||||
We can explain it with a simple image. Here I have labelled the order of contours in red color and
|
||||
the hierarchy they belongs to, in green color (either 1 or 2). The order is same as the order OpenCV
|
||||
detects contours.
|
||||
|
||||

|
||||
|
||||
So consider first contour, ie contour-0. It is hierarchy-1. It has two holes, contours 1&2, and they
|
||||
belong to hierarchy-2. So for contour-0, Next contour in same hierarchy level is contour-3. And
|
||||
there is no previous one. And its first is child is contour-1 in hierarchy-2. It has no parent,
|
||||
because it is in hierarchy-1. So its hierarchy array is [3,-1,1,-1]
|
||||
|
||||
Now take contour-1. It is in hierarchy-2. Next one in same hierarchy (under the parenthood of
|
||||
contour-1) is contour-2. No previous one. No child, but parent is contour-0. So array is
|
||||
[2,-1,-1,0].
|
||||
|
||||
Similarly contour-2 : It is in hierarchy-2. There is not next contour in same hierarchy under
|
||||
contour-0. So no Next. Previous is contour-1. No child, parent is contour-0. So array is
|
||||
[-1,1,-1,0].
|
||||
|
||||
Contour - 3 : Next in hierarchy-1 is contour-5. Previous is contour-0. Child is contour-4 and no
|
||||
parent. So array is [5,0,4,-1].
|
||||
|
||||
Contour - 4 : It is in hierarchy 2 under contour-3 and it has no sibling. So no next, no previous,
|
||||
no child, parent is contour-3. So array is [-1,-1,-1,3].
|
||||
|
||||
|
||||
### 4. RETR_TREE
|
||||
|
||||
And this is the final guy, Mr.Perfect. It retrieves all the contours and creates a full family
|
||||
hierarchy list. **It even tells, who is the grandpa, father, son, grandson and even beyond... :)**.
|
||||
|
||||
For example, I took above image, rewrite the code for cv.RETR_TREE, reorder the contours as per the
|
||||
result given by OpenCV and analyze it. Again, red letters give the contour number and green letters
|
||||
give the hierarchy order.
|
||||
|
||||

|
||||
|
||||
Take contour-0 : It is in hierarchy-0. Next contour in same hierarchy is contour-7. No previous
|
||||
contours. Child is contour-1. And no parent. So array is [7,-1,1,-1].
|
||||
|
||||
Take contour-2 : It is in hierarchy-1. No contour in same level. No previous one. Child is
|
||||
contour-2. Parent is contour-0. So array is [-1,-1,2,0].
|
||||
@@ -0,0 +1,72 @@
|
||||
Contours : More Functions {#tutorial_js_contours_more_functions}
|
||||
=========================
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
- Convexity defects and how to find them.
|
||||
- Finding shortest distance from a point to a polygon
|
||||
- Matching different shapes
|
||||
|
||||
Theory and Code
|
||||
---------------
|
||||
|
||||
### 1. Convexity Defects
|
||||
|
||||
We saw what is convex hull in second chapter about contours. Any deviation of the object from this
|
||||
hull can be considered as convexity defect.We can visualize it using an image. We draw a
|
||||
line joining start point and end point, then draw a circle at the farthest point.
|
||||
|
||||
@note Remember we have to pass returnPoints = False while finding convex hull, in order to find
|
||||
convexity defects.
|
||||
|
||||
We use the function: **cv.convexityDefects (contour, convexhull, convexityDefect)**
|
||||
@param contour input contour.
|
||||
@param convexhull convex hull obtained using convexHull that should contain indices of the contour points that make the hull
|
||||
@param convexityDefect the output vector of convexity defects. Each convexity defect is represented as 4-element(start_index, end_index, farthest_pt_index, fixpt_depth), where indices are 0-based indices in the original contour of the convexity defect beginning, end and the farthest point, and fixpt_depth is fixed-point approximation (with 8 fractional bits) of the distance between the farthest contour point and the hull. That is, to get the floating-point value of the depth will be fixpt_depth/256.0.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contours_more_functions_convexityDefects.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
|
||||
### 2. Point Polygon Test
|
||||
|
||||
This function finds the shortest distance between a point in the image and a contour. It returns the
|
||||
distance which is negative when point is outside the contour, positive when point is inside and zero
|
||||
if point is on the contour.
|
||||
|
||||
We use the function: **cv.pointPolygonTest (contour, pt, measureDist)**
|
||||
@param contour input contour.
|
||||
@param pt point tested against the contour.
|
||||
@param measureDist if true, the function estimates the signed distance from the point to the nearest contour edge. Otherwise, the function only checks if the point is inside a contour or not.
|
||||
|
||||
@code{.js}
|
||||
let dist = cv.pointPolygonTest(cnt, new cv.Point(50, 50), true);
|
||||
@endcode
|
||||
|
||||
### 3. Match Shapes
|
||||
|
||||
OpenCV comes with a function **cv.matchShapes()** which enables us to compare two shapes, or two
|
||||
contours and returns a metric showing the similarity. The lower the result, the better match it is.
|
||||
It is calculated based on the hu-moment values. Different measurement methods are explained in the
|
||||
docs.
|
||||
|
||||
We use the function: **cv.matchShapes (contour1, contour2, method, parameter)**
|
||||
@param contour1 first contour or grayscale image.
|
||||
@param contour2 second contour or grayscale image.
|
||||
@param method comparison method, see cv::ShapeMatchModes
|
||||
@param parameter method-specific parameter(not supported now).
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
\htmlonly
|
||||
<iframe src="../../js_contours_more_functions_shape.html" width="100%"
|
||||
onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
|
||||
</iframe>
|
||||
\endhtmlonly
|
||||
@@ -0,0 +1,26 @@
|
||||
Contours in OpenCV.js {#tutorial_js_table_of_contents_contours}
|
||||
==================
|
||||
|
||||
- @subpage tutorial_js_contours_begin
|
||||
|
||||
Learn to find and draw Contours.
|
||||
|
||||
- @subpage tutorial_js_contour_features
|
||||
|
||||
Learn
|
||||
to find different features of contours like area, perimeter, bounding rectangle etc.
|
||||
|
||||
- @subpage tutorial_js_contour_properties
|
||||
|
||||
Learn
|
||||
to find different properties of contours like Solidity, Mean Intensity etc.
|
||||
|
||||
- @subpage tutorial_js_contours_more_functions
|
||||
|
||||
Learn
|
||||
to find convexity defects, pointPolygonTest, match different shapes etc.
|
||||
|
||||
- @subpage tutorial_js_contours_hierarchy
|
||||
|
||||
Learn
|
||||
about Contour Hierarchy
|
||||
Reference in New Issue
Block a user