%\texttt{\href{http://www.ros.org/wiki/Stack Manifest}{stack manifest}}& Description of a ROS stack.
%\end{tabular}
\emph{The OpenCV C++ reference manual is here: \url{http://opencv.itseez.com}. Use \textbf{Quick Search} to find descriptions of the particular functions and classes}
\emph{The OpenCV C++ reference manual is here: \url{http://docs.opencv.org}. Use \textbf{Quick Search} to find descriptions of the particular functions and classes}
\section{Key OpenCV Classes}
\begin{tabular}{@{}p{\the\MyLen}%
@{}p{\linewidth-\the\MyLen}@{}}
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#Point_}{Point\_}}& Template 2D point class \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#Point3_}{Point3\_}}& Template 3D point class \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#Size_}{Size\_}}& Template size (width, height) class \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#Vec}{Vec}}& Template short vector class \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#Matx}{Matx}}& Template small matrix class \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#Range}{Range}}& Integer value range \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#Mat}{Mat}}& 2D or multi-dimensional dense array (can be used to store matrices, images, histograms, feature descriptors, voxel volumes etc.)\\
\texttt{\href{http://docs.opencv.org/modules/core/doc/basic_structures.html\#Range}{Range}}& Integer value range \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/basic_structures.html\#Mat}{Mat}}& 2D or multi-dimensional dense array (can be used to store matrices, images, histograms, feature descriptors, voxel volumes etc.)\\
\textbf{Convert matrix to/from other structures}\\
\>\textbf{(without copying the data)}\\
@ -230,32 +230,32 @@
\section{Matrix Manipulations: Copying, Shuffling, Part Access}
\begin{tabular}{@{}p{\the\MyLen}%
@{}p{\linewidth-\the\MyLen}@{}}
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#mat-copyto}{src.copyTo(dst)}}& Copy matrix to another one \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#mat-convertto}{src.convertTo(dst,type,scale,shift)}}&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Scale and convert to another datatype \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#mat-clone}{m.clone()}}& Make deep copy of a matrix \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#mat-reshape}{m.reshape(nch,nrows)}}& Change matrix dimensions and/or number of channels without copying data \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/basic_structures.html\#mat-copyto}{src.copyTo(dst)}}& Copy matrix to another one \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/basic_structures.html\#mat-convertto}{src.convertTo(dst,type,scale,shift)}}&\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Scale and convert to another datatype \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/basic_structures.html\#mat-clone}{m.clone()}}& Make deep copy of a matrix \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/basic_structures.html\#mat-reshape}{m.reshape(nch,nrows)}}& Change matrix dimensions and/or number of channels without copying data \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/basic_structures.html\#mat-colrange}{m.colRange(Range(j1,j2))}}&\ \ \ \ \ \ \ Take a matrix row/column span \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#mat-diag}{m.diag(i)}}& Take a matrix diagonal \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/basic_structures.html\#mat-diag}{m.diag(i)}}& Take a matrix diagonal \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#Mat}{m(Range(i1,i2),Range(j1,j2)), m(roi)}}&\ \ \ \ \ \ \ \ \ \ \ \ \ Take a submatrix \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/basic_structures.html\#Mat}{m(Range(i1,i2),Range(j1,j2)), m(roi)}}&\ \ \ \ \ \ \ \ \ \ \ \ \ Take a submatrix \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html\#repeat}{m.repeat(ny,nx)}}& Make a bigger matrix from a smaller one \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/operations_on_arrays.html\#repeat}{m.repeat(ny,nx)}}& Make a bigger matrix from a smaller one \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html\#flip}{flip(src,dst,dir)}}& Reverse the order of matrix rows and/or columns \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/operations_on_arrays.html\#flip}{flip(src,dst,dir)}}& Reverse the order of matrix rows and/or columns \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html\#split}{split(...)}}& Split multi-channel matrix into separate channels \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/operations_on_arrays.html\#split}{split(...)}}& Split multi-channel matrix into separate channels \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html\#merge}{merge(...)}}& Make a multi-channel matrix out of the separate channels \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/operations_on_arrays.html\#merge}{merge(...)}}& Make a multi-channel matrix out of the separate channels \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html\#mixchannels}{mixChannels(...)}}& Generalized form of split() and merge() \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/operations_on_arrays.html\#mixchannels}{mixChannels(...)}}& Generalized form of split() and merge() \\
\texttt{\href{http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html\#randshuffle}{randShuffle(...)}}& Randomly shuffle matrix elements \\
\texttt{\href{http://docs.opencv.org/modules/core/doc/operations_on_arrays.html\#randshuffle}{randShuffle(...)}}& Randomly shuffle matrix elements \\
\end{tabular}
@ -278,17 +278,17 @@ other matrix operations, such as
For some operations a more convenient \href{http://opencv.itseez.com/modules/core/doc/basic_structures.html\#matrix-expressions}{algebraic notation} can be used, for example:
For some operations a more convenient \href{http://docs.opencv.org/modules/core/doc/basic_structures.html\#matrix-expressions}{algebraic notation} can be used, for example:
\texttt{\href{http://opencv.itseez.com/modules/imgproc/doc/geometric_transformations.html\#convertmaps}{convertMaps()}}& Optimize maps for a faster remap() execution\\
\texttt{\href{http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html\#convertmaps}{convertMaps()}}& Optimize maps for a faster remap() execution\\
\end{tabular}
@ -422,21 +422,21 @@ Example. Decimate image by factor of $\sqrt{2}$:\\
\begin{tabular}{@{}p{\the\MyLen}%
@{}p{\linewidth-\the\MyLen}@{}}
\texttt{\href{http://opencv.itseez.com/modules/imgproc/doc/miscellaneous_transformations.html\#cvtcolor}{cvtColor()}}& Convert image from one color space to another \\
\texttt{\href{http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html\#cvtcolor}{cvtColor()}}& Convert image from one color space to another \\
\texttt{\href{http://opencv.itseez.com/modules/imgproc/doc/miscellaneous_transformations.html\#threshold}{threshold()}}, \texttt{\href{http://opencv.itseez.com/modules/imgproc/doc/miscellaneous_transformations.html\#adaptivethreshold}{adaptivethreshold()}}& Convert grayscale image to binary image using a fixed or a variable threshold \\
\texttt{\href{http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html\#threshold}{threshold()}}, \texttt{\href{http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html\#adaptivethreshold}{adaptivethreshold()}}& Convert grayscale image to binary image using a fixed or a variable threshold \\
\texttt{\href{http://opencv.itseez.com/modules/imgproc/doc/miscellaneous_transformations.html\#floodfill}{floodFill()}}& Find a connected component using region growing algorithm\\
\texttt{\href{http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html\#floodfill}{floodFill()}}& Find a connected component using region growing algorithm\\
\texttt{\href{http://opencv.itseez.com/modules/imgproc/doc/miscellaneous_transformations.html\#integral}{integral()}}& Compute integral image \\
\texttt{\href{http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html\#integral}{integral()}}& Compute integral image \\
See the samples \texttt{\href{http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/watershed.cpp}{watershed.cpp}} and \texttt{\href{http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/grabcut.cpp}{grabcut.cpp}}.
See the samples \texttt{\href{http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/watershed.cpp}{watershed.cpp}} and \texttt{\href{http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/grabcut.cpp}{grabcut.cpp}}.
\end{tabular}
@ -445,13 +445,13 @@ Example. Decimate image by factor of $\sqrt{2}$:\\
\texttt{\href{http://opencv.itseez.com/modules/imgproc/doc/histograms.html\#calcbackproject}{calcBackProject()}}& Back-project the histogram \\
\texttt{\href{http://docs.opencv.org/modules/imgproc/doc/histograms.html\#calcbackproject}{calcBackProject()}}& Back-project the histogram \\
\texttt{\href{http://opencv.itseez.com/modules/imgproc/doc/histograms.html\#equalizehist}{equalizeHist()}}& Normalize image brightness and contrast\\
\texttt{\href{http://docs.opencv.org/modules/imgproc/doc/histograms.html\#equalizehist}{equalizeHist()}}& Normalize image brightness and contrast\\
\texttt{\href{http://opencv.itseez.com/modules/imgproc/doc/histograms.html\#comparehist}{compareHist()}}& Compare two histograms\\
\texttt{\href{http://docs.opencv.org/modules/imgproc/doc/histograms.html\#comparehist}{compareHist()}}& Compare two histograms\\
\end{tabular}
@ -464,12 +464,12 @@ Example. Compute Hue-Saturation histogram of an image:\\
\end{tabbing}
\subsection{Contours}
See \texttt{\href{http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/contours2.cpp}{contours2.cpp}} and \texttt{\href{http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/squares.cpp}{squares.cpp}}
See \texttt{\href{http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/contours2.cpp}{contours2.cpp}} and \texttt{\href{http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/squares.cpp}{squares.cpp}}
samples on what are the contours and how to use them.
\section{Data I/O}
\href{http://opencv.itseez.com/modules/core/doc/xml_yaml_persistence.html\#xml-yaml-file-storages-writing-to-a-file-storage}{XML/YAML storages} are collections (possibly nested) of scalar values, structures and heterogeneous lists.
\href{http://docs.opencv.org/modules/core/doc/xml_yaml_persistence.html\#xml-yaml-file-storages-writing-to-a-file-storage}{XML/YAML storages} are collections (possibly nested) of scalar values, structures and heterogeneous lists.
\begin{tabbing}
\textbf{Wr}\=\textbf{iting data to YAML (or XML)}\\
@ -509,7 +509,7 @@ samples on what are the contours and how to use them.
\emph{The functions can read/write images in the following formats: \textbf{BMP (.bmp), JPEG (.jpg, .jpeg), TIFF (.tif, .tiff), PNG (.png), PBM/PGM/PPM (.p?m), Sun Raster (.sr), JPEG 2000 (.jp2)}. Every format supports 8-bit, 1- or 3-channel images. Some formats (PNG, JPEG 2000) support 16 bits per channel.}
@ -544,72 +544,72 @@ samples on what are the contours and how to use them.
\texttt{\href{http://opencv.itseez.com/modules/highgui/doc/user_interface.html\#destroywindow}{destroyWindow(winname)}}&\ \ \ Destroy the specified window \\
\texttt{\href{http://docs.opencv.org/modules/highgui/doc/user_interface.html\#destroywindow}{destroyWindow(winname)}}&\ \ \ Destroy the specified window \\
\texttt{\href{http://opencv.itseez.com/modules/highgui/doc/user_interface.html\#imshow}{imshow(winname, mtx)}}& Show image in the window \\
\texttt{\href{http://docs.opencv.org/modules/highgui/doc/user_interface.html\#imshow}{imshow(winname, mtx)}}& Show image in the window \\
\texttt{\href{http://opencv.itseez.com/modules/highgui/doc/user_interface.html\#waitkey}{waitKey(delay)}}& Wait for a key press during the specified time interval (or forever). Process events while waiting. \emph{Do not forget to call this function several times a second in your code.}\\
\texttt{\href{http://docs.opencv.org/modules/highgui/doc/user_interface.html\#waitkey}{waitKey(delay)}}& Wait for a key press during the specified time interval (or forever). Process events while waiting. \emph{Do not forget to call this function several times a second in your code.}\\
\texttt{\href{http://opencv.itseez.com/modules/highgui/doc/user_interface.html\#createtrackbar}{createTrackbar(...)}}& Add trackbar (slider) to the specified window \\
\texttt{\href{http://docs.opencv.org/modules/highgui/doc/user_interface.html\#createtrackbar}{createTrackbar(...)}}& Add trackbar (slider) to the specified window \\
\texttt{\href{http://opencv.itseez.com/modules/highgui/doc/user_interface.html\#setmousecallback}{setMouseCallback(...)}}&\ \ Set the callback on mouse clicks and movements in the specified window \\
\texttt{\href{http://docs.opencv.org/modules/highgui/doc/user_interface.html\#setmousecallback}{setMouseCallback(...)}}&\ \ Set the callback on mouse clicks and movements in the specified window \\
\end{tabular}
See \texttt{\href{http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/camshiftdemo.cpp}{camshiftdemo.cpp}} and other \href{http://code.opencv.org/svn/opencv/trunk/opencv/samples/}{OpenCV samples} on how to use the GUI functions.
See \texttt{\href{http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/camshiftdemo.cpp}{camshiftdemo.cpp}} and other \href{http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/}{OpenCV samples} on how to use the GUI functions.
\section{Camera Calibration, Pose Estimation and Depth Estimation}
\begin{tabular}{@{}p{\the\MyLen}%
@{}p{\linewidth-\the\MyLen}@{}}
\texttt{\href{http://opencv.itseez.com/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#calibratecamera}{calibrateCamera()}}& Calibrate camera from several views of a calibration pattern. \\
\texttt{\href{http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#calibratecamera}{calibrateCamera()}}& Calibrate camera from several views of a calibration pattern. \\
\texttt{\href{http://opencv.itseez.com/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#findchessboardcorners}{findChessboardCorners()}}&\ \ \ \ \ \ Find feature points on the checkerboard calibration pattern. \\
\texttt{\href{http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#findchessboardcorners}{findChessboardCorners()}}&\ \ \ \ \ \ Find feature points on the checkerboard calibration pattern. \\
\texttt{\href{http://opencv.itseez.com/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#solvepnp}{solvePnP()}}& Find the object pose from the known projections of its feature points. \\
\texttt{\href{http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#solvepnp}{solvePnP()}}& Find the object pose from the known projections of its feature points. \\
\texttt{\href{http://opencv.itseez.com/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#stereorectify}{stereoRectify()}}& Compute the rectification transforms for a calibrated stereo camera.\\
\texttt{\href{http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#stereorectify}{stereoRectify()}}& Compute the rectification transforms for a calibrated stereo camera.\\
\texttt{\href{http://opencv.itseez.com/modules/imgproc/doc/geometric_transformations.html\#initundistortrectifymap}{initUndistortRectifyMap()}}&\ \ \ \ \ \ Compute rectification map (for \texttt{remap()}) for each stereo camera head.\\
\texttt{\href{http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html\#initundistortrectifymap}{initUndistortRectifyMap()}}&\ \ \ \ \ \ Compute rectification map (for \texttt{remap()}) for each stereo camera head.\\
\texttt{\href{http://opencv.itseez.com/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#StereoBM}{StereoBM}}, \texttt{\href{http://opencv.itseez.com/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#StereoSGBM}{StereoSGBM}}& The stereo correspondence engines to be run on rectified stereo pairs.\\
\texttt{\href{http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#StereoBM}{StereoBM}}, \texttt{\href{http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#StereoSGBM}{StereoSGBM}}& The stereo correspondence engines to be run on rectified stereo pairs.\\
\texttt{\href{http://opencv.itseez.com/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#reprojectimageto3d}{reprojectImageTo3D()}}& Convert disparity map to 3D point cloud.\\
\texttt{\href{http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#reprojectimageto3d}{reprojectImageTo3D()}}& Convert disparity map to 3D point cloud.\\
\texttt{\href{http://opencv.itseez.com/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#findhomography}{findHomography()}}& Find best-fit perspective transformation between two 2D point sets. \\
\texttt{\href{http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html\#findhomography}{findHomography()}}& Find best-fit perspective transformation between two 2D point sets. \\
\end{tabular}
To calibrate a camera, you can use \texttt{\href{http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/calibration.cpp}{calibration.cpp}} or
To calibrate a camera, you can use \texttt{\href{http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/calibration.cpp}{calibration.cpp}} or
\texttt{\href{http://opencv.itseez.com/modules/imgproc/doc/object_detection.html\#matchtemplate}{matchTemplate}}& Compute proximity map for given template.\\
\texttt{\href{http://docs.opencv.org/modules/imgproc/doc/object_detection.html\#matchtemplate}{matchTemplate}}& Compute proximity map for given template.\\
\texttt{\href{http://opencv.itseez.com/modules/objdetect/doc/cascade_classification.html\#cascadeclassifier}{CascadeClassifier}}& Viola's Cascade of Boosted classifiers using Haar or LBP features. Suits for detecting faces, facial features and some other objects without diverse textures. See \texttt{\href{http://code.opencv.org/svn/opencv/trunk/opencv/samples/c/facedetect.cpp}{facedetect.cpp}}\\
\texttt{\href{http://docs.opencv.org/modules/objdetect/doc/cascade_classification.html\#cascadeclassifier}{CascadeClassifier}}& Viola's Cascade of Boosted classifiers using Haar or LBP features. Suits for detecting faces, facial features and some other objects without diverse textures. See \texttt{\href{http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/c/facedetect.cpp}{facedetect.cpp}}\\
\texttt{{HOGDescriptor}}& N. Dalal's object detector using Histogram-of-Oriented-Gradients (HOG) features. Suits for detecting people, cars and other objects with well-defined silhouettes. See \texttt{\href{http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/peopledetect.cpp}{peopledetect.cpp}}\\
\texttt{{HOGDescriptor}}& N. Dalal's object detector using Histogram-of-Oriented-Gradients (HOG) features. Suits for detecting people, cars and other objects with well-defined silhouettes. See \texttt{\href{http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/peopledetect.cpp}{peopledetect.cpp}}\\
\end{tabular}
%
%
% feature detection:
% features2d toolbox
%
%
% object detection:
% using a classifier running on a sliding window: cascadeclassifier + hog.
% using salient point features: features2d -> matching
@ -9,7 +9,7 @@ In this tutorial you will learn how to:
..container:: enumeratevisibleitemswithsquare
* Use :point:`Point <>` to define 2D points in an image.
* Use :point:`Point <>` to define 2D points in an image.
* Use :scalar:`Scalar <>` and why it is useful
* Draw a **line** by using the OpenCV function :line:`line <>`
* Draw an **ellipse** by using the OpenCV function :ellipse:`ellipse <>`
@ -30,15 +30,15 @@ Point
It represents a 2D point, specified by its image coordinates :math:`x` and :math:`y`. We can define it as:
..code-block:: cpp
Point pt;
pt.x = 10;
pt.x = 10;
pt.y = 8;
or
..code-block:: cpp
Point pt = Point(10, 8);
Scalar
@ -48,7 +48,7 @@ Scalar
* Let's see an example, if we are asked for a color argument and we give:
..code-block:: cpp
Scalar( a, b, c )
We would be defining a RGB color such as: *Red = c*, *Green = b* and *Blue = a*
@ -56,12 +56,12 @@ Scalar
Code
=====
* This code is in your OpenCV sample folder. Otherwise you can grab it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp>`_
* This code is in your OpenCV sample folder. Otherwise you can grab it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp>`_
Explanation
=============
#. Since we plan to draw two examples (an atom and a rook), we have to create 02 images and two windows to display them.
#. Since we plan to draw two examples (an atom and a rook), we have to create 02 images and two windows to display them.
* In the previous tutorial (:ref:`Drawing_1`) we drew diverse geometric figures, giving as input parameters such as coordinates (in the form of :point:`Points <>`), color, thickness, etc. You might have noticed that we gave specific values for these arguments.
* In this tutorial, we intend to use *random* values for the drawing parameters. Also, we intend to populate our image with a big number of geometric figures. Since we will be initializing them in a random fashion, this process will be automatic and made by using *loops* .
* This code is in your OpenCV sample folder. Otherwise you can grab it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/core/Matrix/Drawing_2.cpp>`_ .
* This code is in your OpenCV sample folder. Otherwise you can grab it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/core/Matrix/Drawing_2.cpp>`_ .
Explanation
============
@ -43,7 +43,7 @@ Explanation
Mat image = Mat::zeros( window_height, window_width, CV_8UC3 );
/// Show it in a window during DELAY ms
imshow( window_name, image );
imshow( window_name, image );
#. Then we proceed to draw crazy stuff. After taking a look at the code, you can see that it is mainly divided in 8 sections, defined as functions:
@ -110,22 +110,22 @@ Explanation
* The *for* loop will repeat **NUMBER** times. Since the function :line:`line <>` is inside this loop, that means that **NUMBER** lines will be generated.
* The line extremes are given by *pt1* and *pt2*. For *pt1* we can see that:
..code-block:: cpp
pt1.x = rng.uniform( x_1, x_2 );
pt1.x = rng.uniform( x_1, x_2 );
pt1.y = rng.uniform( y_1, y_2 );
* We know that **rng** is a *Random number generator* object. In the code above we are calling **rng.uniform(a,b)**. This generates a radombly uniformed distribution between the values **a** and **b** (inclusive in **a**, exclusive in **b**).
* We know that **rng** is a *Random number generator* object. In the code above we are calling **rng.uniform(a,b)**. This generates a radombly uniformed distribution between the values **a** and **b** (inclusive in **a**, exclusive in **b**).
* From the explanation above, we deduce that the extremes *pt1* and *pt2* will be random values, so the lines positions will be quite impredictable, giving a nice visual effect (check out the Result section below).
* As another observation, we notice that in the :line:`line <>` arguments, for the *color* input we enter:
..code-block:: cpp
randomColor(rng)
randomColor(rng)
Let's check the function implementation:
..code-block:: cpp
@ -138,7 +138,7 @@ Explanation
As we can see, the return value is an *Scalar* with 3 randomly initialized values, which are used as the *R*, *G* and *B* parameters for the line color. Hence, the color of the lines will be random too!
#. The explanation above applies for the other functions generating circles, ellipses, polygones, etc. The parameters such as *center* and *vertices* are also generated randomly.
#. The explanation above applies for the other functions generating circles, ellipses, polygones, etc. The parameters such as *center* and *vertices* are also generated randomly.
#. Before finishing, we also should take a look at the functions *Display_Random_Text* and *Displaying_Big_End*, since they both have a few interesting features:
@ -158,7 +158,7 @@ Explanation
putText( image, "Testing text rendering", org, rng.uniform(0,8),
So, **image2** is the substraction of **image** and **Scalar::all(i)**. In fact, what happens here is that every pixel of **image2** will be the result of substracting every pixel of **image** minus the value of **i** (remember that for each pixel we are considering three values such as R, G and B, so each of them will be affected)
Also remember that the substraction operation *always* performs internally a **saturate** operation, which means that the result obtained will always be inside the allowed range (no negative and between 0 and 255 for our example).
Also remember that the substraction operation *always* performs internally a **saturate** operation, which means that the result obtained will always be inside the allowed range (no negative and between 0 and 255 for our example).
Result
========
@ -234,7 +234,7 @@ As you just saw in the Code section, the program will sequentially execute diver
..image:: images/Drawing_2_Tutorial_Result_0.jpg
:alt:Drawing Tutorial 2 - Final Result 0
:align:center
:align:center
#. Then, a new set of figures, these time *rectangles* will follow.
@ -242,13 +242,13 @@ As you just saw in the Code section, the program will sequentially execute diver
..image:: images/Drawing_2_Tutorial_Result_2.jpg
:alt:Drawing Tutorial 2 - Final Result 2
:align:center
:align:center
#. Now, *polylines* with 03 segments will appear on screen, again in random configurations.
..image:: images/Drawing_2_Tutorial_Result_3.jpg
:alt:Drawing Tutorial 2 - Final Result 3
:align:center
:align:center
#. Filled polygons (in this example triangles) will follow.
@ -256,7 +256,7 @@ As you just saw in the Code section, the program will sequentially execute diver
..image:: images/Drawing_2_Tutorial_Result_5.jpg
:alt:Drawing Tutorial 2 - Final Result 5
:align:center
:align:center
#. Near the end, the text *"Testing Text Rendering"* will appear in a variety of fonts, sizes, colors and positions.
@ -264,4 +264,4 @@ As you just saw in the Code section, the program will sequentially execute diver
@ -15,7 +15,7 @@ In this tutorial you will learn how to:
* Use :surf_descriptor_extractor:`SurfDescriptorExtractor<>` and its function :descriptor_extractor:`compute<>` to perform the required calculations.
* Use a :brute_force_matcher:`BruteForceMatcher<>` to match the features vector
* Use the function :draw_matches:`drawMatches<>` to draw the detected matches.
Theory
======
@ -23,9 +23,9 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/features2D/SURF_descriptor.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/features2D/SURF_descriptor.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include <stdio.h>
#include <iostream>
@ -45,7 +45,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
Mat img_1 = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
Mat img_2 = imread( argv[2], CV_LOAD_IMAGE_GRAYSCALE );
if( !img_1.data || !img_2.data )
{ return -1; }
@ -74,7 +74,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
@ -14,7 +14,7 @@ In this tutorial you will learn how to:
* Use the :surf_feature_detector:`SurfFeatureDetector<>` and its function :feature_detector_detect:`detect<>` to perform the detection process
* Use the function :draw_keypoints:`drawKeypoints<>` to draw the detected keypoints
Theory
======
@ -22,14 +22,14 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/features2D/SURF_detector.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/features2D/SURF_detector.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
@ -44,7 +44,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
Mat img_1 = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
Mat img_2 = imread( argv[2], CV_LOAD_IMAGE_GRAYSCALE );
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include <stdio.h>
#include <iostream>
@ -41,7 +41,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
Mat img_1 = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
Mat img_2 = imread( argv[2], CV_LOAD_IMAGE_GRAYSCALE );
@ -12,7 +12,7 @@ In this tutorial you will learn how to:
* Use the function :find_homography:`findHomography<>` to find the transform between matched keypoints.
* Use the function :perspective_transform:`perspectiveTransform<>` to map the points.
Theory
======
@ -20,9 +20,9 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/features2D/SURF_Homography.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/features2D/SURF_Homography.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include <stdio.h>
#include <iostream>
@ -43,7 +43,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
Mat img_object = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
Mat img_scene = imread( argv[2], CV_LOAD_IMAGE_GRAYSCALE );
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/TrackingMotion/cornerSubPix_Demo.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/TrackingMotion/cornerSubPix_Demo.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
@ -55,7 +55,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
@ -11,7 +11,7 @@ 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.
* 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
@ -20,9 +20,9 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/TrackingMotion/cornerDetector_Demo.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/TrackingMotion/cornerDetector_Demo.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
@ -34,9 +34,9 @@ This tutorial code's is shown lines below. You can also download it from `here <
using namespace std;
/// Global variables
Mat src, src_gray;
Mat src, src_gray;
Mat myHarris_dst; Mat myHarris_copy; Mat Mc;
Mat myShiTomasi_dst; Mat myShiTomasi_copy;
Mat myShiTomasi_dst; Mat myShiTomasi_copy;
int myShiTomasi_qualityLevel = 50;
int myHarris_qualityLevel = 50;
@ -70,7 +70,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/TrackingMotion/goodFeaturesToTrack_Demo.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/TrackingMotion/goodFeaturesToTrack_Demo.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
@ -56,7 +56,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
* Use the function :corner_harris:`cornerHarris <>` to detect corners using the Harris-Stephens method.
Theory
@ -56,7 +56,7 @@ How does it work?
..container:: enumeratevisibleitemswithsquare
* Let's look for corners. Since corners represents a variation in the gradient in the image, we will look for this "variation".
* Let's look for corners. Since corners represents a variation in the gradient in the image, we will look for this "variation".
* Consider a grayscale image :math:`I`. We are going to sweep a window :math:`w(x,y)` (with displacements :math:`u` in the x direction and :math:`v` in the right direction) :math:`I` and will calculate the variation of intensity.
@ -66,10 +66,10 @@ How does it work?
where:
* :math:`w(x,y)` is the window at position :math:`(x,y)`
* :math:`w(x,y)` is the window at position :math:`(x,y)`
* :math:`I(x,y)` is the intensity at :math:`(x,y)`
* :math:`I(x+u,y+v)` is the intensity at the moved window :math:`(x+u,y+v)`
* Since we are looking for windows with corners, we are looking for windows with a large variation in intensity. Hence, we have to maximize the equation above, specifically the term:
* A score is calculated for each window, to determine if it can possibly contain a corner:
..math::
R = det(M) - k(trace(M))^{2}
R = det(M) - k(trace(M))^{2}
where:
* det(M) = :math:`\lambda_{1}\lambda_{2}`
* trace(M) = :math:`\lambda_{1}+\lambda_{2}`
a window with a score :math:`R` greater than a certain value is considered a "corner"
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/TrackingMotion/cornerHarris_Demo.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/TrackingMotion/cornerHarris_Demo.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
@ -161,7 +161,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace cv;
using namespace std;
/// Global variables
@ -186,7 +186,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
* In short: A set of operations that process images based on shapes. Morphological operations apply a *structuring element* to an input image and generate an output image.
* In short: A set of operations that process images based on shapes. Morphological operations apply a *structuring element* to an input image and generate an output image.
* The most basic morphological operations are two: Erosion and Dilation. They have a wide array of uses, i.e. :
The background (bright) dilates around the black regions of the letter.
@ -58,21 +58,21 @@ Erosion
* This operation is the sister of dilation. What this does is to compute a local minimum over the area of the kernel.
* As the kernel :math:`B` is scanned over the image, we compute the minimal pixel value overlapped by :math:`B` and replace the image pixel under the anchor point with that minimal value.
* As the kernel :math:`B` is scanned over the image, we compute the minimal pixel value overlapped by :math:`B` and replace the image pixel under the anchor point with that minimal value.
* Analagously to the example for dilation, we can apply the erosion operator to the original image (shown above). You can see in the result below that the bright areas of the image (the background, apparently), get thinner, whereas the dark zones (the "writing"( gets bigger.
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
@ -104,29 +104,29 @@ This tutorial code's is shown lines below. You can also download it from `here <
Mat element = getStructuringElement( dilation_type,
Mat element = getStructuringElement( dilation_type,
Size( 2*dilation_size + 1, 2*dilation_size+1 ),
Point( dilation_size, dilation_size ) );
Point( dilation_size, dilation_size ) );
/// Apply the dilation operation
dilate( src, dilation_dst, element );
imshow( "Dilation Demo", dilation_dst );
imshow( "Dilation Demo", dilation_dst );
}
@ -182,12 +182,12 @@ Explanation
* Create a set of 02 Trackbars for each operation:
* The first trackbar "Element" returns either **erosion_elem** or **dilation_elem**
* The second trackbar "Kernel size" return **erosion_size** or **dilation_size** for the corresponding operation.
* The second trackbar "Kernel size" return **erosion_size** or **dilation_size** for the corresponding operation.
* Every time we move any slider, the user's function **Erosion** or **Dilation** will be called and it will update the output image based on the current trackbar values.
Mat element = getStructuringElement( erosion_type,
Mat element = getStructuringElement( erosion_type,
Size( 2*erosion_size + 1, 2*erosion_size+1 ),
Point( erosion_size, erosion_size ) );
Point( erosion_size, erosion_size ) );
/// Apply the erosion operation
erode( src, erosion_dst, element );
imshow( "Erosion Demo", erosion_dst );
imshow( "Erosion Demo", erosion_dst );
}
* The function that performs the *erosion* operation is :erode:`erode <>`. As we can see, it receives three arguments:
* *src*: The source image
* *erosion_dst*: The output image
* *element*: This is the kernel we will use to perform the operation. If we do not specify, the default is a simple :math:`3x3` matrix. Otherwise, we can specify its shape. For this, we need to use the function :get_structuring_element:`getStructuringElement <>`:
..code-block:: cpp
Mat element = getStructuringElement( erosion_type,
Mat element = getStructuringElement( erosion_type,
Size( 2*erosion_size + 1, 2*erosion_size+1 ),
Point( erosion_size, erosion_size ) );
Point( erosion_size, erosion_size ) );
We can choose any of three shapes for our kernel:
..container:: enumeratevisibleitemswithsquare
+ Rectangular box: MORPH_RECT
+ Cross: MORPH_CROSS
+ Cross: MORPH_CROSS
+ Ellipse: MORPH_ELLIPSE
Then, we just have to specify the size of our kernel and the *anchor point*. If not specified, it is assumed to be in the center.
@ -233,8 +233,8 @@ Explanation
* That is all. We are ready to perform the erosion of our image.
..note::
Additionally, there is another parameter that allows you to perform multiple erosions (iterations) at once. We are not using it in this simple tutorial, though. You can check out the Reference for more details.
Additionally, there is another parameter that allows you to perform multiple erosions (iterations) at once. We are not using it in this simple tutorial, though. You can check out the Reference for more details.
#. **dilation:**
@ -250,12 +250,12 @@ The code is below. As you can see, it is completely similar to the snippet of co
We get the results below. Varying the indices in the Trackbars give different output images, naturally. Try them out! You can even try to add a third Trackbar to control the number of iterations.
The explanation below belongs to the book `Computer Vision: Algorithms and Applications <http://szeliski.org/Book/>`_ by Richard Szeliski and to *LearningOpenCV*
The explanation below belongs to the book `Computer Vision: Algorithms and Applications <http://szeliski.org/Book/>`_ by Richard Szeliski and to *LearningOpenCV*
..container:: enumeratevisibleitemswithsquare
* *Smoothing*, also called *blurring*, is a simple and frequently used image processing operation.
* *Smoothing*, also called *blurring*, is a simple and frequently used image processing operation.
* There are many reasons for smoothing. In this tutorial we will focus on smoothing in order to reduce noise (other uses will be seen in the following tutorials).
@ -33,7 +33,7 @@ Theory
g(i,j) = \sum_{k,l} f(i+k, j+l) h(k,l)
:math:`h(k,l)` is called the *kernel*, which is nothing more than the coefficients of the filter.
It helps to visualize a *filter* as a window of coefficients sliding across the image.
@ -44,19 +44,19 @@ Normalized Box Filter
..container:: enumeratevisibleitemswithsquare
* This filter is the simplest of all! Each output pixel is the *mean* of its kernel neighbors ( all of them contribute with equal weights)
* This filter is the simplest of all! Each output pixel is the *mean* of its kernel neighbors ( all of them contribute with equal weights)
* The kernel is below:
..math::
K = \dfrac{1}{K_{width} \cdot K_{height}} \begin{bmatrix}
1 & 1 & 1 & ... & 1 \\
1 & 1 & 1 & ... & 1 \\
. & . & . & ... & 1 \\
. & . & . & ... & 1 \\
1 & 1 & 1 & ... & 1
\end{bmatrix}
\end{bmatrix}
Gaussian Filter
@ -69,16 +69,16 @@ Gaussian Filter
* Just to make the picture clearer, remember how a 1D Gaussian kernel look like?
Assuming that an image is 1D, you can notice that the pixel located in the middle would have the biggest weight. The weight of its neighbors decreases as the spatial distance between them and the center pixel increases.
Assuming that an image is 1D, you can notice that the pixel located in the middle would have the biggest weight. The weight of its neighbors decreases as the spatial distance between them and the center pixel increases.
..note::
Remember that a 2D Gaussian can be represented as :
where :math:`\mu` is the mean (the peak) and :math:`\sigma` represents the variance (per each of the variables :math:`x` and :math:`y`)
@ -97,9 +97,9 @@ Bilateral Filter
* So far, we have explained some filters which main goal is to *smooth* an input image. However, sometimes the filters do not only dissolve the noise, but also smooth away the *edges*. To avoid this (at certain extent at least), we can use a bilateral filter.
* In an analogous way as the Gaussian filter, the bilateral filter also considers the neighboring pixels with weights assigned to each of them. These weights have two components, the first of which is the same weighting used by the Gaussian filter. The second component takes into account the difference in intensity between the neighboring pixels and the evaluated one.
* In an analogous way as the Gaussian filter, the bilateral filter also considers the neighboring pixels with weights assigned to each of them. These weights have two components, the first of which is the same weighting used by the Gaussian filter. The second component takes into account the difference in intensity between the neighboring pixels and the evaluated one.
* For a more detailed explanation you can check `this link <http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html>`_
* For a more detailed explanation you can check `this link <http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html>`_
Code
@ -108,14 +108,14 @@ Code
..container:: enumeratevisibleitemswithsquare
* **What does this program do?**
..container:: enumeratevisibleitemswithsquare
* Loads an image
* Applies 4 different kinds of filters (explained in Theory) and show the filtered images sequentially
#. Let's check the OpenCV functions that involve only the smoothing procedure, since the rest is already known by now.
#. Let's check the OpenCV functions that involve only the smoothing procedure, since the rest is already known by now.
#. **Normalized Block Filter:**
@ -237,10 +237,10 @@ Explanation
+ *dst*: Destination image
+ *Size( w,h )*: Defines the size of the kernel to be used ( of width *w* pixels and height *h* pixels)
+ *Size( w,h )*: Defines the size of the kernel to be used ( of width *w* pixels and height *h* pixels)
+ *Point(-1, -1)*: Indicates where the anchor point (the pixel evaluated) is located with respect to the neighborhood. If there is a negative value, then the center of the kernel is considered the anchor point.
+ *Point(-1, -1)*: Indicates where the anchor point (the pixel evaluated) is located with respect to the neighborhood. If there is a negative value, then the center of the kernel is considered the anchor point.
#. **Gaussian Filter:**
It is performed by the function :gaussian_blur:`GaussianBlur <>` :
@ -262,9 +262,9 @@ Explanation
+ *Size(w, h)*: The size of the kernel to be used (the neighbors to be considered). :math:`w` and :math:`h` have to be odd and positive numbers otherwise thi size will be calculated using the :math:`\sigma_{x}` and :math:`\sigma_{y}` arguments.
+ :math:`\sigma_{x}`: The standard deviation in x. Writing :math:`0` implies that :math:`\sigma_{x}` is calculated using kernel size.
+ :math:`\sigma_{y}`: The standard deviation in y. Writing :math:`0` implies that :math:`\sigma_{y}` is calculated using kernel size.
#. **Median Filter:**
@ -283,12 +283,12 @@ Explanation
+ *src*: Source image
+ *dst*: Destination image, must be the same type as *src*
+ *i*: Size of the kernel (only one because we use a square window). Must be odd.
+ *i*: Size of the kernel (only one because we use a square window). Must be odd.
#. **Bilateral Filter**
Provided by OpenCV function :bilateral_filter:`bilateralFilter <>`
..code-block:: cpp
@ -296,7 +296,7 @@ Explanation
for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
* How to use the OpenCV function :calc_back_project:`calcBackProject <>` to calculate Back Projection
* How to mix different channels of an image by using the OpenCV function :mix_channels:`mixChannels <>`
@ -27,8 +27,8 @@ What is Back Projection?
..container:: enumeratevisibleitemswithsquare
* Back Projection is a way of recording how well the pixels of a given image fit the distribution of pixels in a histogram model.
* To make it simpler: For Back Projection, you calculate the histogram model of a feature and then use it to find this feature in an image.
* To make it simpler: For Back Projection, you calculate the histogram model of a feature and then use it to find this feature in an image.
* Application example: If you have a histogram of flesh color (say, a Hue-Saturation histogram ), then you can use it to find flesh color areas in an image:
@ -42,9 +42,9 @@ How does it work?
* Let's say you have gotten a skin histogram (Hue-Saturation) based on the image below. The histogram besides is going to be our *model histogram* (which we know represents a sample of skin tonality). You applied some mask to capture only the histogram of the skin area:
====== ======
|T0| |T1|
====== ======
====== ======
|T0| |T1|
====== ======
..|T0|image:: images/Back_Projection_Theory0.jpg
:align:middle
@ -55,9 +55,9 @@ How does it work?
* Now, let's imagine that you get another hand image (Test Image) like the one below: (with its respective histogram):
====== ======
|T2| |T3|
====== ======
====== ======
|T2| |T3|
====== ======
..|T2|image:: images/Back_Projection_Theory2.jpg
:align:middle
@ -70,7 +70,7 @@ How does it work?
a. In each pixel of our Test Image (i.e. :math:`p(i,j)` ), collect the data and find the correspondent bin location for that pixel (i.e. :math:`( h_{i,j}, s_{i,j} )` ).
b. Lookup the *model histogram* in the correspondent bin - :math:`( h_{i,j}, s_{i,j} )` - and read the bin value.
b. Lookup the *model histogram* in the correspondent bin - :math:`( h_{i,j}, s_{i,j} )` - and read the bin value.
c. Store this bin value in a new image (*BackProjection*). Also, you may consider to normalize the *model histogram* first, so the output for the Test Image can be visible for you.
@ -88,7 +88,7 @@ Code
..container:: enumeratevisibleitemswithsquare
* **What does this program do?**
..container:: enumeratevisibleitemswithsquare
* Loads an image
@ -99,9 +99,9 @@ Code
* **Downloadable code**:
a. Click `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp>`_ for the basic version (explained in this tutorial).
b. For stuff slightly fancier (using H-S histograms and floodFill to define a mask for the skin area) you can check the `improved demo <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo2.cpp>`_
c. ...or you can always check out the classical `camshiftdemo <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/camshiftdemo.cpp>`_ in samples.
a. Click `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp>`_ for the basic version (explained in this tutorial).
b. For stuff slightly fancier (using H-S histograms and floodFill to define a mask for the skin area) you can check the `improved demo <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo2.cpp>`_
c. ...or you can always check out the classical `camshiftdemo <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/camshiftdemo.cpp>`_ in samples.
#. Read the input image and transform it to HSV format:
@ -206,7 +206,7 @@ Explanation
hue.create( hsv.size(), hsv.depth() );
int ch[] = { 0, 0 };
mixChannels( &hsv, 1, &hue, 1, ch, 1 );
mixChannels( &hsv, 1, &hue, 1, ch, 1 );
as you see, we use the function :mix_channels:`mixChannels` to get only the channel 0 (Hue) from the hsv image. It gets the following parameters:
@ -214,15 +214,15 @@ Explanation
+ **&hsv:** The source array from which the channels will be copied
+ **1:** The number of source arrays
+ **&hue:** The destination array of the copied channels
+ **&hue:** The destination array of the copied channels
+ **1:** The number of destination arrays
+ **ch[] = {0,0}:** The array of index pairs indicating how the channels are copied. In this case, the Hue(0) channel of &hsv is being copied to the 0 channel of &hue (1-channel)
+ **1:** Number of index pairs
+ **1:** Number of index pairs
#. Create a Trackbar for the user to enter the bin values. Any change on the Trackbar means a call to the **Hist_and_Backproj** callback function.
all the arguments are known (the same as used to calculate the histogram), only we add the backproj matrix, which will store the backprojection of the source image (&hue)
#. Here are the output by using a sample image ( guess what? Another hand ). You can play with the bin values and you will observe how it affects the results:
* What happens if we want to *count* this data in an organized way? Since we know that the *range* of information value for this case is 256 values, we can segment our range in subparts (called **bins**) like:
and we can keep count of the number of pixels that fall in the range of each :math:`bin_{i}`. Applying this to the example above we get the image below ( axis x represents the bins and axis y the number of pixels in each of them).
* This was just a simple example of how an histogram works and why it is useful. An histogram can keep count not only of color intensities, but of whatever image features that we want to measure (i.e. gradients, directions, etc).
* This was just a simple example of how an histogram works and why it is useful. An histogram can keep count not only of color intensities, but of whatever image features that we want to measure (i.e. gradients, directions, etc).
* Let's identify some parts of the histogram:
a. **dims**: The number of parameters you want to collect data of. In our example, **dims = 1** because we are only counting the intensity values of each pixel (in a greyscale image).
b. **bins**: It is the number of **subdivisions** in each dim. In our example, **bins = 16**
c. **range**: The limits for the values to be measured. In this case: **range = [0,255]**
c. **range**: The limits for the values to be measured. In this case: **range = [0,255]**
* What if you want to count two features? In this case your resulting histogram would be a 3D plot (in which x and y would be :math:`bin_{x}` and :math:`bin_{y}` for each feature and z would be the number of counts for each combination of :math:`(bin_{x}, bin_{y})`. The same would apply for more features (of course it gets trickier).
@ -65,7 +65,7 @@ What OpenCV offers you
-----------------------
For simple purposes, OpenCV implements the function :calc_hist:`calcHist <>`, which calculates the histogram of a set of arrays (usually images or image planes). It can operate with up to 32 dimensions. We will see it in the code below!
* Loads a *base image* and 2 *test images* to be compared with it.
@ -79,8 +79,8 @@ Code
* Compare the histogram of the *base image* with respect to the 2 test histograms, the histogram of the lower half base image and with the same base image histogram.
* Display the numerical matching parameters obtained.
@ -42,30 +42,30 @@ What is Histogram Equalization?
* To make it clearer, from the image above, you can see that the pixels seem clustered around the middle of the available range of intensities. What Histogram Equalization does is to *stretch out* this range. Take a look at the figure below: The green circles indicate the *underpopulated* intensities. After applying the equalization, we get an histogram like the figure in the center. The resulting image is shown in the picture at right.
* Equalization implies *mapping* one distribution (the given histogram) to another distribution (a wider and more uniform distribution of intensity values) so the intensity values are spreaded over the whole range.
* Equalization implies *mapping* one distribution (the given histogram) to another distribution (a wider and more uniform distribution of intensity values) so the intensity values are spreaded over the whole range.
* To accomplish the equalization effect, the remapping should be the *cumulative distribution function (cdf)* (more details, refer to *Learning OpenCV*). For the histogram :math:`H(i)`, its *cumulative distribution* :math:`H^{'}(i)` is:
..math::
H^{'}(i) = \sum_{0 \le j < i} H(j)
H^{'}(i) = \sum_{0 \le j < i} H(j)
To use this as a remapping function, we have to normalize :math:`H^{'}(i)` such that the maximum value is 255 ( or the maximum value for the intensity of the image ). From the example above, the cumulative function is:
* By **sliding**, we mean moving the patch one pixel at a time (left to right, up to down). At each location, a metric is calculated so it represents how "good" or "bad" the match at that location is (or how similar the patch is to that particular area of the source image).
* For each location of **T** over **I**, you *store* the metric in the *result matrix* **(R)**. Each location :math:`(x,y)` in **R** contains the match metric:
the image above is the result **R** of sliding the patch with a metric **TM_CCORR_NORMED**. The brightest locations indicate the highest matches. As you can see, the location marked by the red circle is probably the one with the highest value, so that location (the rectangle formed by that point as a corner and width and height equal to the patch image) is considered the match.
the image above is the result **R** of sliding the patch with a metric **TM_CCORR_NORMED**. The brightest locations indicate the highest matches. As you can see, the location marked by the red circle is probably the one with the highest value, so that location (the rectangle formed by that point as a corner and width and height equal to the patch image) is considered the match.
* In practice, we use the function :min_max_loc:`minMaxLoc <>` to locate the highest value (or lower, depending of the type of matching method) in the *R* matrix.
Which are the matching methods available in OpenCV?
#. Create the Trackbar to enter the kind of matching method to be used. When a change is detected the callback function **MatchingMethod** is called.
..code-block:: cpp
@ -255,7 +255,7 @@ Explanation
waitKey(0);
return 0;
#. Let's check out the callback function. First, it makes a copy of the source image:
..code-block:: cpp
@ -267,12 +267,12 @@ Explanation
#. Next, it creates the result matrix that will store the matching results for each template location. Observe in detail the size of the result matrix (which matches all possible locations for it)
+ **&minVal** and **&maxVal:** Variables to save the minimum and maximum values in **result**
@ -309,18 +309,18 @@ Explanation
#. For the first two methods ( CV\_SQDIFF and CV\_SQDIFF\_NORMED ) the best match are the lowest values. For all the others, higher values represent better matches. So, we save the corresponding value in the **matchLoc** variable:
#. Generate the following result matrices (first row are the standard methods SQDIFF, CCORR and CCOEFF, second row are the same methods in its normalized version). In the first column, the darkest is the better match, for the other two columns, the brighter a location, the higher the match.
* **Low error rate:** Meaning a good detection of only existent edges.
* **Good localization:** The distance between edge pixels detected and real edge pixels have to be minimized.
* **Minimal response:** Only one detector response per edge.
* **Minimal response:** Only one detector response per edge.
Steps
------
@ -27,39 +27,39 @@ Steps
#. Filter out any noise. The Gaussian filter is used for this purpose. An example of a Gaussian kernel of :math:`size = 5` that might be used is shown below:
..math::
K = \dfrac{1}{159}\begin{bmatrix}
2 & 4 & 5 & 4 & 2 \\
4 & 9 & 12 & 9 & 4 \\
5 & 12 & 15 & 12 & 5 \\
4 & 9 & 12 & 9 & 4 \\
2 & 4 & 5 & 4 & 2
\end{bmatrix}
2 & 4 & 5 & 4 & 2
\end{bmatrix}
#. Find the intensity gradient of the image. For this, we follow a procedure analogous to Sobel:
#. Find the intensity gradient of the image. For this, we follow a procedure analogous to Sobel:
a. Apply a pair of convolution masks (in :math:`x` and :math:`y` directions:
..math::
G_{x} = \begin{bmatrix}
-1 & 0 & +1 \\
-2 & 0 & +2 \\
-1 & 0 & +1
-1 & 0 & +1
\end{bmatrix}
G_{y} = \begin{bmatrix}
-1 & -2 & -1 \\
0 & 0 & 0 \\
+1 & +2 & +1
\end{bmatrix}
+1 & +2 & +1
\end{bmatrix}
b. Find the gradient strength and direction with:
..math::
\begin{array}{l}
G = \sqrt{ G_{x}^{2} + G_{y}^{2} } \\
G = \sqrt{ G_{x}^{2} + G_{y}^{2} } \\
\theta = \arctan(\dfrac{ G_{y} }{ G_{x} })
\end{array}
@ -71,22 +71,22 @@ Steps
a. If a pixel gradient is higher than the *upper* threshold, the pixel is accepted as an edge
b. If a pixel gradient value is below the *lower* threshold, then it is rejected.
c. If the pixel gradient is between the two thresholds, then it will be accepted only if it is connected to a pixel that is above the *upper* threshold.
c. If the pixel gradient is between the two thresholds, then it will be accepted only if it is connected to a pixel that is above the *upper* threshold.
Canny recommended a *upper*:*lower* ratio between 2:1 and 3:1.
#. For more details, you can always consult your favorite Computer Vision book.
#. For more details, you can always consult your favorite Computer Vision book.
Code
=====
#. **What does this program do?**
* Asks the user to enter a numerical value to set the lower threshold for our *Canny Edge Detector* (by means of a Trackbar)
* Applies the *Canny Detector* and generates a **mask** (bright lines representing the edges on a black background).
* Applies the mask obtained on the original image and display it in a window.
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgTrans/CannyDetector_Demo.cpp>`_
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ImgTrans/CannyDetector_Demo.cpp>`_
..code-block:: cpp
@ -123,7 +123,7 @@ Code
/// Using Canny's output as a mask, we display our result
dst = Scalar::all(0);
src.copyTo( dst, detected_edges);
imshow( window_name, dst );
}
@ -194,7 +194,7 @@ Explanation
{ return -1; }
#. Create a matrix of the same type and size of *src* (to be *dst*)
..code-block:: cpp
dst.create( src.size(), src.type() );
@ -249,9 +249,9 @@ Explanation
..code-block:: cpp
dst = Scalar::all(0);
#. Finally, we will use the function :copy_to:`copyTo <>` to map only the areas of the image that are identified as edges (on a black background).
#. Finally, we will use the function :copy_to:`copyTo <>` to map only the areas of the image that are identified as edges (on a black background).
..code-block:: cpp
src.copyTo( dst, detected_edges);
@ -280,8 +280,8 @@ Result
:alt:Result after running Canny
:width:200pt
:align:center
* Notice how the image is superposed to the black background on the edge regions.
@ -10,8 +10,8 @@ In this tutorial you will learn how to:
..container:: enumeratevisibleitemswithsquare
* Use the OpenCV function :copy_make_border:`copyMakeBorder <>` to set the borders (extra padding to your image).
* Use the OpenCV function :copy_make_border:`copyMakeBorder <>` to set the borders (extra padding to your image).
Theory
========
@ -19,14 +19,14 @@ Theory
The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler.
#. In our previous tutorial we learned to use convolution to operate on images. One problem that naturally arises is how to handle the boundaries. How can we convolve them if the evaluated points are at the edge of the image?
#. In our previous tutorial we learned to use convolution to operate on images. One problem that naturally arises is how to handle the boundaries. How can we convolve them if the evaluated points are at the edge of the image?
#. What most of OpenCV functions do is to copy a given image onto another slightly larger image and then automatically pads the boundary (by any of the methods explained in the sample code just below). This way, the convolution can be performed over the needed pixels without problems (the extra padding is cut after the operation is done).
#. In this tutorial, we will briefly explore two ways of defining the extra padding (border) for an image:
a. **BORDER_CONSTANT**: Pad the image with a constant value (i.e. black or :math:`0`
b. **BORDER_REPLICATE**: The row or column at the very edge of the original is replicated to the extra border.
This will be seen more clearly in the Code section.
@ -37,20 +37,20 @@ Code
======
#. **What does this program do?**
* Load an image
* Load an image
* Let the user choose what kind of padding use in the input image. There are two options:
#. *Constant value border*: Applies a padding of a constant value for the whole border. This value will be updated randomly each 0.5 seconds.
#. *Constant value border*: Applies a padding of a constant value for the whole border. This value will be updated randomly each 0.5 seconds.
#. *Replicated border*: The border will be replicated from the pixel values at the edges of the original image.
The user chooses either option by pressing 'c' (constant) or 'r' (replicate)
* The program finishes when the user presses 'ESC'
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp>`_
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
@ -59,7 +59,7 @@ Code
using namespace cv;
/// Global Variables
/// Global Variables
Mat src, dst;
int top, bottom, left, right;
int borderType;
@ -75,10 +75,10 @@ Code
/// Load an image
src = imread( argv[1] );
if( !src.data )
{ return -1;
printf(" No data entered, please enter the path to an image file \n");
printf(" No data entered, please enter the path to an image file \n");
}
/// Brief how-to for this program
@ -92,12 +92,12 @@ Code
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
/// Initialize arguments for the filter
top = (int) (0.05*src.rows); bottom = (int) (0.05*src.rows);
top = (int) (0.05*src.rows); bottom = (int) (0.05*src.rows);
left = (int) (0.05*src.cols); right = (int) (0.05*src.cols);
dst = src;
imshow( window_name, dst );
while( true )
{
c = waitKey(500);
@ -140,14 +140,14 @@ Explanation
..code-block:: cpp
src = imread( argv[1] );
if( !src.data )
{ return -1;
printf(" No data entered, please enter the path to an image file \n");
printf(" No data entered, please enter the path to an image file \n");
}
#. After giving a short intro of how to use the program, we create a window:
..code-block:: cpp
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
@ -156,13 +156,13 @@ Explanation
..code-block:: cpp
top = (int) (0.05*src.rows); bottom = (int) (0.05*src.rows);
top = (int) (0.05*src.rows); bottom = (int) (0.05*src.rows);
left = (int) (0.05*src.cols); right = (int) (0.05*src.cols);
#. The program begins a *while* loop. If the user presses 'c' or 'r', the *borderType* variable takes the value of *BORDER_CONSTANT* or *BORDER_REPLICATE* respectively:
..code-block:: cpp
while( true )
{
c = waitKey(500);
@ -185,7 +185,7 @@ Explanation
#. Finally, we call the function :copy_make_border:`copyMakeBorder <>` to apply the respective padding:
..code-block:: cpp
copyMakeBorder( src, dst, top, bottom, left, right, borderType, value );
The arguments are:
@ -199,7 +199,7 @@ Explanation
#. We display our output image in the image created previously
..code-block:: cpp
imshow( window_name, dst );
@ -213,12 +213,12 @@ Results
..container:: enumeratevisibleitemswithsquare
* By default, it begins with the border set to BORDER_CONSTANT. Hence, a succession of random colored borders will be shown.
* If you press 'r', the border will become a replica of the edge pixels.
* If you press 'r', the border will become a replica of the edge pixels.
* If you press 'c', the random colored borders will appear again
* If you press 'ESC' the program will exit.
Below some screenshot showing how the border changes color and how the *BORDER_REPLICATE* option looks:
@ -10,8 +10,8 @@ In this tutorial you will learn how to:
..container:: enumeratevisibleitemswithsquare
* Use the OpenCV function :filter2d:`filter2D <>` to create your own linear filters.
* Use the OpenCV function :filter2d:`filter2D <>` to create your own linear filters.
Theory
=======
@ -21,15 +21,15 @@ Theory
Convolution
------------
In a very general sense, convolution is an operation between every part of an image and an operator (kernel).
In a very general sense, convolution is an operation between every part of an image and an operator (kernel).
What is a kernel?
------------------
A kernel is essentially a fixed size array of numerical coefficeints along with an *anchor point* in that array, which is tipically located at the center.
A kernel is essentially a fixed size array of numerical coefficeints along with an *anchor point* in that array, which is tipically located at the center.
Fortunately, OpenCV provides you with the function :filter2d:`filter2D <>` so you do not have to code all these operations.
Fortunately, OpenCV provides you with the function :filter2d:`filter2D <>` so you do not have to code all these operations.
Code
======
#. **What does this program do?**
* Loads an image
* Performs a *normalized box filter*. For instance, for a kernel of size :math:`size = 3`, the kernel would be:
..math::
K = \dfrac{1}{3 \cdot 3} \begin{bmatrix}
1 & 1 & 1 \\
1 & 1 & 1 \\
1 & 1 & 1
\end{bmatrix}
1 & 1 & 1
\end{bmatrix}
The program will perform the filter operation with kernels of sizes 3, 5, 7, 9 and 11.
* The filter output (with each kernel) will be shown during 500 milliseconds
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgTrans/filter2D_demo.cpp>`_
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ImgTrans/filter2D_demo.cpp>`_
The first line is to update the *kernel_size* to odd values in the range: :math:`[3,11]`. The second line actually builds the kernel by setting its value to a matrix filled with :math:`1's` and normalizing it by dividing it between the number of elements.
The first line is to update the *kernel_size* to odd values in the range: :math:`[3,11]`. The second line actually builds the kernel by setting its value to a matrix filled with :math:`1's` and normalizing it by dividing it between the number of elements.
#. After setting the kernel, we can generate the filter by using the function :filter2d:`filter2D <>`:
* The Hough Circle Transform works in a *roughly* analogous way to the Hough Line Transform explained in the previous tutorial.
* In the line detection case, a line was defined by two parameters :math:`(r, \theta)`. In the circle case, we need three parameters to define a circle:
..math::
C : ( x_{center}, y_{center}, r )
C : ( x_{center}, y_{center}, r )
where :math:`(x_{center}, y_{center})` define the center position (gree point) and :math:`r` is the radius, which allows us to completely define a circle, as it can be seen below:
:alt:Result of detecting circles with Hough Transform
:align:center
:align:center
* For sake of efficiency, OpenCV implements a detection method slightly trickier than the standard Hough Transform: *The Hough gradient method*. For more details, please check the book *Learning OpenCV* or your favorite Computer Vision bibliography
@ -34,19 +34,19 @@ Code
======
#. **What does this program do?**
* Loads an image and blur it to reduce the noise
* Applies the *Hough Circle Transform* to the blurred image .
* Applies the *Hough Circle Transform* to the blurred image .
* Display the detected circle in a window.
..|TutorialHoughCirclesSimpleDownload|replace:: here
#. The sample code that we will explain can be downloaded from |TutorialHoughCirclesSimpleDownload|_. A slightly fancier version (which shows both Hough standard and probabilistic with trackbars for changing the threshold values) can be found |TutorialHoughCirclesFancyDownload|_.
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
@ -66,7 +66,7 @@ Code
if( !src.data )
{ return -1; }
/// Convert it to gray
/// Convert it to gray
cvtColor( src, src_gray, CV_BGR2GRAY );
/// Reduce the noise so we avoid false circle detection
@ -88,7 +88,7 @@ Code
circle( src, center, radius, Scalar(0,0,255), 3, 8, 0 );
}
/// Show your results
/// Show your results
namedWindow( "Hough Circle Transform Demo", CV_WINDOW_AUTOSIZE );
imshow( "Hough Circle Transform Demo", src );
@ -117,7 +117,7 @@ Explanation
cvtColor( src, src_gray, CV_BGR2GRAY );
#. Apply a Gaussian blur to reduce noise and avoid false circle detection:
Meaning that each pair :math:`(r_{\theta},\theta)` represents each line that passes by :math:`(x_{0}, y_{0})`.
Meaning that each pair :math:`(r_{\theta},\theta)` represents each line that passes by :math:`(x_{0}, y_{0})`.
#. If for a given :math:`(x_{0}, y_{0})` we plot the family of lines that goes through it, we get a sinusoid. For instance, for :math:`x_{0} = 8` and :math:`y_{0} = 6` we get the following plot (in a plane :math:`\theta` - :math:`r`):
:alt:Polar plot of a the family of lines of a point
:align:center
:align:center
We consider only points such that :math:`r > 0` and :math:`0< \theta < 2 \pi`.
We consider only points such that :math:`r > 0` and :math:`0< \theta < 2 \pi`.
#. We can do the same operation above for all the points in an image. If the curves of two different points intersect in the plane :math:`\theta` - :math:`r`, that means that both points belong to a same line. For instance, following with the example above and drawing the plot for two more points: :math:`x_{1} = 9`, :math:`y_{1} = 4` and :math:`x_{2} = 12`, :math:`y_{2} = 3`, we get:
:alt:Polar plot of the family of lines for three points
:align:center
:align:center
The three plots intersect in one single point :math:`(0.925, 9.6)`, these coordinates are the parameters (:math:`\theta, r`) or the line in which :math:`(x_{0}, y_{0})`, :math:`(x_{1}, y_{1})` and :math:`(x_{2}, y_{2})` lay.
The three plots intersect in one single point :math:`(0.925, 9.6)`, these coordinates are the parameters (:math:`\theta, r`) or the line in which :math:`(x_{0}, y_{0})`, :math:`(x_{1}, y_{1})` and :math:`(x_{2}, y_{2})` lay.
#. What does all the stuff above mean? It means that in general, a line can be *detected* by finding the number of intersections between curves.The more curves intersecting means that the line represented by that intersection have more points. In general, we can define a *threshold* of the minimum number of intersections needed to *detect* a line.
#. This is what the Hough Line Transform does. It keeps track of the intersection between curves of every point in the image. If the number of intersections is above some *threshold*, then it declares it as a line with the parameters :math:`(\theta, r_{\theta})` of the intersection point.
Standard and Probabilistic Hough Line Transform
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OpenCV implements two kind of Hough Line Transforms:
OpenCV implements two kind of Hough Line Transforms:
a. **The Standard Hough Transform**
@ -88,21 +88,21 @@ b. **The Probabilistic Hough Line Transform**
Code
======
..|TutorialHoughLinesSimpleDownload|replace:: here
* Applies either a *Standard Hough Line Transform* or a *Probabilistic Line Transform*.
* Applies either a *Standard Hough Line Transform* or a *Probabilistic Line Transform*.
* Display the original image and the detected line in two windows.
#. The sample code that we will explain can be downloaded from |TutorialHoughLinesSimpleDownload|_. A slightly fancier version (which shows both Hough standard and probabilistic with trackbars for changing the threshold values) can be found |TutorialHoughLinesFancyDownload|_.
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
@ -207,9 +207,9 @@ Explanation
* *rho* : The resolution of the parameter :math:`r` in pixels. We use **1** pixel.
* *theta*: The resolution of the parameter :math:`\theta` in radians. We use **1 degree** (CV_PI/180)
* *threshold*: The minimum number of intersections to "*detect*" a line
* *srn* and *stn*: Default parameters to zero. Check OpenCV reference for more info.
* *srn* and *stn*: Default parameters to zero. Check OpenCV reference for more info.
b. And then you display the result by drawing the lines.
b. And then you display the result by drawing the lines.
* *dst*: Output of the edge detector. It should be a grayscale image (although in fact it is a binary one)
* *lines*: A vector that will store the parameters :math:`(x_{start}, y_{start}, x_{end}, y_{end})` of the detected lines
* *rho* : The resolution of the parameter :math:`r` in pixels. We use **1** pixel.
* *theta*: The resolution of the parameter :math:`\theta` in radians. We use **1 degree** (CV_PI/180)
* *threshold*: The minimum number of intersections to "*detect*" a line
* *minLinLength*: The minimum number of points that can form a line. Lines with less than this number of points are disregarded.
* *maxLineGap*: The maximum gap between two points to be considered in the same line.
* *minLinLength*: The minimum number of points that can form a line. Lines with less than this number of points are disregarded.
* *maxLineGap*: The maximum gap between two points to be considered in the same line.
b. And then you display the result by drawing the lines.
@ -256,7 +256,7 @@ Explanation
}
#. Display the original image and the detected lines:
#. Display the original image and the detected lines:
..code-block:: cpp
@ -274,20 +274,20 @@ Result
=======
..note::
The results below are obtained using the slightly fancier version we mentioned in the *Code* section. It still implements the same stuff as above, only adding the Trackbar for the Threshold.
:alt:Result of detecting lines with Hough Transform
:align:center
:align:center
We get the following result by using the Probabilistic Hough Line Transform:
..image:: images/Hough_Lines_Tutorial_Result.jpg
:alt:Result of detecting lines with Hough Transform
:align:center
:align:center
You may observe that the number of lines detected vary while you change the *threshold*. The explanation is sort of evident: If you establish a higher threshold, fewer lines will be detected (since you will need more points to declare a line detected).
You may observe that the number of lines detected vary while you change the *threshold*. The explanation is sort of evident: If you establish a higher threshold, fewer lines will be detected (since you will need more points to declare a line detected).
#. From the explanation above, we deduce that the second derivative can be used to *detect edges*. Since images are "*2D*", we would need to take the derivative in both dimensions. Here, the Laplacian operator comes handy.
#. The *Laplacian operator* is defined by:
..math::
@ -49,13 +49,13 @@ Code
======
#. **What does this program do?**
* Loads an image
* Remove noise by applying a Gaussian blur and then convert the original image to grayscale
* Remove noise by applying a Gaussian blur and then convert the original image to grayscale
* Applies a Laplacian operator to the grayscale image and stores the output image
* Display the result in a window
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp>`_
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp>`_
* It is the process of taking pixels from one place in the image and locating them in another position in a new image.
* It is the process of taking pixels from one place in the image and locating them in another position in a new image.
* To accomplish the mapping process, it might be necessary to do some interpolation for non-integer pixel locations, since there will not always be a one-to-one-pixel correspondence between source and destination images.
* We can express the remap for every pixel location :math:`(x,y)` as:
..math::
g(x,y) = f ( h(x,y) )
where :math:`g()` is the remapped image, :math:`f()` the source image and :math:`h(x,y)` is the mapping function that operates on :math:`(x,y)`.
@ -34,7 +34,7 @@ What is remapping?
h(x,y) = (I.cols - x, y )
What would happen? It is easily seen that the image would flip in the :math:`x` direction. For instance, consider the input image:
What would happen? It is easily seen that the image would flip in the :math:`x` direction. For instance, consider the input image:
..image:: images/Remap_Tutorial_Theory_0.jpg
:alt:Original test image
@ -54,12 +54,12 @@ Code
====
#. **What does this program do?**
* Loads an image
* Each second, apply 1 of 4 different remapping processes to the image and display them indefinitely in a window.
* Wait for the user to exit the program
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgTrans/Remap_Demo.cpp>`_
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ImgTrans/Remap_Demo.cpp>`_
for all pairs :math:`(i,j)` such that: :math:`\dfrac{src.cols}{4}<i<\dfrac{3 \cdot src.cols}{4}` and :math:`\dfrac{src.rows}{4}<j<\dfrac{3 \cdot src.rows}{4}`
for all pairs :math:`(i,j)` such that: :math:`\dfrac{src.cols}{4}<i<\dfrac{3 \cdot src.cols}{4}` and :math:`\dfrac{src.rows}{4}<j<\dfrac{3 \cdot src.rows}{4}`
b. Turn the image upside down: :math:`h( i, j ) = (i, src.rows - j)`
c. Reflect the image from left to right: :math:`h(i,j) = ( src.cols - i, j )`
d. Combination of b and c: :math:`h(i,j) = ( src.cols - i, src.rows - j )`
This is expressed in the following snippet. Here, *map_x* represents the first coordinate of *h(i,j)* and *map_y* the second coordinate.
..code-block:: cpp
for( int j = 0; j < src.rows; j++ )
{ for( int i = 0; i < src.cols; i++ )
{
switch( ind )
{
{
case 0:
if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 )
You can easily notice that in an *edge*, the pixel intensity *changes* in a notorious way. A good way to express *changes* is by using *derivatives*. A high change in gradient indicates a major change in the image.
You can easily notice that in an *edge*, the pixel intensity *changes* in a notorious way. A good way to express *changes* is by using *derivatives*. A high change in gradient indicates a major change in the image.
#. To be more graphical, let's assume we have a 1D-image. An edge is shown by the "jump" in intensity in the plot below:
@ -51,9 +51,9 @@ Theory
Sobel Operator
---------------
#. The Sobel Operator is a discrete differentiation operator. It computes an approximation of the gradient of an image intensity function.
#. The Sobel Operator is a discrete differentiation operator. It computes an approximation of the gradient of an image intensity function.
#. The Sobel Operator combines Gaussian smoothing and differentiation.
#. The Sobel Operator combines Gaussian smoothing and differentiation.
Formulation
^^^^^^^^^^^^
@ -64,21 +64,21 @@ Assuming that the image to be operated is :math:`I`:
a. **Horizontal changes**: This is computed by convolving :math:`I` with a kernel :math:`G_{x}` with odd size. For example for a kernel size of 3, :math:`G_{x}` would be computed as:
..math::
G_{x} = \begin{bmatrix}
-1 & 0 & +1 \\
-2 & 0 & +2 \\
-1 & 0 & +1
-1 & 0 & +1
\end{bmatrix} * I
b. **Vertical changes**: This is computed by convolving :math:`I` with a kernel :math:`G_{y}` with odd size. For example for a kernel size of 3, :math:`G_{y}` would be computed as:
..math::
G_{y} = \begin{bmatrix}
-1 & -2 & -1 \\
0 & 0 & 0 \\
+1 & +2 & +1
+1 & +2 & +1
\end{bmatrix} * I
#. At each point of the image we calculate an approximation of the *gradient* in that point by combining both results above:
@ -90,7 +90,7 @@ Assuming that the image to be operated is :math:`I`:
Although sometimes the following simpler equation is used:
..math::
G = |G_{x}| + |G_{y}|
@ -103,14 +103,14 @@ Assuming that the image to be operated is :math:`I`:
G_{x} = \begin{bmatrix}
-3 & 0 & +3 \\
-10 & 0 & +10 \\
-3 & 0 & +3
\end{bmatrix}
-3 & 0 & +3
\end{bmatrix}
G_{y} = \begin{bmatrix}
-3 & -10 & -3 \\
0 & 0 & 0 \\
+3 & +10 & +3
\end{bmatrix}
+3 & +10 & +3
\end{bmatrix}
You can check out more information of this function in the OpenCV reference (:scharr:`Scharr <>`). Also, in the sample code below, you will notice that above the code for :sobel:`Sobel <>` function there is also code for the :scharr:`Scharr <>` function commented. Uncommenting it (and obviously commenting the Sobel stuff) should give you an idea of how this function works.
@ -118,12 +118,12 @@ Code
=====
#. **What does this program do?**
* Applies the *Sobel Operator* and generates as output an image with the detected *edges* bright on a darker background.
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp>`_
..code-block:: cpp
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp>`_
* *src_gray*: In our example, the input image. Here it is *CV_8U*
* *grad_x*/*grad_y*: The output image.
* *src_gray*: In our example, the input image. Here it is *CV_8U*
* *grad_x*/*grad_y*: The output image.
* *ddepth*: The depth of the output image. We set it to *CV_16S* to avoid overflow.
* *x_order*: The order of the derivative in **x** direction.
* *y_order*: The order of the derivative in **y** direction.
* *x_order*: The order of the derivative in **x** direction.
* *y_order*: The order of the derivative in **y** direction.
* *scale*, *delta* and *BORDER_DEFAULT*: We use default values.
Notice that to calculate the gradient in *x* direction we use: :math:`x_{order}= 1` and :math:`y_{order} = 0`. We do analogously for the *y* direction.
Notice that to calculate the gradient in *x* direction we use: :math:`x_{order}= 1` and :math:`y_{order} = 0`. We do analogously for the *y* direction.
#. We convert our partial results back to *CV_8U*:
@ -248,7 +248,7 @@ Explanation
convertScaleAbs( grad_x, abs_grad_x );
convertScaleAbs( grad_y, abs_grad_y );
#. Finally, we try to approximate the *gradient* by adding both directional gradients (note that this is not an exact calculation at all! but it is good for our purposes).
@ -268,7 +268,7 @@ Results
========
#. Here is the output of applying our basic detector to *lena.jpg*:
#. It is any transformation that can be expressed in the form of a *matrix multiplication* (linear transformation) followed by a *vector addition* (translation).
#. It is any transformation that can be expressed in the form of a *matrix multiplication* (linear transformation) followed by a *vector addition* (translation).
#. From the above, We can use an Affine Transformation to express:
#. From the above, We can use an Affine Transformation to express:
a. Rotations (linear transformation)
b. Translations (vector addition)
c. Scale operations (linear transformation)
you can see that, in essence, an Affine Transformation represents a **relation** between two images.
#. The usual way to represent an Affine Transform is by using a :math:`2 \times 3` matrix.
you can see that, in essence, an Affine Transformation represents a **relation** between two images.
..math::
#. The usual way to represent an Affine Transform is by using a :math:`2 \times 3` matrix.
..math::
A = \begin{bmatrix}
a_{00} & a_{01} \\
a_{00} & a_{01} \\
a_{10} & a_{11}
\end{bmatrix}_{2 \times 2}
B = \begin{bmatrix}
b_{00} \\
b_{00} \\
b_{10}
\end{bmatrix}_{2 \times 1}
M = \begin{bmatrix}
A & B
A & B
\end{bmatrix}
=
=
\begin{bmatrix}
a_{00} & a_{01} & b_{00} \\
a_{10} & a_{11} & b_{10}
a_{00} & a_{01} & b_{00} \\
a_{10} & a_{11} & b_{10}
\end{bmatrix}_{2 \times 3}
Considering that we want to transform a 2D vector :math:`X = \begin{bmatrix}x \\ y\end{bmatrix}` by using :math:`A` and :math:`B`, we can do it equivalently with:
:math:`T = A \cdot \begin{bmatrix}x \\ y\end{bmatrix} + B` or :math:`T = M \cdot [x, y, 1]^{T}`
..math::
T = \begin{bmatrix}
a_{00}x + a_{01}y + b_{00} \\
a_{00}x + a_{01}y + b_{00} \\
a_{10}x + a_{11}y + b_{10}
\end{bmatrix}
\end{bmatrix}
How do we get an Affine Transformation?
@ -80,20 +80,20 @@ How do we get an Affine Transformation?
:width:350pt
:align:center
the points 1, 2 and 3 (forming a triangle in image 1) are mapped into image 2, still forming a triangle, but now they have changed notoriously. If we find the Affine Transformation with these 3 points (you can choose them as you like), then we can apply this found relation to the whole pixels in the image.
the points 1, 2 and 3 (forming a triangle in image 1) are mapped into image 2, still forming a triangle, but now they have changed notoriously. If we find the Affine Transformation with these 3 points (you can choose them as you like), then we can apply this found relation to the whole pixels in the image.
Code
====
#. **What does this program do?**
* Loads an image
* Applies an Affine Transform to the image. This Transform is obtained from the relation between three points. We use the function :warp_affine:`warpAffine <>` for that purpose.
* Applies a Rotation to the image after being transformed. This rotation is with respect to the image center
* Waits until the user exits the program
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgTrans/Geometric_Transforms_Demo.cpp>`_
#. The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ImgTrans/Geometric_Transforms_Demo.cpp>`_
..code-block:: cpp
@ -123,14 +123,14 @@ Code
/// Load the image
src = imread( argv[1], 1 );
/// Set the dst image the same type and size as src
/// Set the dst image the same type and size as src
You may want to draw the points to make a better idea of how they change. Their locations are approximately the same as the ones depicted in the example figure (in the Theory section). You may note that the size and orientation of the triangle defined by the 3 points change.
#. Armed with both sets of points, we calculate the Affine Transform by using OpenCV function :get_affine_transform:`getAffineTransform <>`:
@ -264,7 +264,7 @@ Explanation
#. Finally, we display our results in two windows plus the original image for good measure:
..code-block:: cpp
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, src );
@ -292,7 +292,7 @@ Result
:alt:Original image
:width:250pt
:align:center
after applying the first Affine Transform we obtain:
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
@ -145,7 +145,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
if( !src.data )
{ return -1; }
/// Create window
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
@ -153,12 +153,12 @@ This tutorial code's is shown lines below. You can also download it from `here <
createTrackbar("Operator:\n 0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat", window_name, &morph_operator, max_operator, Morphology_Operations );
* Every time we move any slider, the user's function **Morphology_Operations** will be called to effectuate a new morphology operation and it will update the output image based on the current trackbar values.
..code-block:: cpp
/**
/**
* @function Morphology_Operations
*/
void Morphology_Operations( int, void* )
@ -235,11 +235,11 @@ Explanation
// Since MORPH_X : 2,3,4,5 and 6
int operation = morph_operator + 2;
Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );
Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );
/// Apply the specified morphology operation
morphologyEx( src, dst, operation, element );
imshow( window_name, dst );
imshow( window_name, dst );
}
@ -259,11 +259,11 @@ Explanation
..code-block:: cpp
int operation = morph_operator + 2;
int operation = morph_operator + 2;
* **element**: The kernel to be used. We use the function :get_structuring_element:`getStructuringElement <>` to define our own structure.
* And here are two snapshots of the display window. The first picture shows the output after using the operator **Opening** with a cross kernel. The second picture (right side, shows the result of using a **Blackhat** operator with an ellipse kernel.
@ -11,7 +11,7 @@ In this tutorial you will learn how to:
..container:: enumeratevisibleitemswithsquare
* Use the OpenCV functions :pyr_up:`pyrUp <>` and :pyr_down:`pyrDown <>` to downsample or upsample a given image.
Theory
=======
@ -21,9 +21,9 @@ Theory
..container:: enumeratevisibleitemswithsquare
* Usually we need to convert an image to a size different than its original. For this, there are two possible options:
#. *Upsize* the image (zoom in) or
#. *Downsize* it (zoom out).
#. *Upsize* the image (zoom in) or
#. *Downsize* it (zoom out).
* Although there is a *geometric transformation* function in OpenCV that -literally- resize an image (:resize:`resize <>`, which we will show in a future tutorial), in this section we analyze first the use of **Image Pyramids**, which are widely applied in a huge range of vision applications.
@ -39,20 +39,20 @@ Image Pyramid
* **Gaussian pyramid:** Used to downsample images
* **Laplacian pyramid:** Used to reconstruct an upsampled image from an image lower in the pyramid (with less resolution)
* **Laplacian pyramid:** Used to reconstruct an upsampled image from an image lower in the pyramid (with less resolution)
* In this tutorial we'll use the *Gaussian pyramid*.
Gaussian Pyramid
^^^^^^^^^^^^^^^^^
* Imagine the pyramid as a set of layers in which the higher the layer, the smaller the size.
* Imagine the pyramid as a set of layers in which the higher the layer, the smaller the size.
* You can easily notice that the resulting image will be exactly one-quarter the area of its predecessor. Iterating this process on the input image :math:`G_{0}` (original image) produces the entire pyramid.
@ -72,7 +72,7 @@ Gaussian Pyramid
* Perform a convolution with the same kernel shown above (multiplied by 4) to approximate the values of the "missing pixels"
* These two procedures (downsampling and upsampling as explained above) are implemented by the OpenCV functions :pyr_up:`pyrUp <>` and :pyr_down:`pyrDown <>`, as we will see in an example with the code below:
* These two procedures (downsampling and upsampling as explained above) are implemented by the OpenCV functions :pyr_up:`pyrUp <>` and :pyr_down:`pyrDown <>`, as we will see in an example with the code below:
..note::
When we reduce the size of an image, we are actually *losing* information of the image.
@ -80,9 +80,9 @@ Gaussian Pyramid
Code
======
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgProc/Pyramids.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ImgProc/Pyramids.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
@ -115,7 +115,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
{ printf(" No data! -- Exiting the program \n");
return -1; }
tmp = src;
tmp = src;
dst = tmp;
/// Create window
@ -124,7 +124,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
/// Loop
while( true )
{
{
int c;
c = waitKey(10);
@ -132,7 +132,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
Our program exits if the user presses *ESC*. Besides, it has two options:
* **Perform upsampling (after pressing 'u')**
* **Perform upsampling (after pressing 'u')**
..code-block:: cpp
@ -217,7 +217,7 @@ Explanation
* *dst*: The destination image (to be shown on screen, supposedly the double of the input image)
* *Size( tmp.cols*2, tmp.rows*2 )* : The destination size. Since we are upsampling, :pyr_up:`pyrUp <>` expects a size double than the input image (in this case *tmp*).
* **Perform downsampling (after pressing 'd')**
* **Perform downsampling (after pressing 'd')**
..code-block:: cpp
@ -232,7 +232,7 @@ Explanation
* Notice that it is important that the input image can be divided by a factor of two (in both dimensions). Otherwise, an error will be shown.
* Finally, we update the input image **tmp** with the current image displayed, so the subsequent operations are performed on it.
..code-block:: cpp
tmp = dst;
@ -245,19 +245,19 @@ Results
* After compiling the code above we can test it. The program calls an image **chicky_512.jpg** that comes in the *tutorial_code/image* folder. Notice that this image is :math:`512 \times 512`, hence a downsample won't generate any error (:math:`512 = 2^{9}`). The original image is shown below:
* Note that we should have lost some resolution due to the fact that we are diminishing the size of the image. This is evident after we apply :pyr_up:`pyrUp <>` twice (by pressing 'u'). Our output is now:
@ -11,9 +11,9 @@ In this tutorial you will learn how to:
..container:: enumeratevisibleitemswithsquare
* Use the OpenCV function :bounding_rect:`boundingRect <>`
* Use the OpenCV function :bounding_rect:`boundingRect <>`
* Use the OpenCV function :min_enclosing_circle:`minEnclosingCircle <>`
Theory
======
@ -21,9 +21,9 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
@ -73,7 +73,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
@ -11,9 +11,9 @@ In this tutorial you will learn how to:
..container:: enumeratevisibleitemswithsquare
* Use the OpenCV function :min_area_rect:`minAreaRect <>`
* Use the OpenCV function :min_area_rect:`minAreaRect <>`
* Use the OpenCV function :fit_ellipse:`fitEllipse <>`
Theory
======
@ -21,9 +21,9 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
@ -73,7 +73,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
@ -10,8 +10,8 @@ In this tutorial you will learn how to:
..container:: enumeratevisibleitemswithsquare
* Use the OpenCV function :find_contours:`findContours <>`
* Use the OpenCV function :draw_contours:`drawContours <>`
* Use the OpenCV function :find_contours:`findContours <>`
* Use the OpenCV function :draw_contours:`drawContours <>`
Theory
======
@ -19,9 +19,9 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
@ -71,20 +71,20 @@ This tutorial code's is shown lines below. You can also download it from `here <
@ -10,7 +10,7 @@ In this tutorial you will learn how to:
..container:: enumeratevisibleitemswithsquare
* Use the OpenCV function :convex_hull:`convexHull <>`
* Use the OpenCV function :convex_hull:`convexHull <>`
Theory
@ -19,11 +19,11 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
@ -33,7 +33,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
using namespace std;
Mat src; Mat src_gray;
int thresh = 100;
int thresh = 100;
int max_thresh = 255;
RNG rng(12345);
@ -73,21 +73,21 @@ This tutorial code's is shown lines below. You can also download it from `here <
@ -11,9 +11,9 @@ In this tutorial you will learn how to:
..container:: enumeratevisibleitemswithsquare
* Use the OpenCV function :moments:`moments <>`
* Use the OpenCV function :moments:`moments <>`
* Use the OpenCV function :contour_area:`contourArea <>`
* Use the OpenCV function :arc_length:`arcLength <>`
* Use the OpenCV function :arc_length:`arcLength <>`
Theory
======
@ -21,9 +21,9 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
@ -73,7 +73,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
@ -10,8 +10,8 @@ In this tutorial you will learn how to:
..container:: enumeratevisibleitemswithsquare
* Use the OpenCV function :point_polygon_test:`pointPolygonTest <>`
* Use the OpenCV function :point_polygon_test:`pointPolygonTest <>`
Theory
======
@ -19,9 +19,9 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
@ -51,13 +51,13 @@ This tutorial code's is shown lines below. You can also download it from `here <
* Application example: Separate out regions of an image corresponding to objects which we want to analyze. This separation is based on the variation of intensity between the object pixels and the background pixels.
* To differentiate the pixels we are interested in from the rest (which will eventually be rejected), we perform a comparison of each pixel intensity value with respect to a *threshold* (determined according to the problem to solve).
* To differentiate the pixels we are interested in from the rest (which will eventually be rejected), we perform a comparison of each pixel intensity value with respect to a *threshold* (determined according to the problem to solve).
* Once we have separated properly the important pixels, we can set them with a determined value to identify them (i.e. we can assign them a value of :math:`0` (black), :math:`255` (white) or any value that suits your needs).
* So, if the intensity of the pixel :math:`src(x,y)` is higher than :math:`thresh`, then the new pixel intensity is set to a :math:`MaxVal`. Otherwise, the pixels are set to :math:`0`.
* If the intensity of the pixel :math:`src(x,y)` is higher than :math:`thresh`, then the new pixel intensity is set to a :math:`0`. Otherwise, it is set to :math:`MaxVal`.
The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgProc/Threshold.cpp>`_
The tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/ImgProc/Threshold.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
@ -173,8 +173,8 @@ The tutorial code's is shown lines below. You can also download it from `here <h
#. First, we try to threshold our image with a *binary threhold inverted*. We expect that the pixels brighter than the :math:`thresh` will turn dark, which is what actually happens, as we can see in the snapshot below (notice from the original image, that the doggie's tongue and eyes are particularly bright in comparison with the image, this is reflected in the output image).
#. Now we try with the *threshold to zero*. With this, we expect that the darkest pixels (below the threshold) will become completely black, whereas the pixels with value greater than the threshold will keep its original value. This is verified by the following snapshot of the output image:
* Create a named OpenCV window (using :named_window:`namedWindow <>`)
* Display an image in an OpenCV window (using :imshow:`imshow <>`)
@ -17,7 +17,7 @@ In this tutorial you will learn how to:
Source Code
===========
Download the source code from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/introduction/display_image/display_image.cpp>`_.
Download the source code from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/introduction/display_image/display_image.cpp>`_.
In OpenCV 2 we have multiple modules. Each one takes care of a different area or approach towards image processing. You could already observe this in the structure of the user guide of these tutorials itself. Before you use any of them you first need to include the header files where the content of each individual module is declared.
You'll almost always end up using the:
You'll almost always end up using the:
..container:: enumeratevisibleitemswithsquare
@ -75,23 +75,23 @@ Now we call the :imread:`imread <>` function which loads the image name specifie
:tab-width:4
:lines:17
..note::
..note::
OpenCV offers support for the image formats Windows bitmap (bmp), portable image formats (pbm, pgm, ppm) and Sun raster (sr, ras). With help of plugins (you need to specify to use them if you build yourself the library, nevertheless in the packages we ship present by default) you may also load image formats like JPEG (jpeg, jpg, jpe), JPEG 2000 (jp2 - codenamed in the CMake as Jasper), TIFF files (tiff, tif) and portable network graphics (png). Furthermore, OpenEXR is also a possibility.
OpenCV offers support for the image formats Windows bitmap (bmp), portable image formats (pbm, pgm, ppm) and Sun raster (sr, ras). With help of plugins (you need to specify to use them if you build yourself the library, nevertheless in the packages we ship present by default) you may also load image formats like JPEG (jpeg, jpg, jpe), JPEG 2000 (jp2 - codenamed in the CMake as Jasper), TIFF files (tiff, tif) and portable network graphics (png). Furthermore, OpenEXR is also a possibility.
After checking that the image data was loaded correctly, we want to display our image, so we create an OpenCV window using the :named_window:`namedWindow <>` function. These are automatically managed by OpenCV once you create them. For this you need to specify its name and how it should handle the change of the image it contains from a size point of view. It may be:
After checking that the image data was loaded correctly, we want to display our image, so we create an OpenCV window using the :named_window:`namedWindow <>` function. These are automatically managed by OpenCV once you create them. For this you need to specify its name and how it should handle the change of the image it contains from a size point of view. It may be:
..container:: enumeratevisibleitemswithsquare
+ *CV_WINDOW_AUTOSIZE* is the only supported one if you do not use the Qt backend. In this case the window size will take up the size of the image it shows. No resize permitted!
+ *CV_WINDOW_NORMAL* on Qt you may use this to allow window resize. The image will resize itself according to the current window size. By using the | operator you also need to specify if you would like the image to keep its aspect ratio (*CV_WINDOW_KEEPRATIO*) or not (*CV_WINDOW_FREERATIO*).
+ *CV_WINDOW_AUTOSIZE* is the only supported one if you do not use the Qt backend. In this case the window size will take up the size of the image it shows. No resize permitted!
+ *CV_WINDOW_NORMAL* on Qt you may use this to allow window resize. The image will resize itself according to the current window size. By using the | operator you also need to specify if you would like the image to keep its aspect ratio (*CV_WINDOW_KEEPRATIO*) or not (*CV_WINDOW_FREERATIO*).
Finally, to update the content of the OpenCV window with a new image use the :imshow:`imshow <>` function. Specify the OpenCV window name to update and the image to use during this operation:
Finally, to update the content of the OpenCV window with a new image use the :imshow:`imshow <>` function. Specify the OpenCV window name to update and the image to use during this operation:
* Compile your code and then run the executable giving an image path as argument. If you're on Windows the executable will of course contain an *exe* extension too. Of course assure the image file is near your program file.
* Compile your code and then run the executable giving an image path as argument. If you're on Windows the executable will of course contain an *exe* extension too. Of course assure the image file is near your program file.
@ -14,7 +14,7 @@ In this tutorial you will learn how to:
* :cascade_classifier_load:`load <>` to load a .xml classifier file. It can be either a Haar or a LBP classifer
* :cascade_classifier_detect_multiscale:`detectMultiScale <>` to perform the detection.
Theory
======
@ -22,9 +22,9 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/objectDetection/objectDetection.cpp>`_ . The second version (using LBP for face detection) can be `found here <http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/objectDetection/objectDetection2.cpp>`_
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/objectDetection/objectDetection.cpp>`_ . The second version (using LBP for face detection) can be `found here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/objectDetection/objectDetection2.cpp>`_
..code-block:: cpp
..code-block:: cpp
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
@ -56,7 +56,7 @@ This tutorial code's is shown lines below. You can also download it from `here <
Remember to copy the files *haarcascade_frontalface_alt.xml* and *haarcascade_eye_tree_eyeglasses.xml* in your current directory. They are located in *opencv/data/haarcascades*
Remember to copy the files *haarcascade_frontalface_alt.xml* and *haarcascade_eye_tree_eyeglasses.xml* in your current directory. They are located in *opencv/data/haarcascades*
#. This is the result of using the file *lbpcascade_frontalface.xml* (LBP trained) for the face detection. For the eyes we keep using the file used in the tutorial.
#. This is the result of using the file *lbpcascade_frontalface.xml* (LBP trained) for the face detection. For the eyes we keep using the file used in the tutorial.
The following links describe a set of basic OpenCV tutorials. All the source code mentioned here is provide as part of the OpenCV regular releases, so check before you start copy & pasting the code. The list of tutorials below is automatically generated from reST files located in our SVN repository.
The following links describe a set of basic OpenCV tutorials. All the source code mentioned here is provide as part of the OpenCV regular releases, so check before you start copy & pasting the code. The list of tutorials below is automatically generated from reST files located in our GIT repository.
As always, we would be happy to hear your comments and receive your contributions on any tutorial.
@ -10,12 +10,12 @@ As always, we would be happy to hear your comments and receive your contribution
|Core| Here you will learn the about the basic building blocks of the library. A must read and know for understanding how to manipulate the images on a pixel level.
|HighGui| This section contains valuable tutorials about how to read/save your image/video files and how to use the built-in graphical user interface of the library.
|HighGui| This section contains valuable tutorials about how to read/save your image/video files and how to use the built-in graphical user interface of the library.
|Calib3D| Although we got most of our images in a 2D format they do come from a 3D world. Here you will learn how to find out from the 2D images information about the 3D world.
|Calib3D| Although we got most of our images in a 2D format they do come from a 3D world. Here you will learn how to find out from the 2D images information about the 3D world.
|General| These tutorials are the bottom of the iceberg as they link together multiple of the modules presented above in order to solve complex problems.
@ -15,7 +15,7 @@ In order to use depth sensor with OpenCV you should do the following preliminary
Install OpenNI library (from here http://www.openni.org/downloadfiles) and PrimeSensor Module for OpenNI (from here https://github.com/avin2/SensorKinect). The installation should be done to default folders listed in the instructions of these products, e.g.:
..code-block:: text
OpenNI:
Linux & MacOSX:
Libs into: /usr/lib
@ -30,7 +30,7 @@ In order to use depth sensor with OpenCV you should do the following preliminary
If one or both products were installed to the other folders, the user should change corresponding CMake variables ``OPENNI_LIB_DIR``, ``OPENNI_INCLUDE_DIR`` or/and ``OPENNI_PRIME_SENSOR_MODULE_BIN_DIR``.
#.
Configure OpenCV with OpenNI support by setting ``WITH_OPENNI`` flag in CMake. If OpenNI is found in install folders OpenCV will be built with OpenNI library (see a status ``OpenNI`` in CMake log) whereas PrimeSensor Modules can not be found (see a status ``OpenNI PrimeSensor Modules`` in CMake log). Without PrimeSensor module OpenCV will be successfully compiled with OpenNI library, but ``VideoCapture`` object will not grab data from Kinect sensor.
@ -56,9 +56,9 @@ In order to get depth map from depth sensor use ``VideoCapture::operator >>``, e
VideoCapture capture( CV_CAP_OPENNI );
for(;;)
{
Mat depthMap;
Mat depthMap;
capture >> depthMap;
if( waitKey( 30 ) >= 0 )
break;
}
@ -70,19 +70,19 @@ For getting several data maps use ``VideoCapture::grab`` and ``VideoCapture::ret
{
Mat depthMap;
Mat rgbImage
capture.grab();
capture.retrieve( depthMap, OPENNI_DEPTH_MAP );
capture.retrieve( bgrImage, OPENNI_BGR_IMAGE );
if( waitKey( 30 ) >= 0 )
break;
}
For setting and getting some property of sensor` data generators use ``VideoCapture::set`` and ``VideoCapture::get`` methods respectively, e.g. ::
@ -100,34 +100,34 @@ Some depth sensors (for example XtionPRO) do not have image generator. In order
Flags specifing the needed generator type must be used in combination with particular generator property. The following properties of cameras available through OpenNI interfaces are supported:
*
*
For image generator:
- ``CV_CAP_PROP_OPENNI_OUTPUT_MODE`` -- Three output modes are supported: ``CV_CAP_OPENNI_VGA_30HZ`` used by default (image generator returns images in VGA resolution with 30 FPS), ``CV_CAP_OPENNI_SXGA_15HZ`` (image generator returns images in SXGA resolution with 15 FPS) and ``CV_CAP_OPENNI_SXGA_30HZ`` (image generator returns images in SXGA resolution with 30 FPS, the mode is supported by XtionPRO Live); depth generator's maps are always in VGA resolution.
*
*
For depth generator:
- ``CV_CAP_PROP_OPENNI_REGISTRATION`` -- Flag that registers the remapping depth map to image map by changing depth generator's view point (if the flag is ``"on"``) or sets this view point to its normal one (if the flag is ``"off"``). The registration process’s resulting images are pixel-aligned,which means that every pixel in the image is aligned to a pixel in the depth image.
Next properties are available for getting only:
- ``CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH`` -- A maximum supported depth of Kinect in mm.
- ``CV_CAP_PROP_OPENNI_BASELINE`` -- Baseline value in mm.
- ``CV_CAP_PROP_OPENNI_FOCAL_LENGTH`` -- A focal length in pixels.
- ``CV_CAP_PROP_OPENNI_BASELINE`` -- Baseline value in mm.
- ``CV_CAP_PROP_OPENNI_FOCAL_LENGTH`` -- A focal length in pixels.
- ``CV_CAP_PROP_FRAME_WIDTH`` -- Frame width in pixels.
- ``CV_CAP_PROP_FRAME_HEIGHT`` -- Frame height in pixels.
- ``CV_CAP_PROP_FPS`` -- Frame rate in FPS.
*
Some typical flags combinations "generator type + property" are defined as single flags:
@ -2446,6 +2446,6 @@ The above methods are usually enough for users. If you want to make your own alg
* Make a class and specify ``Algorithm`` as its base class.
* The algorithm parameters should be the class members. See ``Algorithm::get()`` for the list of possible types of the parameters.
* Add public virtual method ``AlgorithmInfo* info() const;`` to your class.
* Add constructor function, ``AlgorithmInfo`` instance and implement the ``info()`` method. The simplest way is to take http://code.opencv.org/svn/opencv/trunk/opencv/modules/ml/src/ml_init.cpp as the reference and modify it according to the list of your parameters.
* Add constructor function, ``AlgorithmInfo`` instance and implement the ``info()`` method. The simplest way is to take http://code.opencv.org/projects/opencv/repository/revisions/master/entry/modules/ml/src/ml_init.cpp as the reference and modify it according to the list of your parameters.
* Add some public function (e.g. ``initModule_<mymodule>()``) that calls info() of your algorithm and put it into the same source file as ``info()`` implementation. This is to force C++ linker to include this object file into the target application. See ``Algorithm::create()`` for details.
@ -42,7 +42,7 @@ You can always determine at runtime whether the OpenCV GPU-built binaries (or PT
Utilizing Multiple GPUs
-----------------------
In the current version, each of the OpenCV GPU algorithms can use only a single GPU. So, to utilize multiple GPUs, you have to manually distribute the work between GPUs.
In the current version, each of the OpenCV GPU algorithms can use only a single GPU. So, to utilize multiple GPUs, you have to manually distribute the work between GPUs.
Switching active devie can be done using :ocv:func:`gpu::setDevice()` function. For more details please read Cuda C Programing Guide.
While developing algorithms for multiple GPUs, note a data passing overhead. For primitive functions and small images, it can be significant, which may eliminate all the advantages of having multiple GPUs. But for high-level algorithms, consider using multi-GPU acceleration. For example, the Stereo Block Matching algorithm has been successfully parallelized using the following algorithm:
@ -59,5 +59,5 @@ While developing algorithms for multiple GPUs, note a data passing overhead. For
With this algorithm, a dual GPU gave a 180
%
performance increase comparing to the single Fermi GPU. For a source code example, see
@ -294,7 +294,7 @@ The methods/functions grab the next frame from video file or camera and return t
The primary use of the function is in multi-camera environments, especially when the cameras do not have hardware synchronization. That is, you call ``VideoCapture::grab()`` for each camera and after that call the slower method ``VideoCapture::retrieve()`` to decode and get frame from each camera. This way the overhead on demosaicing or motion jpeg decompression etc. is eliminated and the retrieved frames from different cameras will be closer in time.
Also, when a connected camera is multi-head (for example, a stereo camera or a Kinect device), the correct way of retrieving data from it is to call `VideoCapture::grab` first and then call :ocv:func:`VideoCapture::retrieve` one or more times with different values of the ``channel`` parameter. See http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/kinect_maps.cpp
Also, when a connected camera is multi-head (for example, a stereo camera or a Kinect device), the correct way of retrieving data from it is to call `VideoCapture::grab` first and then call :ocv:func:`VideoCapture::retrieve` one or more times with different values of the ``channel`` parameter. See http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/kinect_maps.cpp
@ -203,7 +203,7 @@ Sets mouse handler for the specified window
:param winname:Window name
:param onMouse:Mouse callback. See OpenCV samples, such as http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/ffilldemo.cpp, on how to specify and use the callback.
:param onMouse:Mouse callback. See OpenCV samples, such as http://code.opencv.org/projects/opencv/repository/revisions/master/entry/samples/cpp/ffilldemo.cpp, on how to specify and use the callback.
:param userdata:The optional parameter passed to the callback.
@ -202,7 +202,7 @@ Approximates a polygonal curve(s) with the specified precision.
The functions ``approxPolyDP`` approximate a curve or a polygon with another curve/polygon with less vertices so that the distance between them is less or equal to the specified precision. It uses the Douglas-Peucker algorithm
@ -21,7 +21,7 @@ The word "cascade" in the classifier name means that the resultant classifier co
The feature used in a particular classifier is specified by its shape (1a, 2b etc.), position within the region of interest and the scale (this scale is not the same as the scale used at the detection stage, though these two scales are multiplied). For example, in the case of the third line feature (2c) the response is calculated as the difference between the sum of image pixels under the rectangle covering the whole feature (including the two white stripes and the black stripe in the middle) and the sum of the image pixels under the black stripe multiplied by 3 in order to compensate for the differences in the size of areas. The sums of pixel values over a rectangular regions are calculated rapidly using integral images (see below and the :ocv:func:`integral` description).
To see the object detector at work, have a look at the facedetect demo:
The following reference is for the detection part only. There is a separate application called ``opencv_traincascade`` that can train a cascade of boosted classifiers from a set of samples.