Added reST tutorials for Contours (6 in imgproc) and for Corner Detection (4 in features2D) + links in conf.py
18
doc/conf.py
@ -329,7 +329,23 @@ extlinks = {'cvt_color': ('http://opencv.willowgarage.com/documentation/cpp/imgp
|
|||||||
'min_max_loc' : ('http://opencv.willowgarage.com/documentation/cpp/core_operations_on_arrays.html?#minMaxLoc%s', None),
|
'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),
|
'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),
|
'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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 80 KiB |
@ -5,4 +5,91 @@
|
|||||||
|
|
||||||
Learn about how to use the feature points detectors, descriptors and matching framework found inside OpenCV.
|
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
|
||||||
|
@ -0,0 +1,139 @@
|
|||||||
|
.. _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
|
||||||
|
|
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 20 KiB |
@ -0,0 +1,155 @@
|
|||||||
|
.. _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
|
||||||
|
|
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 63 KiB |
@ -0,0 +1,122 @@
|
|||||||
|
.. _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
|
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 80 KiB |
@ -0,0 +1,116 @@
|
|||||||
|
.. _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
|
||||||
|
|
||||||
|
|
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 30 KiB |
@ -0,0 +1,126 @@
|
|||||||
|
.. _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
|
||||||
|
|
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 22 KiB |
@ -0,0 +1,128 @@
|
|||||||
|
.. _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
|
||||||
|
|
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 22 KiB |
@ -0,0 +1,109 @@
|
|||||||
|
.. _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
|
||||||
|
|
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 17 KiB |
118
doc/tutorials/imgproc/shapedescriptors/hull/hull.rst
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
.. _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
|
||||||
|
|
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 24 KiB |
136
doc/tutorials/imgproc/shapedescriptors/moments/moments.rst
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
.. _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
|
||||||
|
|
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 9.8 KiB |
@ -0,0 +1,119 @@
|
|||||||
|
.. _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
|
||||||
|
|
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 14 KiB |
@ -383,7 +383,132 @@ In this section you will learn about the image processing (manipulation) functio
|
|||||||
:height: 90pt
|
:height: 90pt
|
||||||
:width: 90pt
|
:width: 90pt
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
|
.. tabularcolumns:: m{100pt} m{300pt}
|
||||||
|
.. cssclass:: toctableopencv
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|FindContours| **Title:** :ref:`find_contours`
|
||||||
|
|
||||||
|
*Compatibility:* > OpenCV 2.0
|
||||||
|
|
||||||
|
*Author:* |Author_AnaH|
|
||||||
|
|
||||||
|
Where we learn how to find contours of objects in our image
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|
||||||
|
.. |FindContours| image:: images/shapedescriptors/Find_Contours_Tutorial_Cover.jpg
|
||||||
|
:height: 90pt
|
||||||
|
:width: 90pt
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
|
.. tabularcolumns:: m{100pt} m{300pt}
|
||||||
|
.. cssclass:: toctableopencv
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|Hull| **Title:** :ref:`hull`
|
||||||
|
|
||||||
|
*Compatibility:* > OpenCV 2.0
|
||||||
|
|
||||||
|
*Author:* |Author_AnaH|
|
||||||
|
|
||||||
|
Where we learn how to get hull contours and draw them!
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|
||||||
|
.. |Hull| image:: images/shapedescriptors/Hull_Tutorial_Cover.jpg
|
||||||
|
:height: 90pt
|
||||||
|
:width: 90pt
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
|
.. tabularcolumns:: m{100pt} m{300pt}
|
||||||
|
.. cssclass:: toctableopencv
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|BRC| **Title:** :ref:`bounding_rects_circles`
|
||||||
|
|
||||||
|
*Compatibility:* > OpenCV 2.0
|
||||||
|
|
||||||
|
*Author:* |Author_AnaH|
|
||||||
|
|
||||||
|
Where we learn how to obtain bounding boxes and circles for our contours.
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|
||||||
|
.. |BRC| image:: images/shapedescriptors/Bounding_Rects_Circles_Tutorial_Cover.jpg
|
||||||
|
:height: 90pt
|
||||||
|
:width: 90pt
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
|
.. tabularcolumns:: m{100pt} m{300pt}
|
||||||
|
.. cssclass:: toctableopencv
|
||||||
|
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|BRE| **Title:** :ref:`bounding_rotated_ellipses`
|
||||||
|
|
||||||
|
*Compatibility:* > OpenCV 2.0
|
||||||
|
|
||||||
|
*Author:* |Author_AnaH|
|
||||||
|
|
||||||
|
Where we learn how to obtain rotated bounding boxes and ellipses for our contours.
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|
||||||
|
.. |BRE| image:: images/shapedescriptors/Bounding_Rotated_Ellipses_Tutorial_Cover.jpg
|
||||||
|
:height: 90pt
|
||||||
|
:width: 90pt
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
|
.. tabularcolumns:: m{100pt} m{300pt}
|
||||||
|
.. cssclass:: toctableopencv
|
||||||
|
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|MU| **Title:** :ref:`moments`
|
||||||
|
|
||||||
|
*Compatibility:* > OpenCV 2.0
|
||||||
|
|
||||||
|
*Author:* |Author_AnaH|
|
||||||
|
|
||||||
|
Where we learn to calculate the moments of an image
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|
||||||
|
.. |MU| image:: images/shapedescriptors/Moments_Tutorial_Cover.jpg
|
||||||
|
:height: 90pt
|
||||||
|
:width: 90pt
|
||||||
|
|
||||||
|
|
||||||
|
+
|
||||||
|
|
||||||
|
.. tabularcolumns:: m{100pt} m{300pt}
|
||||||
|
.. cssclass:: toctableopencv
|
||||||
|
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|PPT| **Title:** :ref:`point_polygon_test`
|
||||||
|
|
||||||
|
*Compatibility:* > OpenCV 2.0
|
||||||
|
|
||||||
|
*Author:* |Author_AnaH|
|
||||||
|
|
||||||
|
Where we learn how to calculate distances from the image to contours
|
||||||
|
|
||||||
|
===================== ==============================================
|
||||||
|
|
||||||
|
.. |PPT| image:: images/shapedescriptors/Point_Polygon_Test_Tutorial_Cover.jpg
|
||||||
|
:height: 90pt
|
||||||
|
:width: 90pt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:hidden:
|
:hidden:
|
||||||
|
|
||||||
@ -406,9 +531,12 @@ In this section you will learn about the image processing (manipulation) functio
|
|||||||
../histograms/histogram_comparison/histogram_comparison
|
../histograms/histogram_comparison/histogram_comparison
|
||||||
../histograms/back_projection/back_projection
|
../histograms/back_projection/back_projection
|
||||||
../histograms/template_matching/template_matching
|
../histograms/template_matching/template_matching
|
||||||
|
../shapedescriptors/find_contours/find_contours
|
||||||
|
../shapedescriptors/hull/hull
|
||||||
|
../shapedescriptors/bounding_rects_circles/bounding_rects_circles
|
||||||
|
../shapedescriptors/bounding_rotated_ellipses/bounding_rotated_ellipses
|
||||||
|
../shapedescriptors/moments/moments
|
||||||
|
../shapedescriptors/point_polygon_test/point_polygon_test
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|