'min_max_loc' : ('http://opencv.willowgarage.com/documentation/cpp/core_operations_on_arrays.html?#minMaxLoc%s', None),
'mix_channels' : ( 'http://opencv.willowgarage.com/documentation/cpp/core_operations_on_arrays.html?#mixChannels%s', None),
'calc_back_project' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_histograms.html?#calcBackProject%s', None),
- 'compare_hist' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_histograms.html?#compareHist%s', None)
+ 'compare_hist' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_histograms.html?#compareHist%s', None),
+ 'corner_harris' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cornerHarris%s', None),
+ 'good_features_to_track' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cv-goodfeaturestotrack%s', None),
+ 'corner_min_eigenval' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cv-cornermineigenval%s', None),
+ 'corner_eigenvals_and_vecs' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cv-cornereigenvalsandvecs%s', None),
+ 'corner_sub_pix' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_feature_detection.html?#cv-cornersubpix%s', None),
+ 'find_contours' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-findcontours%s', None),
+ 'convex_hull' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-convexhull%s', None),
+ 'draw_contours' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-drawcontours%s', None),
+ 'bounding_rect' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-boundingrect%s', None),
+ 'min_enclosing_circle' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-minenclosingcircle%s', None),
+ 'min_area_rect' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-minarearect%s', None),
+ 'fit_ellipse' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-fitellipse%s', None),
+ 'moments' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-moments%s', None),
+ 'contour_area' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-contourarea%s', None),
+ 'arc_length' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-arclength%s', None),
+ 'point_polygon_test' : ('http://opencv.willowgarage.com/documentation/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-pointpolygontest%s', None)
}
Learn about how to use the feature points detectors, descriptors and matching framework found inside OpenCV.
-.. include:: ../../definitions/noContent.rst
+.. include:: ../../definitions/tocDefinitions.rst
+
++
+ .. tabularcolumns:: m{100pt} m{300pt}
+ .. cssclass:: toctableopencv
+
+ ===================== ==============================================
+ |Harris| **Title:** :ref:`harris_detector`
+
+ *Compatibility:* > OpenCV 2.0
+
+ *Author:* |Author_AnaH|
+
+ Why is it a good idea to track corners? We learn to use the Harris method to detect corners
+
+ ===================== ==============================================
+
+ .. |Harris| image:: images/trackingmotion/Harris_Detector_Cover.jpg
+ :height: 90pt
+ :width: 90pt
+
+
++
+ .. tabularcolumns:: m{100pt} m{300pt}
+ .. cssclass:: toctableopencv
+
+ ===================== ==============================================
+ |ShiTomasi| **Title:** :ref:`good_features_to_track`
+
+ *Compatibility:* > OpenCV 2.0
+
+ *Author:* |Author_AnaH|
+
+ Where we use an improved method to detect corners more accuratelyI
+
+ ===================== ==============================================
+
+ .. |ShiTomasi| image:: images/trackingmotion/Shi_Tomasi_Detector_Cover.jpg
+ :height: 90pt
+ :width: 90pt
+
+
++
+ .. tabularcolumns:: m{100pt} m{300pt}
+ .. cssclass:: toctableopencv
+
+ ===================== ==============================================
+ |GenericCorner| **Title:** :ref:`generic_corner_detector`
+
+ *Compatibility:* > OpenCV 2.0
+
+ *Author:* |Author_AnaH|
+
+ Here you will learn how to use OpenCV functions to make your personalized corner detector!
+
+ ===================== ==============================================
+
+ .. |GenericCorner| image:: images/trackingmotion/Generic_Corner_Detector_Cover.jpg
+ :height: 90pt
+ :width: 90pt
+
+
++
+ .. tabularcolumns:: m{100pt} m{300pt}
+ .. cssclass:: toctableopencv
+
+ ===================== ==============================================
+ |Subpixel| **Title:** :ref:`corner_subpixeles`
+
+ *Compatibility:* > OpenCV 2.0
+
+ *Author:* |Author_AnaH|
+
+ Is pixel resolution enough? Here we learn a simple method to improve our accuracy.
+
+ ===================== ==============================================
+
+ .. |Subpixel| image:: images/trackingmotion/Corner_Subpixeles_Cover.jpg
+ :height: 90pt
+ :width: 90pt
+
+.. toctree::
+ :hidden:
+
+ ../trackingmotion/harris_detector/harris_detector
+ ../trackingmotion/good_features_to_track/good_features_to_track.rst
+ ../trackingmotion/generic_corner_detector/generic_corner_detector
+ ../trackingmotion/corner_subpixeles/corner_subpixeles
--- /dev/null
+.. _corner_subpixeles:
+
+Detecting corners location in subpixeles
+****************************************
+
+Goal
+=====
+
+In this tutorial you will learn how to:
+
+.. container:: enumeratevisibleitemswithsquare
+
+ * Use the OpenCV function :corner_sub_pix:`cornerSubPix <>` to find more exact corner positions (more exact than integer pixels).
+
+
+Theory
+======
+
+Code
+====
+
+This tutorial code's is shown lines below. You can also download it from `here <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/TrackingMotion/cornerSubPix_Demo.cpp>`_
+
+.. code-block:: cpp
+
+ #include "opencv2/highgui/highgui.hpp"
+ #include "opencv2/imgproc/imgproc.hpp"
+ #include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ using namespace cv;
+ using namespace std;
+
+ /// Global variables
+ Mat src, src_gray;
+
+ int maxCorners = 10;
+ int maxTrackbar = 25;
+
+ RNG rng(12345);
+ char* source_window = "Image";
+
+ /// Function header
+ void goodFeaturesToTrack_Demo( int, void* );
+
+ /** @function main */
+ int main( int argc, char** argv )
+ {
+ /// Load source image and convert it to gray
+ src = imread( argv[1], 1 );
+ cvtColor( src, src_gray, CV_BGR2GRAY );
+
+ /// Create Window
+ namedWindow( source_window, CV_WINDOW_AUTOSIZE );
+
+ /// Create Trackbar to set the number of corners
+ createTrackbar( "Max corners:", source_window, &maxCorners, maxTrackbar, goodFeaturesToTrack_Demo );
+
+ imshow( source_window, src );
+
+ goodFeaturesToTrack_Demo( 0, 0 );
+
+ waitKey(0);
+ return(0);
+ }
+
+ /**
+ * @function goodFeaturesToTrack_Demo.cpp
+ * @brief Apply Shi-Tomasi corner detector
+ */
+ void goodFeaturesToTrack_Demo( int, void* )
+ {
+ if( maxCorners < 1 ) { maxCorners = 1; }
+
+ /// Parameters for Shi-Tomasi algorithm
+ vector<Point2f> corners;
+ double qualityLevel = 0.01;
+ double minDistance = 10;
+ int blockSize = 3;
+ bool useHarrisDetector = false;
+ double k = 0.04;
+
+ /// Copy the source image
+ Mat copy;
+ copy = src.clone();
+
+ /// Apply corner detection
+ goodFeaturesToTrack( src_gray,
+ corners,
+ maxCorners,
+ qualityLevel,
+ minDistance,
+ Mat(),
+ blockSize,
+ useHarrisDetector,
+ k );
+
+
+ /// Draw corners detected
+ cout<<"** Number of corners detected: "<<corners.size()<<endl;
+ int r = 4;
+ for( int i = 0; i < corners.size(); i++ )
+ { circle( copy, corners[i], r, Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)), -1, 8, 0 ); }
+
+ /// Show what you got
+ namedWindow( source_window, CV_WINDOW_AUTOSIZE );
+ imshow( source_window, copy );
+
+ /// Set the neeed parameters to find the refined corners
+ Size winSize = Size( 5, 5 );
+ Size zeroZone = Size( -1, -1 );
+ TermCriteria criteria = TermCriteria( CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 40, 0.001 );
+
+ /// Calculate the refined corner locations
+ cornerSubPix( src_gray, corners, winSize, zeroZone, criteria );
+
+ /// Write them down
+ for( int i = 0; i < corners.size(); i++ )
+ { cout<<" -- Refined Corner ["<<i<<"] ("<<corners[i].x<<","<<corners[i].y<<")"<<endl; }
+ }
+
+
+Explanation
+============
+
+Result
+======
+
+.. image:: images/Corner_Subpixeles_Original_Image.jpg
+ :height: 200pt
+ :align: center
+
+Here is the result:
+
+.. image:: images/Corner_Subpixeles_Result.jpg
+ :height: 100pt
+ :align: center
+
--- /dev/null
+.. _generic_corner_detector:
+
+Creating yor own corner detector
+********************************
+
+Goal
+=====
+
+In this tutorial you will learn how to:
+
+.. container:: enumeratevisibleitemswithsquare
+
+ * Use the OpenCV function :corner_eigenvals_and_vecs:`cornerEigenValsAndVecs <>` to find the eigenvalues and eigenvectors to determine if a pixel is a corner.
+ * Use the OpenCV function :corner_min_eigenval:`cornerMinEigenVal <>` to find the minimum eigenvalues for corner detection.
+ * To implement our own version of the Harris detector as well as the Shi-Tomasi detector, by using the two functions above.
+
+Theory
+======
+
+Code
+====
+
+This tutorial code's is shown lines below. You can also download it from `here <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/TrackingMotion/cornerDetector_Demo.cpp>`_
+
+.. code-block:: cpp
+
+ #include "opencv2/highgui/highgui.hpp"
+ #include "opencv2/imgproc/imgproc.hpp"
+ #include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ using namespace cv;
+ using namespace std;
+
+ /// Global variables
+ Mat src, src_gray;
+ Mat myHarris_dst; Mat myHarris_copy; Mat Mc;
+ Mat myShiTomasi_dst; Mat myShiTomasi_copy;
+
+ int myShiTomasi_qualityLevel = 50;
+ int myHarris_qualityLevel = 50;
+ int max_qualityLevel = 100;
+
+ double myHarris_minVal; double myHarris_maxVal;
+ double myShiTomasi_minVal; double myShiTomasi_maxVal;
+
+ RNG rng(12345);
+
+ char* myHarris_window = "My Harris corner detector";
+ char* myShiTomasi_window = "My Shi Tomasi corner detector";
+
+ /// Function headers
+ void myShiTomasi_function( int, void* );
+ void myHarris_function( int, void* );
+
+ /** @function main */
+ int main( int argc, char** argv )
+ {
+ /// Load source image and convert it to gray
+ src = imread( argv[1], 1 );
+ cvtColor( src, src_gray, CV_BGR2GRAY );
+
+ /// Set some parameters
+ int blockSize = 3; int apertureSize = 3;
+
+ /// My Harris matrix -- Using cornerEigenValsAndVecs
+ myHarris_dst = Mat::zeros( src_gray.size(), CV_32FC(6) );
+ Mc = Mat::zeros( src_gray.size(), CV_32FC1 );
+
+ cornerEigenValsAndVecs( src_gray, myHarris_dst, blockSize, apertureSize, BORDER_DEFAULT );
+
+ /* calculate Mc */
+ for( int j = 0; j < src_gray.rows; j++ )
+ { for( int i = 0; i < src_gray.cols; i++ )
+ {
+ float lambda_1 = myHarris_dst.at<float>( j, i, 0 );
+ float lambda_2 = myHarris_dst.at<float>( j, i, 1 );
+ Mc.at<float>(j,i) = lambda_1*lambda_2 - 0.04*pow( ( lambda_1 + lambda_2 ), 2 );
+ }
+ }
+
+ minMaxLoc( Mc, &myHarris_minVal, &myHarris_maxVal, 0, 0, Mat() );
+
+ /* Create Window and Trackbar */
+ namedWindow( myHarris_window, CV_WINDOW_AUTOSIZE );
+ createTrackbar( " Quality Level:", myHarris_window, &myHarris_qualityLevel, max_qualityLevel, myHarris_function );
+ myHarris_function( 0, 0 );
+
+ /// My Shi-Tomasi -- Using cornerMinEigenVal
+ myShiTomasi_dst = Mat::zeros( src_gray.size(), CV_32FC1 );
+ cornerMinEigenVal( src_gray, myShiTomasi_dst, blockSize, apertureSize, BORDER_DEFAULT );
+
+ minMaxLoc( myShiTomasi_dst, &myShiTomasi_minVal, &myShiTomasi_maxVal, 0, 0, Mat() );
+
+ /* Create Window and Trackbar */
+ namedWindow( myShiTomasi_window, CV_WINDOW_AUTOSIZE );
+ createTrackbar( " Quality Level:", myShiTomasi_window, &myShiTomasi_qualityLevel, max_qualityLevel, myShiTomasi_function );
+ myShiTomasi_function( 0, 0 );
+
+ waitKey(0);
+ return(0);
+ }
+
+ /** @function myShiTomasi_function */
+ void myShiTomasi_function( int, void* )
+ {
+ myShiTomasi_copy = src.clone();
+
+ if( myShiTomasi_qualityLevel < 1 ) { myShiTomasi_qualityLevel = 1; }
+
+ for( int j = 0; j < src_gray.rows; j++ )
+ { for( int i = 0; i < src_gray.cols; i++ )
+ {
+ if( myShiTomasi_dst.at<float>(j,i) > myShiTomasi_minVal + ( myShiTomasi_maxVal - myShiTomasi_minVal )*myShiTomasi_qualityLevel/max_qualityLevel )
+ { circle( myShiTomasi_copy, Point(i,j), 4, Scalar( rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255) ), -1, 8, 0 ); }
+ }
+ }
+ imshow( myShiTomasi_window, myShiTomasi_copy );
+ }
+
+ /** @function myHarris_function */
+ void myHarris_function( int, void* )
+ {
+ myHarris_copy = src.clone();
+
+ if( myHarris_qualityLevel < 1 ) { myHarris_qualityLevel = 1; }
+
+ for( int j = 0; j < src_gray.rows; j++ )
+ { for( int i = 0; i < src_gray.cols; i++ )
+ {
+ if( Mc.at<float>(j,i) > myHarris_minVal + ( myHarris_maxVal - myHarris_minVal )*myHarris_qualityLevel/max_qualityLevel )
+ { circle( myHarris_copy, Point(i,j), 4, Scalar( rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255) ), -1, 8, 0 ); }
+ }
+ }
+ imshow( myHarris_window, myHarris_copy );
+ }
+
+
+
+Explanation
+============
+
+Result
+======
+
+.. image:: images/My_Harris_corner_detector_Result.jpg
+ :height: 200pt
+ :align: center
+
+
+.. image:: images/My_Shi_Tomasi_corner_detector_Result.jpg
+ :height: 200pt
+ :align: center
+
--- /dev/null
+.. _good_features_to_track:
+
+Shi-Tomasi corner detector
+**************************
+
+Goal
+=====
+
+In this tutorial you will learn how to:
+
+.. container:: enumeratevisibleitemswithsquare
+
+ * Use the function :good_features_to_track:`goodFeaturesToTrack <>` to detect corners using the Shi-Tomasi method.
+
+Theory
+======
+
+Code
+====
+
+This tutorial code's is shown lines below. You can also download it from `here <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/TrackingMotion/goodFeaturesToTrack_Demo.cpp>`_
+
+.. code-block:: cpp
+
+ #include "opencv2/highgui/highgui.hpp"
+ #include "opencv2/imgproc/imgproc.hpp"
+ #include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ using namespace cv;
+ using namespace std;
+
+ /// Global variables
+ Mat src, src_gray;
+
+ int maxCorners = 23;
+ int maxTrackbar = 100;
+
+ RNG rng(12345);
+ char* source_window = "Image";
+
+ /// Function header
+ void goodFeaturesToTrack_Demo( int, void* );
+
+ /**
+ * @function main
+ */
+ int main( int argc, char** argv )
+ {
+ /// Load source image and convert it to gray
+ src = imread( argv[1], 1 );
+ cvtColor( src, src_gray, CV_BGR2GRAY );
+
+ /// Create Window
+ namedWindow( source_window, CV_WINDOW_AUTOSIZE );
+
+ /// Create Trackbar to set the number of corners
+ createTrackbar( "Max corners:", source_window, &maxCorners, maxTrackbar, goodFeaturesToTrack_Demo );
+
+ imshow( source_window, src );
+
+ goodFeaturesToTrack_Demo( 0, 0 );
+
+ waitKey(0);
+ return(0);
+ }
+
+ /**
+ * @function goodFeaturesToTrack_Demo.cpp
+ * @brief Apply Shi-Tomasi corner detector
+ */
+ void goodFeaturesToTrack_Demo( int, void* )
+ {
+ if( maxCorners < 1 ) { maxCorners = 1; }
+
+ /// Parameters for Shi-Tomasi algorithm
+ vector<Point2f> corners;
+ double qualityLevel = 0.01;
+ double minDistance = 10;
+ int blockSize = 3;
+ bool useHarrisDetector = false;
+ double k = 0.04;
+
+ /// Copy the source image
+ Mat copy;
+ copy = src.clone();
+
+ /// Apply corner detection
+ goodFeaturesToTrack( src_gray,
+ corners,
+ maxCorners,
+ qualityLevel,
+ minDistance,
+ Mat(),
+ blockSize,
+ useHarrisDetector,
+ k );
+
+
+ /// Draw corners detected
+ cout<<"** Number of corners detected: "<<corners.size()<<endl;
+ int r = 4;
+ for( int i = 0; i < corners.size(); i++ )
+ { circle( copy, corners[i], r, Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)), -1, 8, 0 ); }
+
+ /// Show what you got
+ namedWindow( source_window, CV_WINDOW_AUTOSIZE );
+ imshow( source_window, copy );
+ }
+
+Explanation
+============
+
+Result
+======
+
+.. image:: images/Shi_Tomasi_Detector_Result.jpg
+ :height: 200pt
+ :align: center
+
+
--- /dev/null
+.. _harris_detector:
+
+Harris corner detector
+**********************
+
+Goal
+=====
+
+In this tutorial you will learn how to:
+
+.. container:: enumeratevisibleitemswithsquare
+
+ * Use the function :corner_harris:`cornerHarris <>` to detect corners using the Harris-Stephens method.
+
+Theory
+======
+
+Code
+====
+
+This tutorial code's is shown lines below. You can also download it from `here <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/TrackingMotion/cornerHarris_Demo.cpp>`_
+
+.. code-block:: cpp
+
+ #include "opencv2/highgui/highgui.hpp"
+ #include "opencv2/imgproc/imgproc.hpp"
+ #include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ using namespace cv;
+ using namespace std;
+
+ /// Global variables
+ Mat src, src_gray;
+ int thresh = 200;
+ int max_thresh = 255;
+
+ char* source_window = "Source image";
+ char* corners_window = "Corners detected";
+
+ /// Function header
+ void cornerHarris_demo( int, void* );
+
+ /** @function main */
+ int main( int argc, char** argv )
+ {
+ /// Load source image and convert it to gray
+ src = imread( argv[1], 1 );
+ cvtColor( src, src_gray, CV_BGR2GRAY );
+
+ /// Create a window and a trackbar
+ namedWindow( source_window, CV_WINDOW_AUTOSIZE );
+ createTrackbar( "Threshold: ", source_window, &thresh, max_thresh, cornerHarris_demo );
+ imshow( source_window, src );
+
+ cornerHarris_demo( 0, 0 );
+
+ waitKey(0);
+ return(0);
+ }
+
+ /** @function cornerHarris_demo */
+ void cornerHarris_demo( int, void* )
+ {
+
+ Mat dst, dst_norm, dst_norm_scaled;
+ dst = Mat::zeros( src.size(), CV_32FC1 );
+
+ /// Detector parameters
+ int blockSize = 2;
+ int apertureSize = 3;
+ double k = 0.04;
+
+ /// Detecting corners
+ cornerHarris( src_gray, dst, blockSize, apertureSize, k, BORDER_DEFAULT );
+
+ /// Normalizing
+ normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
+ convertScaleAbs( dst_norm, dst_norm_scaled );
+
+ /// Drawing a circle around corners
+ for( int j = 0; j < dst_norm.rows ; j++ )
+ { for( int i = 0; i < dst_norm.cols; i++ )
+ {
+ if( (int) dst_norm.at<float>(j,i) > thresh )
+ {
+ circle( dst_norm_scaled, Point( i, j ), 5, Scalar(0), 2, 8, 0 );
+ }
+ }
+ }
+ /// Showing the result
+ namedWindow( corners_window, CV_WINDOW_AUTOSIZE );
+ imshow( corners_window, dst_norm_scaled );
+ }
+
+
+Explanation
+============
+
+Result
+======
+
+The original image:
+
+.. image:: images/Harris_Detector_Original_Image.jpg
+ :height: 200pt
+ :align: center
+
+The detected corners are surrounded by a small black circle
+
+.. image:: images/Harris_Detector_Result.jpg
+ :height: 200pt
+ :align: center
+
+
--- /dev/null
+.. _bounding_rects_circles:
+
+
+Creating Bounding boxes and circles for contours
+*************************************************
+
+Goal
+=====
+
+In this tutorial you will learn how to:
+
+.. container:: enumeratevisibleitemswithsquare
+
+ * Use the OpenCV function :bounding_rect:`boundingRect <>`
+ * Use the OpenCV function :min_enclosing_circle:`minEnclosingCircle <>`
+
+
+Theory
+======
+
+Code
+====
+
+This tutorial code's is shown lines below. You can also download it from `here <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp>`_
+
+.. code-block:: cpp
+
+ #include "opencv2/highgui/highgui.hpp"
+ #include "opencv2/imgproc/imgproc.hpp"
+ #include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ using namespace cv;
+ using namespace std;
+
+ Mat src; Mat src_gray;
+ int thresh = 100;
+ int max_thresh = 255;
+ RNG rng(12345);
+
+ /// Function header
+ void thresh_callback(int, void* );
+
+ /** @function main */
+ int main( int argc, char** argv )
+ {
+ /// Load source image and convert it to gray
+ src = imread( argv[1], 1 );
+
+ /// Convert image to gray and blur it
+ cvtColor( src, src_gray, CV_BGR2GRAY );
+ blur( src_gray, src_gray, Size(3,3) );
+
+ /// Create Window
+ char* source_window = "Source";
+ namedWindow( source_window, CV_WINDOW_AUTOSIZE );
+ imshow( source_window, src );
+
+ createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback );
+ thresh_callback( 0, 0 );
+
+ waitKey(0);
+ return(0);
+ }
+
+ /** @function thresh_callback */
+ void thresh_callback(int, void* )
+ {
+ Mat threshold_output;
+ vector<vector<Point> > contours;
+ vector<Vec4i> hierarchy;
+
+ /// Detect edges using Threshold
+ threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
+ /// Find contours
+ findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
+
+ /// Approximate contours to polygons + get bounding rects and circles
+ vector<vector<Point> > contours_poly( contours.size() );
+ vector<Rect> boundRect( contours.size() );
+ vector<Point2f>center( contours.size() );
+ vector<float>radius( contours.size() );
+
+ for( int i = 0; i < contours.size(); i++ )
+ { approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
+ boundRect[i] = boundingRect( Mat(contours_poly[i]) );
+ minEnclosingCircle( contours_poly[i], center[i], radius[i] );
+ }
+
+
+ /// Draw polygonal contour + bonding rects + circles
+ Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
+ for( int i = 0; i< contours.size(); i++ )
+ {
+ Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
+ drawContours( drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
+ rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
+ circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 );
+ }
+
+ /// Show in a window
+ namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
+ imshow( "Contours", drawing );
+ }
+
+Explanation
+============
+
+Result
+======
+
+#. Here it is:
+
+ ========== ==========
+ |BRC_0| |BRC_1|
+ ========== ==========
+
+ .. |BRC_0| image:: images/Bounding_Rects_Circles_Source_Image.jpg
+ :height: 300pt
+ :align: middle
+
+ .. |BRC_1| image:: images/Bounding_Rects_Circles_Result.jpg
+ :height: 300pt
+ :align: middle
+
--- /dev/null
+.. _bounding_rotated_ellipses:
+
+
+Creating Bounding rotated boxes and ellipses for contours
+**********************************************************
+
+Goal
+=====
+
+In this tutorial you will learn how to:
+
+.. container:: enumeratevisibleitemswithsquare
+
+ * Use the OpenCV function :min_area_rect:`minAreaRect <>`
+ * Use the OpenCV function :fit_ellipse:`fitEllipse <>`
+
+
+Theory
+======
+
+Code
+====
+
+This tutorial code's is shown lines below. You can also download it from `here <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp>`_
+
+.. code-block:: cpp
+
+ #include "opencv2/highgui/highgui.hpp"
+ #include "opencv2/imgproc/imgproc.hpp"
+ #include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ using namespace cv;
+ using namespace std;
+
+ Mat src; Mat src_gray;
+ int thresh = 100;
+ int max_thresh = 255;
+ RNG rng(12345);
+
+ /// Function header
+ void thresh_callback(int, void* );
+
+ /** @function main */
+ int main( int argc, char** argv )
+ {
+ /// Load source image and convert it to gray
+ src = imread( argv[1], 1 );
+
+ /// Convert image to gray and blur it
+ cvtColor( src, src_gray, CV_BGR2GRAY );
+ blur( src_gray, src_gray, Size(3,3) );
+
+ /// Create Window
+ char* source_window = "Source";
+ namedWindow( source_window, CV_WINDOW_AUTOSIZE );
+ imshow( source_window, src );
+
+ createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback );
+ thresh_callback( 0, 0 );
+
+ waitKey(0);
+ return(0);
+ }
+
+ /** @function thresh_callback */
+ void thresh_callback(int, void* )
+ {
+ Mat threshold_output;
+ vector<vector<Point> > contours;
+ vector<Vec4i> hierarchy;
+
+ /// Detect edges using Threshold
+ threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
+ /// Find contours
+ findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
+
+ /// Find the rotated rectangles and ellipses for each contour
+ vector<RotatedRect> minRect( contours.size() );
+ vector<RotatedRect> minEllipse( contours.size() );
+
+ for( int i = 0; i < contours.size(); i++ )
+ { minRect[i] = minAreaRect( Mat(contours[i]) );
+ if( contours[i].size() > 5 )
+ { minEllipse[i] = fitEllipse( Mat(contours[i]) ); }
+ }
+
+ /// Draw contours + rotated rects + ellipses
+ Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
+ for( int i = 0; i< contours.size(); i++ )
+ {
+ Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
+ // contour
+ drawContours( drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
+ // ellipse
+ ellipse( drawing, minEllipse[i], color, 2, 8 );
+ // rotated rectangle
+ Point2f rect_points[4]; minRect[i].points( rect_points );
+ for( int j = 0; j < 4; j++ )
+ line( drawing, rect_points[j], rect_points[(j+1)%4], color, 1, 8 );
+ }
+
+ /// Show in a window
+ namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
+ imshow( "Contours", drawing );
+ }
+
+Explanation
+============
+
+Result
+======
+
+#. Here it is:
+
+ ========== ==========
+ |BRE_0| |BRE_1|
+ ========== ==========
+
+ .. |BRE_0| image:: images/Bounding_Rotated_Ellipses_Source_Image.jpg
+ :height: 300pt
+ :align: middle
+
+ .. |BRE_1| image:: images/Bounding_Rotated_Ellipses_Result.jpg
+ :height: 300pt
+ :align: middle
+
--- /dev/null
+.. _find_contours:
+
+Finding contours in your image
+******************************
+
+Goal
+=====
+
+In this tutorial you will learn how to:
+
+.. container:: enumeratevisibleitemswithsquare
+
+ * Use the OpenCV function :find_contours:`findContours <>`
+ * Use the OpenCV function :draw_contours:`drawContours <>`
+
+Theory
+======
+
+Code
+====
+
+This tutorial code's is shown lines below. You can also download it from `here <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp>`_
+
+.. code-block:: cpp
+
+ #include "opencv2/highgui/highgui.hpp"
+ #include "opencv2/imgproc/imgproc.hpp"
+ #include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ using namespace cv;
+ using namespace std;
+
+ Mat src; Mat src_gray;
+ int thresh = 100;
+ int max_thresh = 255;
+ RNG rng(12345);
+
+ /// Function header
+ void thresh_callback(int, void* );
+
+ /** @function main */
+ int main( int argc, char** argv )
+ {
+ /// Load source image and convert it to gray
+ src = imread( argv[1], 1 );
+
+ /// Convert image to gray and blur it
+ cvtColor( src, src_gray, CV_BGR2GRAY );
+ blur( src_gray, src_gray, Size(3,3) );
+
+ /// Create Window
+ char* source_window = "Source";
+ namedWindow( source_window, CV_WINDOW_AUTOSIZE );
+ imshow( source_window, src );
+
+ createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
+ thresh_callback( 0, 0 );
+
+ waitKey(0);
+ return(0);
+ }
+
+ /** @function thresh_callback */
+ void thresh_callback(int, void* )
+ {
+ Mat canny_output;
+ vector<vector<Point> > contours;
+ vector<Vec4i> hierarchy;
+
+ /// Detect edges using canny
+ Canny( src_gray, canny_output, thresh, thresh*2, 3 );
+ /// Find contours
+ findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
+
+ /// Draw contours
+ Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
+ for( int i = 0; i< contours.size(); i++ )
+ {
+ Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
+ drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
+ }
+
+ /// Show in a window
+ namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
+ imshow( "Contours", drawing );
+ }
+
+Explanation
+============
+
+Result
+======
+
+#. Here it is:
+
+ ============= =============
+ |contour_0| |contour_1|
+ ============= =============
+
+ .. |contour_0| image:: images/Find_Contours_Original_Image.jpg
+ :height: 300pt
+ :align: middle
+
+ .. |contour_1| image:: images/Find_Contours_Result.jpg
+ :height: 300pt
+ :align: middle
+
--- /dev/null
+.. _hull:
+
+Convex Hull
+***********
+
+Goal
+=====
+
+In this tutorial you will learn how to:
+
+.. container:: enumeratevisibleitemswithsquare
+
+ * Use the OpenCV function :convex_hull:`convexHull <>`
+
+
+Theory
+======
+
+Code
+====
+
+This tutorial code's is shown lines below. You can also download it from `here <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp>`_
+
+.. code-block:: cpp
+
+ #include "opencv2/highgui/highgui.hpp"
+ #include "opencv2/imgproc/imgproc.hpp"
+ #include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ using namespace cv;
+ using namespace std;
+
+ Mat src; Mat src_gray;
+ int thresh = 100;
+ int max_thresh = 255;
+ RNG rng(12345);
+
+ /// Function header
+ void thresh_callback(int, void* );
+
+ /** @function main */
+ int main( int argc, char** argv )
+ {
+ /// Load source image and convert it to gray
+ src = imread( argv[1], 1 );
+
+ /// Convert image to gray and blur it
+ cvtColor( src, src_gray, CV_BGR2GRAY );
+ blur( src_gray, src_gray, Size(3,3) );
+
+ /// Create Window
+ char* source_window = "Source";
+ namedWindow( source_window, CV_WINDOW_AUTOSIZE );
+ imshow( source_window, src );
+
+ createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback );
+ thresh_callback( 0, 0 );
+
+ waitKey(0);
+ return(0);
+ }
+
+ /** @function thresh_callback */
+ void thresh_callback(int, void* )
+ {
+ Mat src_copy = src.clone();
+ Mat threshold_output;
+ vector<vector<Point> > contours;
+ vector<Vec4i> hierarchy;
+
+ /// Detect edges using Threshold
+ threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
+
+ /// Find contours
+ findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
+
+ /// Find the convex hull object for each contour
+ vector<vector<Point> >hull( contours.size() );
+ for( int i = 0; i < contours.size(); i++ )
+ { convexHull( Mat(contours[i]), hull[i], false ); }
+
+ /// Draw contours + hull results
+ Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
+ for( int i = 0; i< contours.size(); i++ )
+ {
+ Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
+ drawContours( drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
+ drawContours( drawing, hull, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
+ }
+
+ /// Show in a window
+ namedWindow( "Hull demo", CV_WINDOW_AUTOSIZE );
+ imshow( "Hull demo", drawing );
+ }
+
+
+Explanation
+============
+
+Result
+======
+
+#. Here it is:
+
+ ========== ==========
+ |Hull_0| |Hull_1|
+ ========== ==========
+
+ .. |Hull_0| image:: images/Hull_Original_Image.jpg
+ :height: 300pt
+ :align: middle
+
+ .. |Hull_1| image:: images/Hull_Result.jpg
+ :height: 300pt
+ :align: middle
+
--- /dev/null
+.. _moments:
+
+
+Image Moments
+**************
+
+Goal
+=====
+
+In this tutorial you will learn how to:
+
+.. container:: enumeratevisibleitemswithsquare
+
+ * Use the OpenCV function :moments:`moments <>`
+ * Use the OpenCV function :contour_area:`contourArea <>`
+ * Use the OpenCV function :arc_length:`arcLength <>`
+
+Theory
+======
+
+Code
+====
+
+This tutorial code's is shown lines below. You can also download it from `here <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp>`_
+
+.. code-block:: cpp
+
+ #include "opencv2/highgui/highgui.hpp"
+ #include "opencv2/imgproc/imgproc.hpp"
+ #include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ using namespace cv;
+ using namespace std;
+
+ Mat src; Mat src_gray;
+ int thresh = 100;
+ int max_thresh = 255;
+ RNG rng(12345);
+
+ /// Function header
+ void thresh_callback(int, void* );
+
+ /** @function main */
+ int main( int argc, char** argv )
+ {
+ /// Load source image and convert it to gray
+ src = imread( argv[1], 1 );
+
+ /// Convert image to gray and blur it
+ cvtColor( src, src_gray, CV_BGR2GRAY );
+ blur( src_gray, src_gray, Size(3,3) );
+
+ /// Create Window
+ char* source_window = "Source";
+ namedWindow( source_window, CV_WINDOW_AUTOSIZE );
+ imshow( source_window, src );
+
+ createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
+ thresh_callback( 0, 0 );
+
+ waitKey(0);
+ return(0);
+ }
+
+ /** @function thresh_callback */
+ void thresh_callback(int, void* )
+ {
+ Mat canny_output;
+ vector<vector<Point> > contours;
+ vector<Vec4i> hierarchy;
+
+ /// Detect edges using canny
+ Canny( src_gray, canny_output, thresh, thresh*2, 3 );
+ /// Find contours
+ findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
+
+ /// Get the moments
+ vector<Moments> mu(contours.size() );
+ for( int i = 0; i < contours.size(); i++ )
+ { mu[i] = moments( contours[i], false ); }
+
+ /// Get the mass centers:
+ vector<Point2f> mc( contours.size() );
+ for( int i = 0; i < contours.size(); i++ )
+ { mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }
+
+ /// Draw contours
+ Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
+ for( int i = 0; i< contours.size(); i++ )
+ {
+ Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
+ drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
+ circle( drawing, mc[i], 4, color, -1, 8, 0 );
+ }
+
+ /// Show in a window
+ namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
+ imshow( "Contours", drawing );
+
+ /// Calculate the area with the moments 00 and compare with the result of the OpenCV function
+ printf("\t Info: Area and Contour Length \n");
+ for( int i = 0; i< contours.size(); i++ )
+ {
+ printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], true ) );
+ Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
+ drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
+ circle( drawing, mc[i], 4, color, -1, 8, 0 );
+ }
+ }
+
+Explanation
+============
+
+Result
+======
+
+#. Here it is:
+
+ ========== ========== ==========
+ |MU_0| |MU_1| |MU_2|
+ ========== ========== ==========
+
+ .. |MU_0| image:: images/Moments_Source_Image.jpg
+ :width: 250pt
+ :align: middle
+
+ .. |MU_1| image:: images/Moments_Result1.jpg
+ :width: 250pt
+ :align: middle
+
+ .. |MU_2| image:: images/Moments_Result2.jpg
+ :width: 250pt
+ :align: middle
+
--- /dev/null
+.. _point_polygon_test:
+
+Point Polygon Test
+*******************
+
+Goal
+=====
+
+In this tutorial you will learn how to:
+
+.. container:: enumeratevisibleitemswithsquare
+
+ * Use the OpenCV function :point_polygon_test:`pointPolygonTest <>`
+
+
+Theory
+======
+
+Code
+====
+
+This tutorial code's is shown lines below. You can also download it from `here <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp>`_
+
+.. code-block:: cpp
+
+ #include "opencv2/highgui/highgui.hpp"
+ #include "opencv2/imgproc/imgproc.hpp"
+ #include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ using namespace cv;
+ using namespace std;
+
+ /** @function main */
+ int main( int argc, char** argv )
+ {
+ /// Create an image
+ const int r = 100;
+ Mat src = Mat::zeros( Size( 4*r, 4*r ), CV_8UC1 );
+
+ /// Create a sequence of points to make a contour:
+ vector<Point2f> vert(6);
+
+ vert[0] = Point( 1.5*r, 1.34*r );
+ vert[1] = Point( 1*r, 2*r );
+ vert[2] = Point( 1.5*r, 2.866*r );
+ vert[3] = Point( 2.5*r, 2.866*r );
+ vert[4] = Point( 3*r, 2*r );
+ vert[5] = Point( 2.5*r, 1.34*r );
+
+ /// Draw it in src
+ for( int j = 0; j < 6; j++ )
+ { line( src, vert[j], vert[(j+1)%6], Scalar( 255 ), 3, 8 ); }
+
+ /// Get the contours
+ vector<vector<Point> > contours; vector<Vec4i> hierarchy;
+ Mat src_copy = src.clone();
+
+ findContours( src_copy, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
+
+ /// Calculate the distances to the contour
+ Mat raw_dist( src.size(), CV_32FC1 );
+
+ for( int j = 0; j < src.rows; j++ )
+ { for( int i = 0; i < src.cols; i++ )
+ { raw_dist.at<float>(j,i) = pointPolygonTest( contours[0], Point2f(i,j), true ); }
+ }
+
+ double minVal; double maxVal;
+ minMaxLoc( raw_dist, &minVal, &maxVal, 0, 0, Mat() );
+ minVal = abs(minVal); maxVal = abs(maxVal);
+
+ /// Depicting the distances graphically
+ Mat drawing = Mat::zeros( src.size(), CV_8UC3 );
+
+ for( int j = 0; j < src.rows; j++ )
+ { for( int i = 0; i < src.cols; i++ )
+ {
+ if( raw_dist.at<float>(j,i) < 0 )
+ { drawing.at<Vec3b>(j,i)[0] = 255 - (int) abs(raw_dist.at<float>(j,i))*255/minVal; }
+ else if( raw_dist.at<float>(j,i) > 0 )
+ { drawing.at<Vec3b>(j,i)[2] = 255 - (int) raw_dist.at<float>(j,i)*255/maxVal; }
+ else
+ { drawing.at<Vec3b>(j,i)[0] = 255; drawing.at<Vec3b>(j,i)[1] = 255; drawing.at<Vec3b>(j,i)[2] = 255; }
+ }
+ }
+
+ /// Create Window and show your results
+ char* source_window = "Source";
+ namedWindow( source_window, CV_WINDOW_AUTOSIZE );
+ imshow( source_window, src );
+ namedWindow( "Distance", CV_WINDOW_AUTOSIZE );
+ imshow( "Distance", drawing );
+
+ waitKey(0);
+ return(0);
+ }
+
+Explanation
+============
+
+Result
+======
+
+#. Here it is:
+
+ ========== ==========
+ |PPT_0| |PPT_1|
+ ========== ==========
+
+ .. |PPT_0| image:: images/Point_Polygon_Test_Source_Image.jpg
+ :height: 300pt
+ :align: middle
+
+ .. |PPT_1| image:: images/Point_Polygon_Test_Result.jpg
+ :height: 300pt
+ :align: middle
+
:height: 90pt\r
:width: 90pt\r
\r
++ \r
+\r
+ .. tabularcolumns:: m{100pt} m{300pt}\r
+ .. cssclass:: toctableopencv\r
+ \r
+ ===================== ==============================================\r
+ |FindContours| **Title:** :ref:`find_contours`\r
+\r
+ *Compatibility:* > OpenCV 2.0\r
+ \r
+ *Author:* |Author_AnaH|\r
+\r
+ Where we learn how to find contours of objects in our image\r
+\r
+ ===================== ==============================================\r
+ \r
+ .. |FindContours| image:: images/shapedescriptors/Find_Contours_Tutorial_Cover.jpg\r
+ :height: 90pt\r
+ :width: 90pt\r
+\r
++ \r
+\r
+ .. tabularcolumns:: m{100pt} m{300pt}\r
+ .. cssclass:: toctableopencv\r
+ \r
+ ===================== ==============================================\r
+ |Hull| **Title:** :ref:`hull`\r
+\r
+ *Compatibility:* > OpenCV 2.0\r
+ \r
+ *Author:* |Author_AnaH|\r
+\r
+ Where we learn how to get hull contours and draw them!\r
+\r
+ ===================== ==============================================\r
+ \r
+ .. |Hull| image:: images/shapedescriptors/Hull_Tutorial_Cover.jpg\r
+ :height: 90pt\r
+ :width: 90pt\r
+\r
++ \r
+\r
+ .. tabularcolumns:: m{100pt} m{300pt}\r
+ .. cssclass:: toctableopencv\r
+ \r
+ ===================== ==============================================\r
+ |BRC| **Title:** :ref:`bounding_rects_circles`\r
+\r
+ *Compatibility:* > OpenCV 2.0\r
+ \r
+ *Author:* |Author_AnaH|\r
+\r
+ Where we learn how to obtain bounding boxes and circles for our contours.\r
+\r
+ ===================== ==============================================\r
+ \r
+ .. |BRC| image:: images/shapedescriptors/Bounding_Rects_Circles_Tutorial_Cover.jpg\r
+ :height: 90pt\r
+ :width: 90pt\r
+\r
++ \r
+\r
+ .. tabularcolumns:: m{100pt} m{300pt}\r
+ .. cssclass:: toctableopencv\r
\r
+ \r
+ ===================== ==============================================\r
+ |BRE| **Title:** :ref:`bounding_rotated_ellipses`\r
+\r
+ *Compatibility:* > OpenCV 2.0\r
+ \r
+ *Author:* |Author_AnaH|\r
+\r
+ Where we learn how to obtain rotated bounding boxes and ellipses for our contours.\r
+\r
+ ===================== ==============================================\r
+ \r
+ .. |BRE| image:: images/shapedescriptors/Bounding_Rotated_Ellipses_Tutorial_Cover.jpg\r
+ :height: 90pt\r
+ :width: 90pt\r
+\r
++ \r
+\r
+ .. tabularcolumns:: m{100pt} m{300pt}\r
+ .. cssclass:: toctableopencv\r
+ \r
+ \r
+ ===================== ==============================================\r
+ |MU| **Title:** :ref:`moments`\r
+\r
+ *Compatibility:* > OpenCV 2.0\r
+ \r
+ *Author:* |Author_AnaH|\r
+\r
+ Where we learn to calculate the moments of an image\r
+\r
+ ===================== ==============================================\r
+ \r
+ .. |MU| image:: images/shapedescriptors/Moments_Tutorial_Cover.jpg\r
+ :height: 90pt\r
+ :width: 90pt\r
+\r
+\r
++ \r
+\r
+ .. tabularcolumns:: m{100pt} m{300pt}\r
+ .. cssclass:: toctableopencv\r
+ \r
+ \r
+ ===================== ==============================================\r
+ |PPT| **Title:** :ref:`point_polygon_test`\r
+\r
+ *Compatibility:* > OpenCV 2.0\r
+ \r
+ *Author:* |Author_AnaH|\r
+\r
+ Where we learn how to calculate distances from the image to contours\r
+\r
+ ===================== ==============================================\r
+ \r
+ .. |PPT| image:: images/shapedescriptors/Point_Polygon_Test_Tutorial_Cover.jpg\r
+ :height: 90pt\r
+ :width: 90pt\r
+\r
+\r
+\r
.. toctree::\r
:hidden:\r
\r
../histograms/histogram_comparison/histogram_comparison\r
../histograms/back_projection/back_projection\r
../histograms/template_matching/template_matching\r
-\r
-\r
-\r
+ ../shapedescriptors/find_contours/find_contours\r
+ ../shapedescriptors/hull/hull\r
+ ../shapedescriptors/bounding_rects_circles/bounding_rects_circles\r
+ ../shapedescriptors/bounding_rotated_ellipses/bounding_rotated_ellipses\r
+ ../shapedescriptors/moments/moments\r
+ ../shapedescriptors/point_polygon_test/point_polygon_test\r
\r
\r
\r