removed obsolete tex docs in order to avoid possible confusion
This commit is contained in:
parent
8047d0503f
commit
7735712732
723
doc/CvAux.tex
723
doc/CvAux.tex
@ -1,723 +0,0 @@
|
||||
\section{CvAux}
|
||||
|
||||
\ifC
|
||||
|
||||
\section{Stereo Correspondence Functions}
|
||||
|
||||
\cvCPyFunc{FindStereoCorrespondence}
|
||||
|
||||
Calculates disparity for a stereo-pair.
|
||||
|
||||
\cvdefC{
|
||||
cvFindStereoCorrespondence(
|
||||
\par const CvArr* leftImage, \par const CvArr* rightImage,
|
||||
\par int mode, \par CvArr* depthImage,
|
||||
\par int maxDisparity,
|
||||
\par double param1, \par double param2, \par double param3,
|
||||
\par double param4, \par double param5 );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{leftImage}{Left image of the stereo pair, a rectified, grayscale, 8-bit image.}
|
||||
\cvarg{rightImage}{Right image of the stereo pair, a rectified, grayscale, 8-bit image.}
|
||||
\cvarg{mode}{Algorithm used to find a disparity (now only CV\_DISPARITY\_BIRCHFIELD is supported).}
|
||||
\cvarg{depthImage}{Destination depth image, a grayscale, 8-bit image that codes the scaled disparity, so that the zero disparity (corresponding to the points that are very far from the cameras) maps to 0, and the maximum disparity maps to 255.}
|
||||
\cvarg{maxDisparity}{Maximum possible disparity. The closer the objects to the camera, the larger ths value should be. Very large values slow down the process significantly.}
|
||||
\cvarg{param1, param2, param3, param4, param5}{The parameters of the algorithm. param1 is the constant occlusion penalty, param2 is the constant match reward, param3 defines a highly reliable region (set of contiguous pixels whose reliability is at least param3), param4 defines a moderately reliable region, and param5 defines a slightly reliable region. If some parameter is omitted default, its value is used. In Birchfield's algorithm param1 = 25, param2 = 5, param3 = 12, param4 = 15, and param5 = 25 (These values have been taken from "Depth Discontinuities by Pixel-to-Pixel Stereo" Stanford University Technical Report STAN-CS-TR-96-1573, July 1996.).}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvFindStereoCorrespondence} calculates a disparity map for two rectified grayscale images.
|
||||
|
||||
Example: Calculating disparity for a pair of 8-bit color images
|
||||
|
||||
\begin{lstlisting}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
IplImage* srcLeft = cvLoadImage("left.jpg",1);
|
||||
IplImage* srcRight = cvLoadImage("right.jpg",1);
|
||||
IplImage* leftImage = cvCreateImage(cvGetSize(srcLeft), IPL\_DEPTH\_8U, 1);
|
||||
IplImage* rightImage = cvCreateImage(cvGetSize(srcRight), IPL\_DEPTH\_8U, 1);
|
||||
IplImage* depthImage = cvCreateImage(cvGetSize(srcRight), IPL\_DEPTH\_8U, 1);
|
||||
|
||||
cvCvtColor(srcLeft, leftImage, CV\_BGR2GRAY);
|
||||
cvCvtColor(srcRight, rightImage, CV\_BGR2GRAY);
|
||||
|
||||
cvFindStereoCorrespondence( leftImage, rightImage, CV\_DISPARITY\_BIRCHFIELD,
|
||||
depthImage, 50, 15, 3, 6, 8, 15 );
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
And here is the example stereo pair that can be used to test the example
|
||||
|
||||
\includegraphics{pics/left.jpg}
|
||||
|
||||
\includegraphics{pics/right.jpg}
|
||||
|
||||
\section{View Morphing Functions}
|
||||
|
||||
\cvCPyFunc{MakeScanlines}
|
||||
|
||||
Calculates the coordinates of scanlines for two cameras using a fundamental matrix.
|
||||
|
||||
\cvdefC{
|
||||
void cvMakeScanlines( \par const CvMatrix3* matrix, \par CvSize img\_size, \par int* scanlines1,
|
||||
\par int* scanlines2, \par int* lengths1, \par int* lengths2, \par int* line\_count );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{matrix}{Fundamental matrix.}
|
||||
\cvarg{imgSize}{Size of the image.}
|
||||
\cvarg{scanlines1}{Pointer to the array of calculated scanlines of the first image.}
|
||||
\cvarg{scanlines2}{Pointer to the array of calculated scanlines of the second image.}
|
||||
\cvarg{lengths1}{Pointer to the array of calculated lengths (in pixels) of the first image scanlines.}
|
||||
\cvarg{lengths2}{Pointer to the array of calculated lengths (in pixels) of the second image scanlines.}
|
||||
\cvarg{line\_count}{Pointer to the variable that stores the number of scanlines.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvMakeScanlines} finds the coordinates of scanlines for two images.
|
||||
|
||||
This function returns the number of scanlines. The function does nothing except calculating the number of scanlines if the pointers \texttt{scanlines1} or \texttt{scanlines2} are equal to zero.
|
||||
|
||||
\cvCPyFunc{PreWarpImage}
|
||||
|
||||
Rectifies an image.
|
||||
|
||||
\cvdefC{
|
||||
void cvPreWarpImage( \par int line\_count, \par IplImage* img, \par uchar* dst,
|
||||
\par int* dst\_nums, \par int* scanlines );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{line\_count}{Number of scanlines for the image.}
|
||||
\cvarg{img}{Image to prewarp.}
|
||||
\cvarg{dst}{Data to store for the prewarp image.}
|
||||
\cvarg{dst\_nums}{Pointer to the array of the lengths of the scanlines.}
|
||||
\cvarg{scanlines}{Pointer to the array of the coordinates of the scanlines.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvPreWarpImage} rectifies an image so that the scanlines in the rectified image are horizontal. The output buffer of size \texttt{max(width,height)*line\_count*3} must be allocated before calling the function.
|
||||
|
||||
\cvCPyFunc{FindRuns}
|
||||
|
||||
Retrieves the scanlines from a rectified image and breaks them down into runs.
|
||||
|
||||
\cvdefC{
|
||||
void cvFindRuns( \par int line\_count, \par uchar* prewarp1, \par uchar* prewarp2,
|
||||
\par int* line\_lengths1, \par int* line\_lengths2,
|
||||
\par int* runs1, \par int* runs2,
|
||||
\par int* num\_runs1, \par int* num\_runs2 );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{line\_count}{Number of scanlines.}
|
||||
\cvarg{prewarp1}{Prewarp data of the first image.}
|
||||
\cvarg{prewarp2}{Prewarp data of the second image.}
|
||||
\cvarg{line\_lengths1}{Array of the lengths of the scanlines in the first image.}
|
||||
\cvarg{line\_lengths2}{Array of the lengths of the scanlines in the second image.}
|
||||
\cvarg{runs1}{Array of the runs in each scanline in the first image.}
|
||||
\cvarg{runs2}{Array of the runs in each scanline in the second image.}
|
||||
\cvarg{num\_runs1}{Array of the number of runs in each scanline in the first image.}
|
||||
\cvarg{num\_runs2}{Array of the number of runs in each scanline in the second image.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvFindRuns} retrieves scanlines from the rectified image and breaks each scanline down into several runs, that is, a series of pixels of almost the same brightness.
|
||||
|
||||
\cvCPyFunc{DynamicCorrespondMulti}
|
||||
|
||||
Finds the correspondence between two sets of runs of two warped images.
|
||||
|
||||
\cvdefC{
|
||||
void cvDynamicCorrespondMulti( \par int line\_count, \par int* first, \par int* first\_runs,
|
||||
\par int* second, \par int* second\_runs,
|
||||
\par int* first\_corr, \par int* second\_corr );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{line\_count}{Number of scanlines.}
|
||||
\cvarg{first}{Array of the runs in the first image.}
|
||||
\cvarg{first\_runs}{Array of the number of runs in each scanline of the first image.}
|
||||
\cvarg{second}{Array of the runs in the second image.}
|
||||
\cvarg{second\_runs}{Array of the number of runs in each scanline of the second image.}
|
||||
\cvarg{first\_corr}{Pointer to the array of the correspondence information found for the first runs.}
|
||||
\cvarg{second\_corr}{Pointer to the array of the correspondence information found for the second runs.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvDynamicCorrespondMulti} finds the correspondence between two sets of runs of two images. Memory must be allocated before calling this function. Memory size for one array of correspondence information is
|
||||
|
||||
\texttt{max( width,height )* numscanlines*3*sizeof ( int ).}
|
||||
|
||||
|
||||
\cvCPyFunc{MakeAlphaScanlines}
|
||||
|
||||
Calculates the coordinates of the scanlines in an image from a virtual camera.
|
||||
|
||||
\cvdefC{
|
||||
void cvMakeAlphaScanlines( \par int* scanlines1, \par int* scanlines2,
|
||||
\par int* scanlinesA, \par int* lengths,
|
||||
\par int line\_count, \par float alpha );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{scanlines1}{Pointer to the array of the first scanlines.}
|
||||
\cvarg{scanlines2}{Pointer to the array of the second scanlines.}
|
||||
\cvarg{scanlinesA}{Pointer to the array of the scanlines found in the virtual image.}
|
||||
\cvarg{lengths}{Pointer to the array of the lengths of the scanlines found in the virtual image.}
|
||||
\cvarg{line\_count}{Number of scanlines.}
|
||||
\cvarg{alpha}{Position of virtual camera \texttt{(0.0 - 1.0)}.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvMakeAlphaScanlines} finds the coordinates of the scanlines for the virtual camera with the given camera position.
|
||||
|
||||
Memory must be allocated before calling this function. Memory size for the array of correspondence runs is \texttt{numscanlines*2*4*sizeof(int)}. Memory size for the array of the scanline lengths is \texttt{numscanlines*2*4*sizeof(int).}
|
||||
|
||||
\cvCPyFunc{MorphEpilinesMulti}
|
||||
|
||||
Morphs two pre-warped images using information about their stereo correspondence.
|
||||
|
||||
\cvdefC{
|
||||
void cvMorphEpilinesMulti( \par int line\_count, \par uchar* first\_pix, \par int* first\_num,
|
||||
\par uchar* second\_pix, \par int* second\_num,
|
||||
\par uchar* dst\_pix, \par int* dst\_num,
|
||||
\par float alpha, \par int* first, \par int* first\_runs,
|
||||
\par int* second, \par int* second\_runs,
|
||||
\par int* first\_corr, \par int* second\_corr );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{line\_count}{Number of scanlines in the prewarp image.}
|
||||
\cvarg{first\_pix}{Pointer to the first prewarp image.}
|
||||
\cvarg{first\_num}{Pointer to the array of the number of points in each scanline in the first image.}
|
||||
\cvarg{second\_pix}{Pointer to the second prewarp image.}
|
||||
\cvarg{second\_num}{Pointer to the array of the number of points in each scanline in the second image.}
|
||||
\cvarg{dst\_pix}{Pointer to the resulting morphed warped image.}
|
||||
\cvarg{dst\_num}{Pointer to the array of the number of points in each line.}
|
||||
\cvarg{alpha}{Virtual camera position \texttt{(0.0 - 1.0)}.}
|
||||
\cvarg{first}{First sequence of runs.}
|
||||
\cvarg{first\_runs}{Pointer to the number of runs in each scanline in the first image.}
|
||||
\cvarg{second}{Second sequence of runs.}
|
||||
\cvarg{second\_runs}{Pointer to the number of runs in each scanline in the second image.}
|
||||
\cvarg{first\_corr}{Pointer to the array of the correspondence information found for the first runs.}
|
||||
\cvarg{second\_corr}{Pointer to the array of the correspondence information found for the second runs.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvMorphEpilinesMulti} morphs two pre-warped images using information about the correspondence between the scanlines of the two images.
|
||||
|
||||
\cvCPyFunc{PostWarpImage}
|
||||
|
||||
Warps a rectified, morphed image back.
|
||||
|
||||
\cvdefC{
|
||||
void cvPostWarpImage( \par int line\_count, \par uchar* src, \par int* src\_nums,
|
||||
\par IplImage* img, \par int* scanlines );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{line\_count}{Number of scanlines.}
|
||||
\cvarg{src}{Pointer to the prewarp image virtual image.}
|
||||
\cvarg{src\_nums}{Number of scanlines in the image.}
|
||||
\cvarg{img}{Resulting unwarped image.}
|
||||
\cvarg{scanlines}{Pointer to the array of the scanlines data.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvPostWarpImage} warps the resultant image from the virtual camera by storing its rows across the scanlines whose coordinates are calculated by \cross{MakeAlphaScanlines}.
|
||||
|
||||
\cvCPyFunc{DeleteMoire}
|
||||
|
||||
Deletes moire in a given image.
|
||||
|
||||
\cvdefC{
|
||||
void cvDeleteMoire( IplImage* img );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Image.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvDeleteMoire} deletes moire from the given image. The post-warped image may have black (un-covered) points because of possible holes between neighboring scanlines. The function deletes moire (black pixels) from the image by substituting neighboring pixels for black pixels. If all the scanlines are horizontal, the function may be omitted.
|
||||
|
||||
\section{3D Tracking Functions} % XXX Weird URL Formatting, /../?
|
||||
|
||||
The section discusses functions for tracking objects in 3d space using a stereo camera. Besides C API, there is the DirectShow filter
|
||||
|
||||
\href{http://opencvlibrary.sourceforge.net/../appPage/3dTracker/3dTrackerFilter.htm}{http://opencvlibrary.sourceforge.net/../appPage/3dTracker/3dTrackerFilter.htm}
|
||||
|
||||
and the wrapper application.
|
||||
|
||||
\href{http://opencvlibrary.sourceforge.net/../appPage/3dTracker/3dTracker.htm}{http://opencvlibrary.sourceforge.net/../appPage/3dTracker/3dTracker.htm}
|
||||
|
||||
\href{http://opencvlibrary.sourceforge.net/../appPage/3dTracker/3dTrackerTesting.htm}{http://opencvlibrary.sourceforge.net/../appPage/3dTracker/3dTrackerTesting.htm}
|
||||
|
||||
contains a description of how to test the filter on sample data.
|
||||
|
||||
\cvCPyFunc{3dTrackerCalibrateCameras} % XXX URL Formatting
|
||||
|
||||
Simultaneously determines the position and orientation of multiple cameras.
|
||||
|
||||
\cvdefC{
|
||||
CvBool cv3dTrackerCalibrateCameras(\par int num\_cameras,
|
||||
\par const Cv3dTrackerCameraIntrinsics camera\_intrinsics[],
|
||||
\par CvSize checkerboard\_size,
|
||||
\par IplImage *samples[],
|
||||
\par Cv3dTrackerCameraInfo camera\_info[]);
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{num\_cameras}{the number of cameras to calibrate. This is the size of each of the three array parameters.}
|
||||
\cvarg{camera\_intrinsics}{camera intrinsics for each camera, as determined by \cross{CalibFilter}.}
|
||||
\cvarg{checkerboard\_size}{the width and height (in number of squares) of the checkerboard.}
|
||||
\cvarg{samples}{images from each camera, with a view of the checkerboard.}
|
||||
\cvarg{camera\_info}{filled in with the results of the camera calibration. This is passed into \cross{3dTrackerLocateObjects} to do tracking.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cv3dTrackerCalibrateCameras} searches for a checkerboard of the specified size in each of the images. For each image in which it finds the checkerboard, it fills in the corresponding slot in \texttt{camera\_info} with the position and orientation of the camera relative to the checkerboard and sets the \texttt{valid} flag. If it finds the checkerboard in all the images, it returns true; otherwise it returns false.
|
||||
|
||||
This function does not change the members of the \texttt{camera\_info} array that correspond to images in which the checkerboard was not found. This allows you to calibrate each camera independently, instead of simultaneously. To accomplish this, do the following:
|
||||
\begin{enumerate}
|
||||
\item Clear all the \texttt{valid} flags before calling this function the first time;
|
||||
\item Call this function with each set of images;
|
||||
\item Check all the \texttt{valid} flags after each call. When all the \texttt{valid} flags are set, calibration is complete.
|
||||
\end{enumerate}
|
||||
|
||||
Note that this method works well only if the checkerboard is rigidly mounted; if it is handheld, all the cameras should be calibrated simultanously to get an accurate result. To ensure that all cameras are calibrated simultaneously, ignore the \texttt{valid} flags and use the return value to decide when calibration is complete.
|
||||
|
||||
\cvCPyFunc{3dTrackerLocateObjects}
|
||||
|
||||
Determines the 3d location of tracked objects.
|
||||
|
||||
\cvdefC{
|
||||
int cv3dTrackerLocateObjects(\par int num\_cameras,
|
||||
\par int num\_objects,
|
||||
\par const Cv3dTrackerCameraInfo camera\_info[],
|
||||
\par const Cv3dTracker2dTrackedObject tracking\_info[],
|
||||
\par Cv3dTrackerTrackedObject tracked\_objects[]);
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{num\_cameras}{the number of cameras.}
|
||||
\cvarg{num\_objects}{the maximum number of objects found by any camera. (Also the maximum number of objects returned in \texttt{tracked\_objects}.}
|
||||
\cvarg{camera\_info}{camera position and location information for each camera, as determined by \newline \cross{3dTrackerCalibrateCameras}.}
|
||||
\cvarg{tracking\_info}{the 2d position of each object as seen by each camera. Although this is specified as a one-dimensional array, it is actually a two-dimensional array: \texttt{const \newline Cv3dTracker2dTrackedObject tracking\_info[num\_cameras][num\_objects]}. The \texttt{id} field of any unused slots must be -1. Ids need not be ordered or consecutive.}
|
||||
\cvarg{tracked\_objects}{filled in with the results.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cv3dTrackerLocateObjects} determines the 3d position of tracked objects based on the 2d tracking information from multiple cameras and the camera position and orientation information computed by \cross{3dTrackerCalibrateCameras}. It locates any objects with the same \texttt{id} that are tracked by more than one camera. It fills in the \texttt{tracked\_objects} array and returns the number of objects located. The \texttt{id} fields of any unused slots in \texttt{tracked\_objects} are set to -1.
|
||||
|
||||
\section{Eigen Objects (PCA) Functions}
|
||||
|
||||
The functions described in this section do PCA analysis
|
||||
and compression for a set of 8-bit images that may not fit
|
||||
into memory all together. If your data fits into memory and
|
||||
the vectors are not 8-bit (or you want a simpler interface), use
|
||||
\cross{CalcCovarMatrix},
|
||||
\cross{SVD}
|
||||
and
|
||||
\cross{GEMM}
|
||||
to do PCA.
|
||||
|
||||
\cvCPyFunc{CalcCovarMatrixEx}
|
||||
|
||||
Calculates the covariance matrix for a group of input objects.
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcCovarMatrixEx( \par int object\_count, \par void* input, \par int io\_flags,
|
||||
\par int iobuf\_size, \par uchar* buffer, \par void* userdata,
|
||||
\par IplImage* avg, \par float* covar\_matrix );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{object\_count}{Number of source objects.}
|
||||
\cvarg{input}{Pointer either to the array of \texttt{IplImage} input objects or to the read callback function according to the value of the parameter \texttt{ioFlags}.}
|
||||
\cvarg{io\_flags}{Input/output flags.}
|
||||
\cvarg{iobuf\_size}{Input/output buffer size.}
|
||||
\cvarg{buffer}{Pointer to the input/output buffer.}
|
||||
\cvarg{userdata}{Pointer to the structure that contains all necessary data for the callback functions.}
|
||||
\cvarg{avg}{Averaged object.}
|
||||
\cvarg{covar\_matrix}{Covariance matrix. An output parameter; must be allocated before the call.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvCalcCovarMatrixEx} calculates a covariance matrix of the input objects group using a previously calculated averaged object. Depending on the \texttt{ioFlags} parameter it may be used either in direct access or callback mode. If \texttt{ioFlags} is not \texttt{CV\_EIGOBJ\_NO\_CALLBACK}, the buffer must be allocated before calling the function.
|
||||
|
||||
\cvCPyFunc{CalcEigenObjects}
|
||||
|
||||
Calculates the orthonormal eigen basis and the averaged object for group a of input objects.
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcEigenObjects( \par int nObjects, \par void* input, \par void* output, \par int ioFlags,
|
||||
\par int ioBufSize, \par void* userData, \par CvTermCriteria* calcLimit,
|
||||
\par IplImage* avg, \par float* eigVals );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{nObjects}{Number of source objects.}
|
||||
\cvarg{input}{Pointer either to the array of \texttt{IplImage} input objects or to the read callback function according to the value of the parameter \texttt{ioFlags}.}
|
||||
\cvarg{output}{Pointer either to the array of eigen objects or to the write callback function according to the value of the parameter ioFlags.}
|
||||
\cvarg{ioFlags}{Input/output flags.}
|
||||
\cvarg{ioBufSize}{Input/output buffer size in bytes. The size is zero if unknown.}
|
||||
\cvarg{userData}{Pointer to the structure that contains all of the necessary data for the callback functions.}
|
||||
\cvarg{calcLimit}{Criteria that determine when to stop the calculation of eigen objects.}
|
||||
\cvarg{avg}{Averaged object.}
|
||||
\cvarg{eigVals}{Pointer to the eigenvalues array in the descending order; may be \texttt{NULL}.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvCalcEigenObjects} calculates the orthonormal eigen basis and the averaged object for a group of input objects. Depending on the \texttt{ioFlags} parameter it may be used either in direct access or callback mode. Depending on the parameter \texttt{calcLimit}, calculations are finished either after the first \texttt{calcLimit.max\_iter} dominating eigen objects are retrieved or if the ratio of the current eigenvalue to the largest eigenvalue comes down to the \texttt{calcLimit.epsilon} threshold. The value \texttt{calcLimit -> type} must be \texttt{CV\_TERMCRIT\_NUMB, CV\_TERMCRIT\_EPS}, or \texttt{CV\_TERMCRIT\_NUMB | CV\_TERMCRIT\_EPS} . The function returns the real values \texttt{calcLimit->max\_iter} and \texttt{calcLimit->epsilon} .
|
||||
|
||||
The function also calculates the averaged object, which must be created previously. Calculated eigen objects are arranged according to the corresponding eigenvalues in descending order.
|
||||
|
||||
The parameter \texttt{eigVals} may be equal to \texttt{NULL} if eigenvalues are not needed.
|
||||
|
||||
The function \texttt{cvCalcEigenObjects} uses the function \cross{cvCalcCovarMatrixEx}.
|
||||
|
||||
\cvCPyFunc{CalcDecompCoeff}
|
||||
|
||||
Calculates the decomposition coefficient of an input object.
|
||||
|
||||
\cvdefC{
|
||||
double cvCalcDecompCoeff( \par IplImage* obj, \par IplImage* eigObj, \par IplImage* avg );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{obj}{Input object.}
|
||||
\cvarg{eigObj}{Eigen object.}
|
||||
\cvarg{avg}{Averaged object.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvCalcDecompCoeff} calculates one decomposition coefficient of the input object using the previously calculated eigen object and the averaged object.
|
||||
|
||||
\cvCPyFunc{EigenDecomposite}
|
||||
|
||||
Calculates all of the decomposition coefficients for an input object.
|
||||
|
||||
\cvdefC{
|
||||
void cvEigenDecomposite( \par IplImage* obj, \par int eigenvec\_count, \par void* eigInput,
|
||||
\par int ioFlags, \par void* userData, \par IplImage* avg, \par float* coeffs );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{obj}{Input object.}
|
||||
\cvarg{eigenvec\_count}{Number of eigen objects.}
|
||||
\cvarg{eigInput}{Pointer either to the array of \texttt{IplImage} input objects or to the read callback function according to the value of the parameter \texttt{ioFlags}.}
|
||||
\cvarg{ioFlags}{Input/output flags.}
|
||||
\cvarg{userData}{Pointer to the structure that contains all of the necessary data for the callback functions.}
|
||||
\cvarg{avg}{Averaged object.}
|
||||
\cvarg{coeffs}{Calculated coefficients; an output parameter.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvEigenDecomposite} calculates all of the decomposition coefficients for the input object using the previously calculated eigen objects basis and the averaged object. Depending on the \texttt{ioFlags} parameter it may be used either in direct access or callback mode.
|
||||
|
||||
\cvCPyFunc{EigenProjection}
|
||||
|
||||
Calculates the object projection into the eigen sub-space.
|
||||
|
||||
\cvdefC{
|
||||
void cvEigenProjection( \par void* input\_vecs, \par int eigenvec\_count, \par int io\_flags, \par void* userdata,
|
||||
\par float* coeffs, \par IplImage* avg, \par IplImage* proj );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{input\_vec}{Pointer to either an array of \texttt{IplImage} input objects or to a callback function, depending on \texttt{io\_flags}.}
|
||||
\cvarg{eigenvec\_count}{Number of eigenvectors.}
|
||||
\cvarg{io\_flags}{Input/output flags; see \cross{cvCalcEigenObjects}.}
|
||||
\cvarg{userdata}{Pointer to the structure that contains all of the necessary data for the callback functions.}
|
||||
\cvarg{coeffs}{Previously calculated decomposition coefficients.}
|
||||
\cvarg{avg}{Average vector, calculated by \cross{cvCalcEigenObjects}.}
|
||||
\cvarg{proj}{Projection to the eigen sub-space.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvEigenProjection} calculates an object projection to the eigen sub-space or, in other words, restores an object using previously calculated eigen objects basis, averaged object, and the decomposition coefficients of the restored object. Depending on the \texttt{io\_flags} parameter it may be used either in direct access or callback mode.
|
||||
|
||||
\````````````section{Embedded Hidden Markov Models Functions}
|
||||
|
||||
In order to support embedded models, the user must define structures to represent a 1D HMM and a 2D embedded HMM model.
|
||||
|
||||
\cvCPyFunc{CvHMM}
|
||||
|
||||
Embedded HMM Structure.
|
||||
|
||||
\cvdefC{typedef struct \_CvEHMM}
|
||||
\begin{lstlisting}
|
||||
{
|
||||
int level;
|
||||
int num_states;
|
||||
float* transP;
|
||||
float** obsProb;
|
||||
union
|
||||
{
|
||||
CvEHMMState* state;
|
||||
struct _CvEHMM* ehmm;
|
||||
} u;
|
||||
} CvEHMM;
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\begin{description}
|
||||
\cvarg{level}{Level of embedded HMM. If \texttt{level ==0}, HMM is mostly external. In 2D HMM there are two types of HMM: 1 external and several embedded. External HMM has \texttt{level ==1}, embedded HMMs have \texttt{level ==0}.}
|
||||
\cvarg{num\_states}{Number of states in 1D HMM.}
|
||||
\cvarg{transP}{State-to-state transition probability, square matrix \texttt{(num\_state×num\_state )}.}
|
||||
\cvarg{obsProb}{Observation probability matrix.}
|
||||
\cvarg{state}{Array of HMM states. For the last-level HMM, that is, an HMM without embedded HMMs, HMM states are real.}
|
||||
\cvarg{ehmm}{Array of embedded HMMs. If HMM is not last-level, then HMM states are not real and they are HMMs.}
|
||||
\end{description}
|
||||
|
||||
For representation of observations the following structure is defined:
|
||||
|
||||
\cvCPyFunc{CvImgObsInfo}
|
||||
|
||||
Image Observation Structure.
|
||||
|
||||
\cvdefC{
|
||||
typedef struct CvImgObsInfo
|
||||
}
|
||||
\begin{lstlisting}
|
||||
{
|
||||
int obs_x;
|
||||
int obs_y;
|
||||
int obs_size;
|
||||
float** obs;
|
||||
int* state;
|
||||
int* mix;
|
||||
} CvImgObsInfo;
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{obs\_x}{Number of observations in the horizontal direction.}
|
||||
\cvarg{obs\_y}{Number of observations in the vertical direction.}
|
||||
\cvarg{obs\_size}{Length of each observation vector.}
|
||||
\cvarg{obs}{Pointer to the observation vectors stored consequently. Number of vectors is \texttt{obs\_x*obs\_y}.}
|
||||
\cvarg{state}{Array of indices of states, assigned to every observation vector.}
|
||||
\cvarg{mix}{Index of mixture component, corresponding to the observation vector within an assigned state.}
|
||||
\end{description}
|
||||
|
||||
\cvCPyFunc{Create2DHMM}
|
||||
|
||||
Creates a 2D, embedded HMM.
|
||||
|
||||
\cvdefC{
|
||||
CvEHMM* cvCreate2DHMM( int* stateNumber, int* numMix, int obsSize );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{stateNumber}{Array, the first element of which specifies the number of superstates in the HMM. All of the subsequent elements specify the number of states in every embedded HMM, corresponding to each superstate. So, the length of the array is \texttt{stateNumber [0]+1}.}
|
||||
\cvarg{numMix}{Array with numbers of Gaussian mixture components for each internal state. The number of elements in the array is equal to number of internal states in the HMM, that is, superstates are not counted here.}
|
||||
\cvarg{obsSize}{Size of the observation vectors to be used with created HMM.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvCreate2DHMM} returns the created structure of the type \cross{CvEHMM} with the specified parameters.
|
||||
|
||||
\cvCPyFunc{Release2DHMM}
|
||||
|
||||
Releases a 2D, embedded HMM.
|
||||
|
||||
\cvdefC{
|
||||
void cvRelease2DHMM(CvEHMM** hmm );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hmm}{Address of the pointer to the HMM to be released.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvRelease2DHMM} frees all the memory used by the HMM and clears the pointer to the HMM.
|
||||
|
||||
\cvCPyFunc{CreateObsInfo}
|
||||
|
||||
Creates a structure to store image observation vectors.
|
||||
|
||||
\cvdefC{
|
||||
CvImgObsInfo* cvCreateObsInfo( CvSize numObs, int obsSize );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{numObs}{Numbers of observations in the horizontal and vertical directions. For the given image and scheme of extracting observations the parameter can be computed via the macro \texttt{CV\_COUNT\_OBS( roi, dctSize, delta, numObs )}, where \texttt{roi, dctSize, delta, numObs} are the pointers to structures of the type \cross{CvSize}. The pointer \texttt{roi} means the size of \texttt{roi} of the image observed, \texttt{numObs} is the output parameter of the macro.}
|
||||
\cvarg{obsSize}{Size of the observation vectors to be stored in the structure.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvCreateObsInfo} creates new structures to store image observation vectors. For definitions of the parameters \texttt{roi, dctSize}, and \texttt{delta} see the specification of the function \texttt{cvImgToObs\_DCT}.
|
||||
|
||||
\cvCPyFunc{ReleaseObsInfo}
|
||||
|
||||
Releases the observation vector structures.
|
||||
|
||||
\cvdefC{
|
||||
void cvReleaseObsInfo( CvImgObsInfo** obsInfo );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{obsInfo}{Address of the pointer to the structure \cross{CvImgObsInfo}.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvReleaseObsInfo} frees all of the memory used by the observations and clears the pointer to the structure \cross{CvImgObsInfo}.
|
||||
|
||||
\cvCPyFunc{ImgToObs\_DCT}
|
||||
|
||||
Extracts observation vectors from an image.
|
||||
|
||||
\cvdefC{
|
||||
void cvImgToObs\_DCT( \par IplImage* image, \par float* obs, \par CvSize dctSize,
|
||||
\par CvSize obsSize, \par CvSize delta );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Input image.}
|
||||
\cvarg{obs}{Pointer to the consequently stored observation vectors.}
|
||||
\cvarg{dctSize}{Size of the image blocks for which the DCT (Discrete Cosine Transform) coefficients are to be computed.}
|
||||
\cvarg{obsSize}{Number of the lowest DCT coefficients in the horizontal and vertical directions to be put into the observation vector.}
|
||||
\cvarg{delta}{Shift in pixels between two consecutive image blocks in the horizontal and vertical directions.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvImgToObs\_DCT} extracts observation vectors, that is, DCT coefficients, from the image. The user must pass \texttt{obsInfo.obs} as the parameter \texttt{obs} to use this function with other HMM functions and use the structure \texttt{obsInfo} of the \cross{CvImgObsInfo} type.
|
||||
|
||||
|
||||
\texttt{Calculating Observations for HMM}
|
||||
|
||||
\cvdefC{
|
||||
CvImgObsInfo* obs\_info;
|
||||
|
||||
...
|
||||
|
||||
cvImgToObs\_DCT( image,obs\_info->obs, //!!!
|
||||
|
||||
dctSize, obsSize, delta );
|
||||
|
||||
}
|
||||
|
||||
\cvCPyFunc{UniformImgSegm}
|
||||
|
||||
Performs uniform segmentation of image observations using HMM states.
|
||||
|
||||
\cvdefC{
|
||||
void cvUniformImgSegm( CvImgObsInfo* obsInfo, CvEHMM* hmm );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{obsInfo}{Observation structures.}
|
||||
\cvarg{hmm}{HMM structure.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvUniformImgSegm} segments image observations using HMM states uniformly (see \textcolor{blue}{\underline{Initial Segmentation}} for 2D Embedded HMM for 2D embedded HMM with 5 superstates and 3, 6, 6, 6, 3 internal states of every corresponding superstate).
|
||||
|
||||
\textcolor{blue}{Initial Segmentation for 2D Embedded HMM}
|
||||
|
||||
\includegraphics{pics/face.png}
|
||||
|
||||
\cvCPyFunc{InitMixSegm}
|
||||
|
||||
Segments all observations within every internal state of HMM using state mixture components.
|
||||
|
||||
\cvdefC{
|
||||
void cvInitMixSegm( \par CvImgObsInfo** obsInfoArray, \par int numImg, \par CvEHMM* hmm );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{obsInfoArray}{Array of pointers to the observation structures.}
|
||||
\cvarg{numImg}{Length of the above array.}
|
||||
\cvarg{hmm}{HMM.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvInitMixSegm} takes a group of observations from several training images already segmented by states and splits a set of observation vectors within every internal HMM state into as many clusters as the number of mixture components in the state.
|
||||
|
||||
\cvCPyFunc{EstimateHMMStateParams}
|
||||
|
||||
Estimates all of the parameters of every HMM state.
|
||||
|
||||
\cvdefC{
|
||||
void cvEstimateHMMStateParams( \par CvImgObsInfo** obsInfoArray, \par int numImg, \par CvEHMM* hmm );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{obsInfoArray}{Array of pointers to the observation structures.}
|
||||
\cvarg{numImg}{Length of the array.}
|
||||
\cvarg{hmm}{HMM.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvEstimateHMMStateParams} computes all inner parameters of every HMM state, including Gaussian means, variances, and so forth.
|
||||
|
||||
\cvCPyFunc{EstimateTransProb}
|
||||
|
||||
Computes transition probability matrices for the embedded HMM.
|
||||
|
||||
\cvdefC{
|
||||
void cvEstimateTransProb( \par CvImgObsInfo** obsInfoArray, \par int numImg, \par CvEHMM* hmm );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{obsInfoArray}{Array of pointers to the observation structures.}
|
||||
\cvarg{numImg}{Length of the above array.}
|
||||
\cvarg{hmm}{HMM.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvEstimateTransProb} uses the current segmentation of image observations to compute the transition probability matrices for all embedded and external HMMs.
|
||||
|
||||
\cvCPyFunc{EstimateObsProb}
|
||||
|
||||
Computes the probability of every observation of several images.
|
||||
|
||||
\cvdefC{
|
||||
void cvEstimateObsProb( CvImgObsInfo* obsInfo, CvEHMM* hmm );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{obsInfo}{Observation structure.}
|
||||
\cvarg{hmm}{HMM structure.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvEstimateObsProb} computes the Gaussian probabilities of each observation to occur in each of the internal HMM states.
|
||||
|
||||
\cvCPyFunc{EViterbi}
|
||||
|
||||
Executes the Viterbi algorithm for the embedded HMM.
|
||||
|
||||
\cvdefC{
|
||||
float cvEViterbi( CvImgObsInfo* obsInfo, CvEHMM* hmm );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{obsInfo}{Observation structure.
|
||||
}\cvarg{hmm}{HMM structure.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvEViterbi} executes the Viterbi algorithm for the embedded HMM. The Viterbi algorithm evaluates the likelihood of the best match between the given image observations and the given HMM and performs segmentation of image observations by HMM states. The segmentation is done on the basis of the match found.
|
||||
|
||||
\cvCPyFunc{MixSegmL2}
|
||||
|
||||
Segments the observations from all of the training images using the mixture components of the newly assigned states.
|
||||
|
||||
\cvdefC{
|
||||
void cvMixSegmL2( \par CvImgObsInfo** obsInfoArray, \par int numImg, \par CvEHMM* hmm );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{obsInfoArray}{Array of pointers to the observation structures.}
|
||||
\cvarg{numImg}{Length of the array.}
|
||||
\cvarg{hmm}{HMM.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvMixSegmL2} segments the observations from all of the training images using the mixture components of the newly Viterbi algorithm-assigned states. The function uses the Euclidean distance to group vectors around the existing mixtures centers.
|
||||
|
||||
\fi
|
1835
doc/calib3d.tex
1835
doc/calib3d.tex
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,291 +0,0 @@
|
||||
\section{Clustering}
|
||||
|
||||
\ifCPy
|
||||
|
||||
\cvCPyFunc{KMeans2}
|
||||
Splits set of vectors by a given number of clusters.
|
||||
|
||||
\cvdefC{int cvKMeans2(const CvArr* samples, int nclusters,\par
|
||||
CvArr* labels, CvTermCriteria termcrit,\par
|
||||
int attempts=1, CvRNG* rng=0, \par
|
||||
int flags=0, CvArr* centers=0,\par
|
||||
double* compactness=0);}
|
||||
\cvdefPy{KMeans2(samples,nclusters,labels,termcrit)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{samples}{Floating-point matrix of input samples, one row per sample}
|
||||
\cvarg{nclusters}{Number of clusters to split the set by}
|
||||
\cvarg{labels}{Output integer vector storing cluster indices for every sample}
|
||||
\cvarg{termcrit}{Specifies maximum number of iterations and/or accuracy (distance the centers can move by between subsequent iterations)}
|
||||
\ifC
|
||||
\cvarg{attempts}{How many times the algorithm is executed using different initial labelings. The algorithm returns labels that yield the best compactness (see the last function parameter)}
|
||||
\cvarg{rng}{Optional external random number generator; can be used to fully control the function behaviour}
|
||||
\cvarg{flags}{Can be 0 or \texttt{CV\_KMEANS\_USE\_INITIAL\_LABELS}. The latter
|
||||
value means that during the first (and possibly the only) attempt, the
|
||||
function uses the user-supplied labels as the initial approximation
|
||||
instead of generating random labels. For the second and further attempts,
|
||||
the function will use randomly generated labels in any case}
|
||||
\cvarg{centers}{The optional output array of the cluster centers}
|
||||
\cvarg{compactness}{The optional output parameter, which is computed as
|
||||
$\sum_i ||\texttt{samples}_i - \texttt{centers}_{\texttt{labels}_i}||^2$
|
||||
after every attempt; the best (minimum) value is chosen and the
|
||||
corresponding labels are returned by the function. Basically, the
|
||||
user can use only the core of the function, set the number of
|
||||
attempts to 1, initialize labels each time using a custom algorithm
|
||||
(\texttt{flags=CV\_KMEAN\_USE\_INITIAL\_LABELS}) and, based on the output compactness
|
||||
or any other criteria, choose the best clustering.}
|
||||
\fi
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvKMeans2} implements a k-means algorithm that finds the
|
||||
centers of \texttt{nclusters} clusters and groups the input samples
|
||||
around the clusters. On output, $\texttt{labels}_i$ contains a cluster index for
|
||||
samples stored in the i-th row of the \texttt{samples} matrix.
|
||||
|
||||
\ifC
|
||||
% Example: Clustering random samples of multi-gaussian distribution with k-means
|
||||
\begin{lstlisting}
|
||||
#include "cxcore.h"
|
||||
#include "highgui.h"
|
||||
|
||||
void main( int argc, char** argv )
|
||||
{
|
||||
#define MAX_CLUSTERS 5
|
||||
CvScalar color_tab[MAX_CLUSTERS];
|
||||
IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
|
||||
CvRNG rng = cvRNG(0xffffffff);
|
||||
|
||||
color_tab[0] = CV_RGB(255,0,0);
|
||||
color_tab[1] = CV_RGB(0,255,0);
|
||||
color_tab[2] = CV_RGB(100,100,255);
|
||||
color_tab[3] = CV_RGB(255,0,255);
|
||||
color_tab[4] = CV_RGB(255,255,0);
|
||||
|
||||
cvNamedWindow( "clusters", 1 );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int k, cluster_count = cvRandInt(&rng)%MAX_CLUSTERS + 1;
|
||||
int i, sample_count = cvRandInt(&rng)%1000 + 1;
|
||||
CvMat* points = cvCreateMat( sample_count, 1, CV_32FC2 );
|
||||
CvMat* clusters = cvCreateMat( sample_count, 1, CV_32SC1 );
|
||||
|
||||
/* generate random sample from multigaussian distribution */
|
||||
for( k = 0; k < cluster_count; k++ )
|
||||
{
|
||||
CvPoint center;
|
||||
CvMat point_chunk;
|
||||
center.x = cvRandInt(&rng)%img->width;
|
||||
center.y = cvRandInt(&rng)%img->height;
|
||||
cvGetRows( points,
|
||||
&point_chunk,
|
||||
k*sample_count/cluster_count,
|
||||
(k == (cluster_count - 1)) ?
|
||||
sample_count :
|
||||
(k+1)*sample_count/cluster_count );
|
||||
cvRandArr( &rng, &point_chunk, CV_RAND_NORMAL,
|
||||
cvScalar(center.x,center.y,0,0),
|
||||
cvScalar(img->width/6, img->height/6,0,0) );
|
||||
}
|
||||
|
||||
/* shuffle samples */
|
||||
for( i = 0; i < sample_count/2; i++ )
|
||||
{
|
||||
CvPoint2D32f* pt1 =
|
||||
(CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
|
||||
CvPoint2D32f* pt2 =
|
||||
(CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
|
||||
CvPoint2D32f temp;
|
||||
CV_SWAP( *pt1, *pt2, temp );
|
||||
}
|
||||
|
||||
cvKMeans2( points, cluster_count, clusters,
|
||||
cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ));
|
||||
|
||||
cvZero( img );
|
||||
|
||||
for( i = 0; i < sample_count; i++ )
|
||||
{
|
||||
CvPoint2D32f pt = ((CvPoint2D32f*)points->data.fl)[i];
|
||||
int cluster_idx = clusters->data.i[i];
|
||||
cvCircle( img,
|
||||
cvPointFrom32f(pt),
|
||||
2,
|
||||
color_tab[cluster_idx],
|
||||
CV_FILLED );
|
||||
}
|
||||
|
||||
cvReleaseMat( &points );
|
||||
cvReleaseMat( &clusters );
|
||||
|
||||
cvShowImage( "clusters", img );
|
||||
|
||||
int key = cvWaitKey(0);
|
||||
if( key == 27 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCPyFunc{SeqPartition}
|
||||
Splits a sequence into equivalency classes.
|
||||
|
||||
\cvdefC{
|
||||
int cvSeqPartition( \par const CvSeq* seq,\par CvMemStorage* storage,\par CvSeq** labels,\par CvCmpFunc is\_equal,\par void* userdata );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{seq}{The sequence to partition}
|
||||
\cvarg{storage}{The storage block to store the sequence of equivalency classes. If it is NULL, the function uses \texttt{seq->storage} for output labels}
|
||||
\cvarg{labels}{Ouput parameter. Double pointer to the sequence of 0-based labels of input sequence elements}
|
||||
\cvarg{is\_equal}{The relation function that should return non-zero if the two particular sequence elements are from the same class, and zero otherwise. The partitioning algorithm uses transitive closure of the relation function as an equivalency critria}
|
||||
\cvarg{userdata}{Pointer that is transparently passed to the \texttt{is\_equal} function}
|
||||
\end{description}
|
||||
|
||||
\begin{lstlisting}
|
||||
typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata);
|
||||
\end{lstlisting}
|
||||
|
||||
The function \texttt{cvSeqPartition} implements a quadratic algorithm for
|
||||
splitting a set into one or more equivalancy classes. The function
|
||||
returns the number of equivalency classes.
|
||||
|
||||
% Example: Partitioning a 2d point set
|
||||
\begin{lstlisting}
|
||||
|
||||
#include "cxcore.h"
|
||||
#include "highgui.h"
|
||||
#include <stdio.h>
|
||||
|
||||
CvSeq* point_seq = 0;
|
||||
IplImage* canvas = 0;
|
||||
CvScalar* colors = 0;
|
||||
int pos = 10;
|
||||
|
||||
int is_equal( const void* _a, const void* _b, void* userdata )
|
||||
{
|
||||
CvPoint a = *(const CvPoint*)_a;
|
||||
CvPoint b = *(const CvPoint*)_b;
|
||||
double threshold = *(double*)userdata;
|
||||
return (double)((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)) <=
|
||||
threshold;
|
||||
}
|
||||
|
||||
void on_track( int pos )
|
||||
{
|
||||
CvSeq* labels = 0;
|
||||
double threshold = pos*pos;
|
||||
int i, class_count = cvSeqPartition( point_seq,
|
||||
0,
|
||||
&labels,
|
||||
is_equal,
|
||||
&threshold );
|
||||
printf("%4d classes\n", class_count );
|
||||
cvZero( canvas );
|
||||
|
||||
for( i = 0; i < labels->total; i++ )
|
||||
{
|
||||
CvPoint pt = *(CvPoint*)cvGetSeqElem( point_seq, i );
|
||||
CvScalar color = colors[*(int*)cvGetSeqElem( labels, i )];
|
||||
cvCircle( canvas, pt, 1, color, -1 );
|
||||
}
|
||||
|
||||
cvShowImage( "points", canvas );
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
point_seq = cvCreateSeq( CV_32SC2,
|
||||
sizeof(CvSeq),
|
||||
sizeof(CvPoint),
|
||||
storage );
|
||||
CvRNG rng = cvRNG(0xffffffff);
|
||||
|
||||
int width = 500, height = 500;
|
||||
int i, count = 1000;
|
||||
canvas = cvCreateImage( cvSize(width,height), 8, 3 );
|
||||
|
||||
colors = (CvScalar*)cvAlloc( count*sizeof(colors[0]) );
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
CvPoint pt;
|
||||
int icolor;
|
||||
pt.x = cvRandInt( &rng ) % width;
|
||||
pt.y = cvRandInt( &rng ) % height;
|
||||
cvSeqPush( point_seq, &pt );
|
||||
icolor = cvRandInt( &rng ) | 0x00404040;
|
||||
colors[i] = CV_RGB(icolor & 255,
|
||||
(icolor >> 8)&255,
|
||||
(icolor >> 16)&255);
|
||||
}
|
||||
|
||||
cvNamedWindow( "points", 1 );
|
||||
cvCreateTrackbar( "threshold", "points", &pos, 50, on_track );
|
||||
on_track(pos);
|
||||
cvWaitKey(0);
|
||||
return 0;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\fi
|
||||
|
||||
\fi
|
||||
|
||||
\ifCpp
|
||||
|
||||
\cvCppFunc{kmeans}
|
||||
Finds the centers of clusters and groups the input samples around the clusters.
|
||||
\cvdefCpp{double kmeans( const Mat\& samples, int clusterCount, Mat\& labels,\par
|
||||
TermCriteria termcrit, int attempts,\par
|
||||
int flags, Mat* centers );}
|
||||
\begin{description}
|
||||
\cvarg{samples}{Floating-point matrix of input samples, one row per sample}
|
||||
\cvarg{clusterCount}{The number of clusters to split the set by}
|
||||
\cvarg{labels}{The input/output integer array that will store the cluster indices for every sample}
|
||||
\cvarg{termcrit}{Specifies maximum number of iterations and/or accuracy (distance the centers can move by between subsequent iterations)}
|
||||
|
||||
\cvarg{attempts}{How many times the algorithm is executed using different initial labelings. The algorithm returns the labels that yield the best compactness (see the last function parameter)}
|
||||
\cvarg{flags}{It can take the following values:
|
||||
\begin{description}
|
||||
\cvarg{KMEANS\_RANDOM\_CENTERS}{Random initial centers are selected in each attempt}
|
||||
\cvarg{KMEANS\_PP\_CENTERS}{Use kmeans++ center initialization by Arthur and Vassilvitskii}
|
||||
\cvarg{KMEANS\_USE\_INITIAL\_LABELS}{During the first (and possibly the only) attempt, the
|
||||
function uses the user-supplied labels instaed of computing them from the initial centers. For the second and further attempts, the function will use the random or semi-random centers (use one of \texttt{KMEANS\_*\_CENTERS} flag to specify the exact method)}
|
||||
\end{description}}
|
||||
\cvarg{centers}{The output matrix of the cluster centers, one row per each cluster center}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{kmeans} implements a k-means algorithm that finds the
|
||||
centers of \texttt{clusterCount} clusters and groups the input samples
|
||||
around the clusters. On output, $\texttt{labels}_i$ contains a 0-based cluster index for
|
||||
the sample stored in the $i^{th}$ row of the \texttt{samples} matrix.
|
||||
|
||||
The function returns the compactness measure, which is computed as
|
||||
\[
|
||||
\sum_i \|\texttt{samples}_i - \texttt{centers}_{\texttt{labels}_i}\|^2
|
||||
\]
|
||||
after every attempt; the best (minimum) value is chosen and the
|
||||
corresponding labels and the compactness value are returned by the function.
|
||||
Basically, the user can use only the core of the function, set the number of
|
||||
attempts to 1, initialize labels each time using some custom algorithm and pass them with
|
||||
\par (\texttt{flags}=\texttt{KMEANS\_USE\_INITIAL\_LABELS}) flag, and then choose the best (most-compact) clustering.
|
||||
|
||||
\cvCppFunc{partition}
|
||||
Splits an element set into equivalency classes.
|
||||
|
||||
\cvdefCpp{template<typename \_Tp, class \_EqPredicate> int\newline
|
||||
partition( const vector<\_Tp>\& vec, vector<int>\& labels,\par
|
||||
\_EqPredicate predicate=\_EqPredicate());}
|
||||
\begin{description}
|
||||
\cvarg{vec}{The set of elements stored as a vector}
|
||||
\cvarg{labels}{The output vector of labels; will contain as many elements as \texttt{vec}. Each label \texttt{labels[i]} is 0-based cluster index of \texttt{vec[i]}}
|
||||
\cvarg{predicate}{The equivalence predicate (i.e. pointer to a boolean function of two arguments or an instance of the class that has the method \texttt{bool operator()(const \_Tp\& a, const \_Tp\& b)}. The predicate returns true when the elements are certainly if the same class, and false if they may or may not be in the same class}
|
||||
\end{description}
|
||||
|
||||
The generic function \texttt{partition} implements an $O(N^2)$ algorithm for
|
||||
splitting a set of $N$ elements into one or more equivalency classes, as described in \url{http://en.wikipedia.org/wiki/Disjoint-set_data_structure}. The function
|
||||
returns the number of equivalency classes.
|
||||
|
||||
|
||||
\fi
|
@ -1,823 +0,0 @@
|
||||
\section{Drawing Functions}
|
||||
|
||||
Drawing functions work with matrices/images of arbitrary depth.
|
||||
The boundaries of the shapes can be rendered with antialiasing (implemented only for 8-bit images for now).
|
||||
All the functions include the parameter color that uses a rgb value (that may be constructed
|
||||
with \texttt{CV\_RGB} \cvC{macro or the \cvCppCross{cvScalar} function}
|
||||
\cvCpp{or the \cross{Scalar} constructor}) for color
|
||||
images and brightness for grayscale images. For color images the order channel
|
||||
is normally \emph{Blue, Green, Red}, this is what \cvCppCross{imshow}, \cvCppCross{imread} and \cvCppCross{imwrite} expect
|
||||
\ifCpp
|
||||
, so if you form a color using \cross{Scalar} constructor, it should look like:
|
||||
\[\texttt{Scalar}(blue\_component, green\_component, red\_component[, alpha\_component])\]
|
||||
\fi
|
||||
\ifC
|
||||
, so if you form a color using \cvCppCross{cvScalar}, it should look like:
|
||||
\[\texttt{cvScalar}(blue\_component, green\_component, red\_component[, alpha\_component])\]
|
||||
\fi
|
||||
|
||||
If you are using your own image rendering and I/O functions, you can use any channel ordering, the drawing functions process each channel independently and do not depend on the channel order or even on the color space used. The whole image can be converted from BGR to RGB or to a different color space using \cvCppCross{cvtColor}.
|
||||
|
||||
If a drawn figure is partially or completely outside the image, the drawing functions clip it. Also, many drawing functions can handle pixel coordinates specified with sub-pixel accuracy, that is, the coordinates can be passed as fixed-point numbers, encoded as integers. The number of fractional bits is specified by the \texttt{shift} parameter and the real point coordinates are calculated as $\texttt{Point}(x,y)\rightarrow\texttt{Point2f}(x*2^{-shift},y*2^{-shift})$. This feature is especially effective wehn rendering antialiased shapes.
|
||||
|
||||
Also, note that the functions do not support alpha-transparency - when the target image is 4-channnel, then the \texttt{color[3]} is simply copied to the repainted pixels. Thus, if you want to paint semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main image.
|
||||
|
||||
\ifCPy
|
||||
|
||||
\cvCPyFunc{Circle}
|
||||
Draws a circle.
|
||||
|
||||
\cvdefC{void cvCircle( \par CvArr* img,\par CvPoint center,\par int radius,\par CvScalar color,\par int thickness=1,\par int lineType=8,\par int shift=0 );}
|
||||
\cvdefPy{Circle(img,center,radius,color,thickness=1,lineType=8,shift=0)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Image where the circle is drawn}
|
||||
\cvarg{center}{Center of the circle}
|
||||
\cvarg{radius}{Radius of the circle}
|
||||
\cvarg{color}{Circle color}
|
||||
\cvarg{thickness}{Thickness of the circle outline if positive, otherwise this indicates that a filled circle is to be drawn}
|
||||
\cvarg{lineType}{Type of the circle boundary, see \cross{Line} description}
|
||||
\cvarg{shift}{Number of fractional bits in the center coordinates and radius value}
|
||||
\end{description}
|
||||
|
||||
The function draws a simple or filled circle with a
|
||||
given center and radius.
|
||||
|
||||
\cvCPyFunc{ClipLine}
|
||||
Clips the line against the image rectangle.
|
||||
|
||||
\cvdefC{int cvClipLine( \par CvSize imgSize,\par CvPoint* pt1,\par CvPoint* pt2 );}
|
||||
\cvdefPy{ClipLine(imgSize, pt1, pt2) -> (clipped\_pt1, clipped\_pt2)}
|
||||
\begin{description}
|
||||
\cvarg{imgSize}{Size of the image}
|
||||
\cvarg{pt1}{First ending point of the line segment. \cvC{It is modified by the function.}}
|
||||
\cvarg{pt2}{Second ending point of the line segment. \cvC{It is modified by the function.}}
|
||||
\end{description}
|
||||
|
||||
The function calculates a part of the line segment which is entirely within the image.
|
||||
\cvC{It returns 0 if the line segment is completely outside the image and 1 otherwise.}
|
||||
\cvPy{If the line segment is outside the image, it returns None. If the line segment is inside the image it returns a new pair of points.}
|
||||
|
||||
\cvCPyFunc{DrawContours}
|
||||
Draws contour outlines or interiors in an image.
|
||||
|
||||
\cvdefC{
|
||||
void cvDrawContours( \par CvArr *img,\par CvSeq* contour,\par CvScalar external\_color,\par CvScalar hole\_color,\par int max\_level,\par int thickness=1,\par int lineType=8 );
|
||||
}
|
||||
\cvdefPy{DrawContours(img,contour,external\_color,hole\_color,max\_level,thickness=1,lineType=8,offset=(0,0))-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Image where the contours are to be drawn. As with any other drawing function, the contours are clipped with the ROI.}
|
||||
\cvarg{contour}{Pointer to the first contour}
|
||||
\cvarg{external\_color}{Color of the external contours}
|
||||
\cvarg{hole\_color}{Color of internal contours (holes)}
|
||||
\cvarg{max\_level}{Maximal level for drawn contours. If 0, only
|
||||
\texttt{contour} is drawn. If 1, the contour and all contours following
|
||||
it on the same level are drawn. If 2, all contours following and all
|
||||
contours one level below the contours are drawn, and so forth. If the value
|
||||
is negative, the function does not draw the contours following after
|
||||
\texttt{contour} but draws the child contours of \texttt{contour} up
|
||||
to the $|\texttt{max\_level}|-1$ level.}
|
||||
\cvarg{thickness}{Thickness of lines the contours are drawn with.
|
||||
If it is negative (For example, =CV\_FILLED), the contour interiors are
|
||||
drawn.}
|
||||
\cvarg{lineType}{Type of the contour segments, see \cross{Line} description}
|
||||
\end{description}
|
||||
|
||||
The function draws contour outlines in the image if $\texttt{thickness} \ge 0$ or fills the area bounded by the contours if $ \texttt{thickness}<0$.
|
||||
|
||||
\ifC
|
||||
Example: Connected component detection via contour functions
|
||||
|
||||
\begin{lstlisting}
|
||||
#include "cv.h"
|
||||
#include "highgui.h"
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
IplImage* src;
|
||||
// the first command line parameter must be file name of binary
|
||||
// (black-n-white) image
|
||||
if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0)
|
||||
{
|
||||
IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 );
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
CvSeq* contour = 0;
|
||||
|
||||
cvThreshold( src, src, 1, 255, CV_THRESH_BINARY );
|
||||
cvNamedWindow( "Source", 1 );
|
||||
cvShowImage( "Source", src );
|
||||
|
||||
cvFindContours( src, storage, &contour, sizeof(CvContour),
|
||||
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
|
||||
cvZero( dst );
|
||||
|
||||
for( ; contour != 0; contour = contour->h_next )
|
||||
{
|
||||
CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );
|
||||
/* replace CV_FILLED with 1 to see the outlines */
|
||||
cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8 );
|
||||
}
|
||||
|
||||
cvNamedWindow( "Components", 1 );
|
||||
cvShowImage( "Components", dst );
|
||||
cvWaitKey(0);
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{Ellipse}
|
||||
Draws a simple or thick elliptic arc or an fills ellipse sector.
|
||||
|
||||
\cvdefC{void cvEllipse( \par CvArr* img,\par CvPoint center,\par CvSize axes,\par double angle,\par double start\_angle,\par double end\_angle,\par CvScalar color,\par int thickness=1,\par int lineType=8,\par int shift=0 );}
|
||||
\cvdefPy{Ellipse(img,center,axes,angle,start\_angle,end\_angle,color,thickness=1,lineType=8,shift=0)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{The image}
|
||||
\cvarg{center}{Center of the ellipse}
|
||||
\cvarg{axes}{Length of the ellipse axes}
|
||||
\cvarg{angle}{Rotation angle}
|
||||
\cvarg{start\_angle}{Starting angle of the elliptic arc}
|
||||
\cvarg{end\_angle}{Ending angle of the elliptic arc.}
|
||||
\cvarg{color}{Ellipse color}
|
||||
\cvarg{thickness}{Thickness of the ellipse arc outline if positive, otherwise this indicates that a filled ellipse sector is to be drawn}
|
||||
\cvarg{lineType}{Type of the ellipse boundary, see \cross{Line} description}
|
||||
\cvarg{shift}{Number of fractional bits in the center coordinates and axes' values}
|
||||
\end{description}
|
||||
|
||||
The function draws a simple or thick elliptic
|
||||
arc or fills an ellipse sector. The arc is clipped by the ROI rectangle.
|
||||
A piecewise-linear approximation is used for antialiased arcs and
|
||||
thick arcs. All the angles are given in degrees. The picture below
|
||||
explains the meaning of the parameters.
|
||||
|
||||
Parameters of Elliptic Arc
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/ellipse.png}
|
||||
|
||||
\cvCPyFunc{EllipseBox}
|
||||
|
||||
Draws a simple or thick elliptic arc or fills an ellipse sector.
|
||||
|
||||
\cvdefC{void cvEllipseBox( \par CvArr* img, \par CvBox2D box, \par CvScalar color,
|
||||
\par int thickness=1, \par int lineType=8, \par int shift=0 );}
|
||||
\cvdefPy{EllipseBox(img,box,color,thickness=1,lineType=8,shift=0)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Image}
|
||||
\cvarg{box}{The enclosing box of the ellipse drawn}
|
||||
\cvarg{thickness}{Thickness of the ellipse boundary}
|
||||
\cvarg{lineType}{Type of the ellipse boundary, see \cross{Line} description}
|
||||
\cvarg{shift}{Number of fractional bits in the box vertex coordinates}
|
||||
\end{description}
|
||||
|
||||
The function draws a simple or thick ellipse outline, or fills an ellipse. The functions provides a convenient way to draw an ellipse approximating some shape; that is what \cross{CamShift} and \cross{FitEllipse} do. The ellipse drawn is clipped by ROI rectangle. A piecewise-linear approximation is used for antialiased arcs and thick arcs.
|
||||
|
||||
\cvCPyFunc{FillConvexPoly}
|
||||
Fills a convex polygon.
|
||||
|
||||
\cvdefC{
|
||||
void cvFillConvexPoly( \par CvArr* img,\par CvPoint* pts,\par int npts,\par CvScalar color,\par int lineType=8,\par int shift=0 );}
|
||||
\cvdefPy{FillConvexPoly(img,pn,color,lineType=8,shift=0)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Image}
|
||||
\ifC
|
||||
\cvarg{pts}{Array of pointers to a single polygon}
|
||||
\cvarg{npts}{Polygon vertex counter}
|
||||
\else
|
||||
\cvarg{pn}{List of coordinate pairs}
|
||||
\fi
|
||||
\cvarg{color}{Polygon color}
|
||||
\cvarg{lineType}{Type of the polygon boundaries, see \cross{Line} description}
|
||||
\cvarg{shift}{Number of fractional bits in the vertex coordinates}
|
||||
\end{description}
|
||||
|
||||
The function fills a convex polygon's interior.
|
||||
This function is much faster than the function \texttt{cvFillPoly}
|
||||
and can fill not only convex polygons but any monotonic polygon,
|
||||
i.e., a polygon whose contour intersects every horizontal line (scan
|
||||
line) twice at the most.
|
||||
|
||||
|
||||
\cvCPyFunc{FillPoly}
|
||||
Fills a polygon's interior.
|
||||
|
||||
\cvdefC{
|
||||
void cvFillPoly( \par CvArr* img,\par CvPoint** pts,\par int* npts,\par int contours,\par CvScalar color,\par int lineType=8,\par int shift=0 );
|
||||
}
|
||||
\cvdefPy{FillPoly(img,polys,color,lineType=8,shift=0)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Image}
|
||||
\ifC
|
||||
\cvarg{pts}{Array of pointers to polygons}
|
||||
\cvarg{npts}{Array of polygon vertex counters}
|
||||
\cvarg{contours}{Number of contours that bind the filled region}
|
||||
\fi
|
||||
\ifPy
|
||||
\cvarg{polys}{List of lists of (x,y) pairs. Each list of points is a polygon.}
|
||||
\fi
|
||||
\cvarg{color}{Polygon color}
|
||||
\cvarg{lineType}{Type of the polygon boundaries, see \cross{Line} description}
|
||||
\cvarg{shift}{Number of fractional bits in the vertex coordinates}
|
||||
\end{description}
|
||||
|
||||
|
||||
The function fills an area bounded by several
|
||||
polygonal contours. The function fills complex areas, for example,
|
||||
areas with holes, contour self-intersection, and so forth.
|
||||
|
||||
\cvCPyFunc{GetTextSize}
|
||||
Retrieves the width and height of a text string.
|
||||
|
||||
\cvdefC{
|
||||
void cvGetTextSize( \par const char* textString,\par const CvFont* font,\par CvSize* textSize,\par int* baseline );}
|
||||
\cvdefPy{GetTextSize(textString,font)-> (textSize,baseline)}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{font}{Pointer to the font structure}
|
||||
\cvarg{textString}{Input string}
|
||||
\cvarg{textSize}{Resultant size of the text string. Height of the text does not include the height of character parts that are below the baseline.}
|
||||
\cvarg{baseline}{y-coordinate of the baseline relative to the bottom-most text point}
|
||||
\end{description}
|
||||
|
||||
The function calculates the dimensions of a rectangle to enclose a text string when a specified font is used.
|
||||
|
||||
\cvCPyFunc{InitFont}
|
||||
Initializes font structure.
|
||||
|
||||
\cvdefC{
|
||||
void cvInitFont( \par CvFont* font,\par int fontFace,\par double hscale,\par double vscale,\par double shear=0,\par int thickness=1,\par int lineType=8 );}
|
||||
\cvdefPy{InitFont(fontFace,hscale,vscale,shear=0,thickness=1,lineType=8)-> font}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{font}{Pointer to the font structure initialized by the function}
|
||||
\cvarg{fontFace}{Font name identifier. Only a subset of Hershey fonts \url{http://sources.isc.org/utils/misc/hershey-font.txt} are supported now:
|
||||
\begin{description}
|
||||
\cvarg{CV\_FONT\_HERSHEY\_SIMPLEX}{normal size sans-serif font}
|
||||
\cvarg{CV\_FONT\_HERSHEY\_PLAIN}{small size sans-serif font}
|
||||
\cvarg{CV\_FONT\_HERSHEY\_DUPLEX}{normal size sans-serif font (more complex than \par \texttt{CV\_FONT\_HERSHEY\_SIMPLEX})}
|
||||
\cvarg{CV\_FONT\_HERSHEY\_COMPLEX}{normal size serif font}
|
||||
\cvarg{CV\_FONT\_HERSHEY\_TRIPLEX}{normal size serif font (more complex than \texttt{CV\_FONT\_HERSHEY\_COMPLEX})}
|
||||
\cvarg{CV\_FONT\_HERSHEY\_COMPLEX\_SMALL}{smaller version of \texttt{CV\_FONT\_HERSHEY\_COMPLEX}}
|
||||
\cvarg{CV\_FONT\_HERSHEY\_SCRIPT\_SIMPLEX}{hand-writing style font}
|
||||
\cvarg{CV\_FONT\_HERSHEY\_SCRIPT\_COMPLEX}{more complex variant of \texttt{CV\_FONT\_HERSHEY\_SCRIPT\_SIMPLEX}}
|
||||
\end{description}
|
||||
The parameter can be composited from one of the values above and an optional \texttt{CV\_FONT\_ITALIC} flag, which indicates italic or oblique font.}
|
||||
\cvarg{hscale}{Horizontal scale. If equal to \texttt{1.0f}, the characters have the original width depending on the font type. If equal to \texttt{0.5f}, the characters are of half the original width.}
|
||||
\cvarg{vscale}{Vertical scale. If equal to \texttt{1.0f}, the characters have the original height depending on the font type. If equal to \texttt{0.5f}, the characters are of half the original height.}
|
||||
\cvarg{shear}{Approximate tangent of the character slope relative to the vertical line. A zero value means a non-italic font, \texttt{1.0f} means about a 45 degree slope, etc.}
|
||||
\cvarg{thickness}{Thickness of the text strokes}
|
||||
\cvarg{lineType}{Type of the strokes, see \cross{Line} description}
|
||||
\end{description}
|
||||
|
||||
The function initializes the font structure that can be passed to text rendering functions.
|
||||
|
||||
|
||||
\cvCPyFunc{InitLineIterator}
|
||||
Initializes the line iterator.
|
||||
|
||||
\cvdefC{
|
||||
int cvInitLineIterator( \par const CvArr* image,\par CvPoint pt1,\par CvPoint pt2,\par CvLineIterator* line\_iterator,\par int connectivity=8,\par int left\_to\_right=0 );
|
||||
}
|
||||
\cvdefPy{InitLineIterator(image, pt1, pt2, connectivity=8, left\_to\_right=0) -> line\_iterator}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Image to sample the line from}
|
||||
\cvarg{pt1}{First ending point of the line segment}
|
||||
\cvarg{pt2}{Second ending point of the line segment}
|
||||
\cvC{\cvarg{line\_iterator}{Pointer to the line iterator state structure}}
|
||||
\cvarg{connectivity}{The scanned line connectivity, 4 or 8.}
|
||||
\cvarg{left\_to\_right}{
|
||||
If ($ \texttt{left\_to\_right} = 0 $ ) then the line is scanned in the specified order, from \texttt{pt1} to \texttt{pt2}.
|
||||
If ($ \texttt{left\_to\_right} \ne 0$) the line is scanned from left-most point to right-most.}
|
||||
\cvPy{\cvarg{line\_iterator}{Iterator over the pixels of the line}}
|
||||
\end{description}
|
||||
|
||||
\ifC
|
||||
The function initializes the line
|
||||
iterator and returns the number of pixels between the two end points.
|
||||
Both points must be inside the image.
|
||||
After the iterator has been
|
||||
initialized, all the points on the raster line that connects the
|
||||
two ending points may be retrieved by successive calls of
|
||||
\texttt{CV\_NEXT\_LINE\_POINT} point.
|
||||
\fi
|
||||
\ifPy
|
||||
The function returns an iterator over the pixels connecting the two points.
|
||||
\fi
|
||||
|
||||
The points on the line are
|
||||
calculated one by one using a 4-connected or 8-connected Bresenham
|
||||
algorithm.
|
||||
|
||||
\ifPy
|
||||
Example: Using line iterator to calculate the sum of pixel values along a color line
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv
|
||||
>>> img = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_COLOR)
|
||||
>>> li = cv.InitLineIterator(img, (100, 100), (125, 150))
|
||||
>>> red_sum = 0
|
||||
>>> green_sum = 0
|
||||
>>> blue_sum = 0
|
||||
>>> for (r, g, b) in li:
|
||||
... red_sum += r
|
||||
... green_sum += g
|
||||
... blue_sum += b
|
||||
>>> print red_sum, green_sum, blue_sum
|
||||
10935.0 9496.0 7946.0
|
||||
\end{lstlisting}
|
||||
|
||||
or more concisely using \href{http://docs.python.org/library/functions.html\#zip}{zip}:
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv
|
||||
>>> img = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_COLOR)
|
||||
>>> li = cv.InitLineIterator(img, (100, 100), (125, 150))
|
||||
>>> print [sum(c) for c in zip(*li)]
|
||||
[10935.0, 9496.0, 7946.0]
|
||||
\end{lstlisting}
|
||||
\fi
|
||||
|
||||
\ifC
|
||||
Example: Using line iterator to calculate the sum of pixel values along the color line.
|
||||
|
||||
\begin{lstlisting}
|
||||
|
||||
CvScalar sum_line_pixels( IplImage* image, CvPoint pt1, CvPoint pt2 )
|
||||
{
|
||||
CvLineIterator iterator;
|
||||
int blue_sum = 0, green_sum = 0, red_sum = 0;
|
||||
int count = cvInitLineIterator( image, pt1, pt2, &iterator, 8, 0 );
|
||||
|
||||
for( int i = 0; i < count; i++ ){
|
||||
blue_sum += iterator.ptr[0];
|
||||
green_sum += iterator.ptr[1];
|
||||
red_sum += iterator.ptr[2];
|
||||
CV_NEXT_LINE_POINT(iterator);
|
||||
|
||||
/* print the pixel coordinates: demonstrates how to calculate the
|
||||
coordinates */
|
||||
{
|
||||
int offset, x, y;
|
||||
/* assume that ROI is not set, otherwise need to take it
|
||||
into account. */
|
||||
offset = iterator.ptr - (uchar*)(image->imageData);
|
||||
y = offset/image->widthStep;
|
||||
x = (offset - y*image->widthStep)/(3*sizeof(uchar)
|
||||
/* size of pixel */);
|
||||
printf("(%d,%d)\n", x, y );
|
||||
}
|
||||
}
|
||||
return cvScalar( blue_sum, green_sum, red_sum );
|
||||
}
|
||||
|
||||
\end{lstlisting}
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{Line}
|
||||
Draws a line segment connecting two points.
|
||||
|
||||
\cvdefC{
|
||||
void cvLine( \par CvArr* img,\par CvPoint pt1,\par CvPoint pt2,\par CvScalar color,\par int thickness=1,\par int lineType=8,\par int shift=0 );
|
||||
}
|
||||
\cvdefPy{Line(img,pt1,pt2,color,thickness=1,lineType=8,shift=0)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{The image}
|
||||
\cvarg{pt1}{First point of the line segment}
|
||||
\cvarg{pt2}{Second point of the line segment}
|
||||
\cvarg{color}{Line color}
|
||||
\cvarg{thickness}{Line thickness}
|
||||
\cvarg{lineType}{Type of the line:
|
||||
\begin{description}
|
||||
\cvarg{8}{(or omitted) 8-connected line.}
|
||||
\cvarg{4}{4-connected line.}
|
||||
\cvarg{CV\_AA}{antialiased line.}
|
||||
\end{description}}
|
||||
\cvarg{shift}{Number of fractional bits in the point coordinates}
|
||||
\end{description}
|
||||
|
||||
The function draws the line segment between
|
||||
\texttt{pt1} and \texttt{pt2} points in the image. The line is
|
||||
clipped by the image or ROI rectangle. For non-antialiased lines
|
||||
with integer coordinates the 8-connected or 4-connected Bresenham
|
||||
algorithm is used. Thick lines are drawn with rounding endings.
|
||||
Antialiased lines are drawn using Gaussian filtering. To specify
|
||||
the line color, the user may use the macro
|
||||
\texttt{CV\_RGB( r, g, b )}.
|
||||
|
||||
\cvCPyFunc{PolyLine}
|
||||
Draws simple or thick polygons.
|
||||
|
||||
\cvdefC{
|
||||
void cvPolyLine( \par CvArr* img,\par CvPoint** pts,\par int* npts,\par int contours,\par int is\_closed,\par CvScalar color,\par int thickness=1,\par int lineType=8,\par int shift=0 );}
|
||||
\cvdefPy{PolyLine(img,polys,is\_closed,color,thickness=1,lineType=8,shift=0)-> None}
|
||||
|
||||
\begin{description}
|
||||
\ifC
|
||||
\cvarg{pts}{Array of pointers to polygons}
|
||||
\cvarg{npts}{Array of polygon vertex counters}
|
||||
\cvarg{contours}{Number of contours that bind the filled region}
|
||||
\fi
|
||||
\ifPy
|
||||
\cvarg{polys}{List of lists of (x,y) pairs. Each list of points is a polygon.}
|
||||
\fi
|
||||
\cvarg{img}{Image}
|
||||
\cvarg{is\_closed}{Indicates whether the polylines must be drawn
|
||||
closed. If closed, the function draws the line from the last vertex
|
||||
of every contour to the first vertex.}
|
||||
\cvarg{color}{Polyline color}
|
||||
\cvarg{thickness}{Thickness of the polyline edges}
|
||||
\cvarg{lineType}{Type of the line segments, see \cross{Line} description}
|
||||
\cvarg{shift}{Number of fractional bits in the vertex coordinates}
|
||||
\end{description}
|
||||
|
||||
The function draws single or multiple polygonal curves.
|
||||
|
||||
\cvCPyFunc{PutText}
|
||||
Draws a text string.
|
||||
|
||||
\cvdefC{
|
||||
void cvPutText( \par CvArr* img,\par const char* text,\par CvPoint org,\par const CvFont* font,\par CvScalar color );}
|
||||
\cvdefPy{PutText(img,text,org,font,color)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Input image}
|
||||
\cvarg{text}{String to print}
|
||||
\cvarg{org}{Coordinates of the bottom-left corner of the first letter}
|
||||
\cvarg{font}{Pointer to the font structure}
|
||||
\cvarg{color}{Text color}
|
||||
\end{description}
|
||||
|
||||
|
||||
The function renders the text in the image with
|
||||
the specified font and color. The printed text is clipped by the ROI
|
||||
rectangle. Symbols that do not belong to the specified font are
|
||||
replaced with the symbol for a rectangle.
|
||||
|
||||
\cvCPyFunc{Rectangle}
|
||||
Draws a simple, thick, or filled rectangle.
|
||||
|
||||
\cvdefC{void cvRectangle( \par CvArr* img,\par CvPoint pt1,\par CvPoint pt2,\par CvScalar color,\par int thickness=1,\par int lineType=8,\par int shift=0 );}
|
||||
\cvdefPy{Rectangle(img,pt1,pt2,color,thickness=1,lineType=8,shift=0)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Image}
|
||||
\cvarg{pt1}{One of the rectangle's vertices}
|
||||
\cvarg{pt2}{Opposite rectangle vertex}
|
||||
\cvarg{color}{Line color (RGB) or brightness (grayscale image)}
|
||||
\cvarg{thickness}{Thickness of lines that make up the rectangle. Negative values, e.g., CV\_FILLED, cause the function to draw a filled rectangle.}
|
||||
\cvarg{lineType}{Type of the line, see \cross{Line} description}
|
||||
\cvarg{shift}{Number of fractional bits in the point coordinates}
|
||||
\end{description}
|
||||
|
||||
The function draws a rectangle with two opposite corners \texttt{pt1} and \texttt{pt2}.
|
||||
|
||||
\cvfunc{CV\_RGB}\label{CV_RGB}
|
||||
Constructs a color value.
|
||||
|
||||
\cvdefC{\#define CV\_RGB( r, g, b ) cvScalar( (b), (g), (r) )}
|
||||
\cvdefPy{CV\_RGB(red,grn,blu)->CvScalar}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{red}{Red component}
|
||||
\cvarg{grn}{Green component}
|
||||
\cvarg{blu}{Blue component}
|
||||
\end{description}
|
||||
|
||||
\fi
|
||||
|
||||
\ifCpp
|
||||
|
||||
\cvCppFunc{circle}
|
||||
Draws a circle
|
||||
|
||||
\cvdefCpp{
|
||||
void circle(Mat\& img, Point center, int radius,\par
|
||||
const Scalar\& color, int thickness=1,\par
|
||||
int lineType=8, int shift=0);
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{img}{Image where the circle is drawn}
|
||||
\cvarg{center}{Center of the circle}
|
||||
\cvarg{radius}{Radius of the circle}
|
||||
\cvarg{color}{Circle color}
|
||||
\cvarg{thickness}{Thickness of the circle outline if positive; negative thickness means that a filled circle is to be drawn}
|
||||
\cvarg{lineType}{Type of the circle boundary, see \cvCppCross{line} description}
|
||||
\cvarg{shift}{Number of fractional bits in the center coordinates and radius value}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{circle} draws a simple or filled circle with a
|
||||
given center and radius.
|
||||
|
||||
\cvCppFunc{clipLine}
|
||||
Clips the line against the image rectangle
|
||||
|
||||
\cvdefCpp{
|
||||
bool clipLine(Size imgSize, Point\& pt1, Point\& pt2);\newline
|
||||
bool clipLine(Rect imgRect, Point\& pt1, Point\& pt2);\newline
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{imgSize}{The image size; the image rectangle will be \texttt{Rect(0, 0, imgSize.width, imgSize.height)}}
|
||||
\cvarg{imgSize}{The image rectangle}
|
||||
\cvarg{pt1}{The first line point}
|
||||
\cvarg{pt2}{The second line point}
|
||||
\end{description}
|
||||
|
||||
The functions \texttt{clipLine} calculate a part of the line
|
||||
segment which is entirely within the specified rectangle.
|
||||
They return \texttt{false} if the line segment is completely outside the rectangle and \texttt{true} otherwise.
|
||||
|
||||
|
||||
\cvCppFunc{ellipse}
|
||||
Draws a simple or thick elliptic arc or an fills ellipse sector.
|
||||
|
||||
\cvdefCpp{
|
||||
void ellipse(Mat\& img, Point center, Size axes,\par
|
||||
double angle, double startAngle, double endAngle,\par
|
||||
const Scalar\& color, int thickness=1,\par
|
||||
int lineType=8, int shift=0);\newline
|
||||
void ellipse(Mat\& img, const RotatedRect\& box, const Scalar\& color,\par
|
||||
int thickness=1, int lineType=8);\newline
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{img}{The image}
|
||||
\cvarg{center}{Center of the ellipse}
|
||||
\cvarg{axes}{Length of the ellipse axes}
|
||||
\cvarg{angle}{The ellipse rotation angle in degrees}
|
||||
\cvarg{startAngle}{Starting angle of the elliptic arc in degrees}
|
||||
\cvarg{endAngle}{Ending angle of the elliptic arc in degrees}
|
||||
\cvarg{box}{Alternative ellipse representation via a \cross{RotatedRect}, i.e. the function draws an ellipse inscribed in the rotated rectangle}
|
||||
\cvarg{color}{Ellipse color}
|
||||
\cvarg{thickness}{Thickness of the ellipse arc outline if positive, otherwise this indicates that a filled ellipse sector is to be drawn}
|
||||
\cvarg{lineType}{Type of the ellipse boundary, see \cvCppCross{line} description}
|
||||
\cvarg{shift}{Number of fractional bits in the center coordinates and axes' values}
|
||||
\end{description}
|
||||
|
||||
The functions \texttt{ellipse} with less parameters draw an ellipse outline, a filled ellipse, an elliptic
|
||||
arc or a filled ellipse sector.
|
||||
A piecewise-linear curve is used to approximate the elliptic arc boundary. If you need more control of the ellipse rendering, you can retrieve the curve using \cvCppCross{ellipse2Poly} and then render it with \cvCppCross{polylines} or fill it with \cvCppCross{fillPoly}. If you use the first variant of the function and want to draw the whole ellipse, not an arc, pass \texttt{startAngle=0} and \texttt{endAngle=360}. The picture below
|
||||
explains the meaning of the parameters.
|
||||
|
||||
Parameters of Elliptic Arc
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/ellipse.png}
|
||||
|
||||
\cvCppFunc{ellipse2Poly}
|
||||
Approximates an elliptic arc with a polyline
|
||||
|
||||
\cvdefCpp{
|
||||
void ellipse2Poly( Point center, Size axes, int angle,\par
|
||||
int startAngle, int endAngle, int delta,\par
|
||||
vector<Point>\& pts );\newline
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{center}{Center of the arc}
|
||||
\cvarg{axes}{Half-sizes of the arc. See \cvCppCross{ellipse}}
|
||||
\cvarg{angle}{Rotation angle of the ellipse in degrees. See \cvCppCross{ellipse}}
|
||||
\cvarg{startAngle}{Starting angle of the elliptic arc in degrees}
|
||||
\cvarg{endAngle}{Ending angle of the elliptic arc in degrees}
|
||||
\cvarg{delta}{Angle between the subsequent polyline vertices. It defines the approximation accuracy.}
|
||||
\cvarg{pts}{The output vector of polyline vertices}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{ellipse2Poly} computes the vertices of a polyline that approximates the specified elliptic arc. It is used by \cvCppCross{ellipse}.
|
||||
|
||||
\cvCppFunc{fillConvexPoly}
|
||||
Fills a convex polygon.
|
||||
|
||||
\cvdefCpp{
|
||||
void fillConvexPoly(Mat\& img, const Point* pts, int npts,\par
|
||||
const Scalar\& color, int lineType=8,\par
|
||||
int shift=0);\newline
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{img}{Image}
|
||||
\cvarg{pts}{The polygon vertices}
|
||||
\cvarg{npts}{The number of polygon vertices}
|
||||
\cvarg{color}{Polygon color}
|
||||
\cvarg{lineType}{Type of the polygon boundaries, see \cvCppCross{line} description}
|
||||
\cvarg{shift}{The number of fractional bits in the vertex coordinates}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{fillConvexPoly} draws a filled convex polygon.
|
||||
This function is much faster than the function \texttt{fillPoly}
|
||||
and can fill not only convex polygons but any monotonic polygon without self-intersections,
|
||||
i.e., a polygon whose contour intersects every horizontal line (scan
|
||||
line) twice at the most (though, its top-most and/or the bottom edge could be horizontal).
|
||||
|
||||
\cvCppFunc{fillPoly}
|
||||
Fills the area bounded by one or more polygons
|
||||
|
||||
\cvdefCpp{void fillPoly(Mat\& img, const Point** pts, \par
|
||||
const int* npts, int ncontours,\par
|
||||
const Scalar\& color, int lineType=8,\par
|
||||
int shift=0, Point offset=Point() );}
|
||||
\begin{description}
|
||||
\cvarg{img}{Image}
|
||||
\cvarg{pts}{Array of polygons, each represented as an array of points}
|
||||
\cvarg{npts}{The array of polygon vertex counters}
|
||||
\cvarg{ncontours}{The number of contours that bind the filled region}
|
||||
\cvarg{color}{Polygon color}
|
||||
\cvarg{lineType}{Type of the polygon boundaries, see \cvCppCross{line} description}
|
||||
\cvarg{shift}{The number of fractional bits in the vertex coordinates}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{fillPoly} fills an area bounded by several
|
||||
polygonal contours. The function can fills complex areas, for example,
|
||||
areas with holes, contours with self-intersections (some of thier parts), and so forth.
|
||||
|
||||
\cvCppFunc{getTextSize}
|
||||
Calculates the width and height of a text string.
|
||||
|
||||
\cvdefCpp{Size getTextSize(const string\& text, int fontFace,\par
|
||||
double fontScale, int thickness,\par
|
||||
int* baseLine);\newline}
|
||||
\begin{description}
|
||||
\cvarg{text}{The input text string}
|
||||
\cvarg{fontFace}{The font to use; see \cvCppCross{putText}}
|
||||
\cvarg{fontScale}{The font scale; see \cvCppCross{putText}}
|
||||
\cvarg{thickness}{The thickness of lines used to render the text; see \cvCppCross{putText}}
|
||||
\cvarg{baseLine}{The output parameter - y-coordinate of the baseline relative to the bottom-most text point}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{getTextSize} calculates and returns size of the box that contain the specified text.
|
||||
That is, the following code will render some text, the tight box surrounding it and the baseline:
|
||||
|
||||
\begin{lstlisting}
|
||||
// Use "y" to show that the baseLine is about
|
||||
string text = "Funny text inside the box";
|
||||
int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
|
||||
double fontScale = 2;
|
||||
int thickness = 3;
|
||||
|
||||
Mat img(600, 800, CV_8UC3, Scalar::all(0));
|
||||
|
||||
int baseline=0;
|
||||
Size textSize = getTextSize(text, fontFace,
|
||||
fontScale, thickness, &baseline);
|
||||
baseline += thickness;
|
||||
|
||||
// center the text
|
||||
Point textOrg((img.cols - textSize.width)/2,
|
||||
(img.rows + textSize.height)/2);
|
||||
|
||||
// draw the box
|
||||
rectangle(img, textOrg + Point(0, baseline),
|
||||
textOrg + Point(textSize.width, -textSize.height),
|
||||
Scalar(0,0,255));
|
||||
// ... and the baseline first
|
||||
line(img, textOrg + Point(0, thickness),
|
||||
textOrg + Point(textSize.width, thickness),
|
||||
Scalar(0, 0, 255));
|
||||
|
||||
// then put the text itself
|
||||
putText(img, text, textOrg, fontFace, fontScale,
|
||||
Scalar::all(255), thickness, 8);
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvCppFunc{line}
|
||||
Draws a line segment connecting two points
|
||||
|
||||
\cvdefCpp{void line(Mat\& img, Point pt1, Point pt2, const Scalar\& color,\par
|
||||
int thickness=1, int lineType=8, int shift=0);\newline}
|
||||
\begin{description}
|
||||
\cvarg{img}{The image}
|
||||
\cvarg{pt1}{First point of the line segment}
|
||||
\cvarg{pt2}{Second point of the line segment}
|
||||
\cvarg{color}{Line color}
|
||||
\cvarg{thickness}{Line thickness}
|
||||
\cvarg{lineType}{Type of the line:
|
||||
\begin{description}
|
||||
\cvarg{8}{(or omitted) 8-connected line.}
|
||||
\cvarg{4}{4-connected line.}
|
||||
\cvarg{CV\_AA}{antialiased line.}
|
||||
\end{description}}
|
||||
\cvarg{shift}{Number of fractional bits in the point coordinates}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{line} draws the line segment between
|
||||
\texttt{pt1} and \texttt{pt2} points in the image. The line is
|
||||
clipped by the image boundaries. For non-antialiased lines
|
||||
with integer coordinates the 8-connected or 4-connected Bresenham
|
||||
algorithm is used. Thick lines are drawn with rounding endings.
|
||||
Antialiased lines are drawn using Gaussian filtering. To specify
|
||||
the line color, the user may use the macro
|
||||
\texttt{CV\_RGB(r, g, b)}.
|
||||
|
||||
|
||||
\cvclass{LineIterator}
|
||||
Class for iterating pixels on a raster line
|
||||
|
||||
\begin{lstlisting}
|
||||
class LineIterator
|
||||
{
|
||||
public:
|
||||
// creates iterators for the line connecting pt1 and pt2
|
||||
// the line will be clipped on the image boundaries
|
||||
// the line is 8-connected or 4-connected
|
||||
// If leftToRight=true, then the iteration is always done
|
||||
// from the left-most point to the right most,
|
||||
// not to depend on the ordering of pt1 and pt2 parameters
|
||||
LineIterator(const Mat& img, Point pt1, Point pt2,
|
||||
int connectivity=8, bool leftToRight=false);
|
||||
// returns pointer to the current line pixel
|
||||
uchar* operator *();
|
||||
// move the iterator to the next pixel
|
||||
LineIterator& operator ++();
|
||||
LineIterator operator ++(int);
|
||||
|
||||
// internal state of the iterator
|
||||
uchar* ptr;
|
||||
int err, count;
|
||||
int minusDelta, plusDelta;
|
||||
int minusStep, plusStep;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class \texttt{LineIterator} is used to get each pixel of a raster line. It can be treated as versatile implementation of the Bresenham algorithm, where you can stop at each pixel and do some extra processing, for example, grab pixel values along the line, or draw a line with some effect (e.g. with XOR operation).
|
||||
|
||||
The number of pixels along the line is store in \texttt{LineIterator::count}.
|
||||
|
||||
\begin{lstlisting}
|
||||
// grabs pixels along the line (pt1, pt2)
|
||||
// from 8-bit 3-channel image to the buffer
|
||||
LineIterator it(img, pt1, pt2, 8);
|
||||
vector<Vec3b> buf(it.count);
|
||||
|
||||
for(int i = 0; i < it.count; i++, ++it)
|
||||
buf[i] = *(const Vec3b)*it;
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvCppFunc{rectangle}
|
||||
Draws a simple, thick, or filled up-right rectangle.
|
||||
|
||||
\cvdefCpp{void rectangle(Mat\& img, Point pt1, Point pt2,\par
|
||||
const Scalar\& color, int thickness=1,\par
|
||||
int lineType=8, int shift=0);}
|
||||
\begin{description}
|
||||
\cvarg{img}{Image}
|
||||
\cvarg{pt1}{One of the rectangle's vertices}
|
||||
\cvarg{pt2}{Opposite to \texttt{pt1} rectangle vertex}
|
||||
\cvarg{color}{Rectangle color or brightness (grayscale image)}
|
||||
\cvarg{thickness}{Thickness of lines that make up the rectangle. Negative values, e.g. \texttt{CV\_FILLED}, mean that the function has to draw a filled rectangle.}
|
||||
\cvarg{lineType}{Type of the line, see \cvCppCross{line} description}
|
||||
\cvarg{shift}{Number of fractional bits in the point coordinates}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{rectangle} draws a rectangle outline or a filled rectangle, which two opposite corners are \texttt{pt1} and \texttt{pt2}.
|
||||
|
||||
|
||||
\cvCppFunc{polylines}
|
||||
Draws several polygonal curves
|
||||
|
||||
\cvdefCpp{void polylines(Mat\& img, const Point** pts, const int* npts,\par
|
||||
int ncontours, bool isClosed, const Scalar\& color,\par
|
||||
int thickness=1, int lineType=8, int shift=0 );\newline}
|
||||
\begin{description}
|
||||
\cvarg{img}{The image}
|
||||
\cvarg{pts}{Array of polygonal curves}
|
||||
\cvarg{npts}{Array of polygon vertex counters}
|
||||
\cvarg{ncontours}{The number of curves}
|
||||
\cvarg{isClosed}{Indicates whether the drawn polylines are closed or not. If they are closed, the function draws the line from the last vertex of each curve to its first vertex}
|
||||
\cvarg{color}{Polyline color}
|
||||
\cvarg{thickness}{Thickness of the polyline edges}
|
||||
\cvarg{lineType}{Type of the line segments, see \cvCppCross{line} description}
|
||||
\cvarg{shift}{The number of fractional bits in the vertex coordinates}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{polylines} draws one or more polygonal curves.
|
||||
|
||||
\cvCppFunc{putText}
|
||||
Draws a text string
|
||||
|
||||
\cvdefCpp{void putText( Mat\& img, const string\& text, Point org,\par
|
||||
int fontFace, double fontScale, Scalar color,\par
|
||||
int thickness=1, int lineType=8,\par
|
||||
bool bottomLeftOrigin=false );}
|
||||
\begin{description}
|
||||
\cvarg{img}{The image}
|
||||
\cvarg{text}{The text string to be drawn}
|
||||
\cvarg{org}{The bottom-left corner of the text string in the image}
|
||||
\cvarg{fontFace}{The font type, one of \texttt{FONT\_HERSHEY\_SIMPLEX}, \texttt{FONT\_HERSHEY\_PLAIN},
|
||||
\texttt{FONT\_HERSHEY\_DUPLEX}, \texttt{FONT\_HERSHEY\_COMPLEX}, \texttt{FONT\_HERSHEY\_TRIPLEX},
|
||||
\texttt{FONT\_HERSHEY\_COMPLEX\_SMALL}, \texttt{FONT\_HERSHEY\_SCRIPT\_SIMPLEX} or \texttt{FONT\_HERSHEY\_SCRIPT\_COMPLEX},
|
||||
where each of the font id's can be combined with \texttt{FONT\_HERSHEY\_ITALIC} to get the slanted letters.}
|
||||
\cvarg{fontScale}{The font scale factor that is multiplied by the font-specific base size}
|
||||
\cvarg{color}{The text color}
|
||||
\cvarg{thickness}{Thickness of the lines used to draw the text}
|
||||
\cvarg{lineType}{The line type; see \texttt{line} for details}
|
||||
\cvarg{bottomLeftOrigin}{When true, the image data origin is at the bottom-left corner, otherwise it's at the top-left corner}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{putText} renders the specified text string in the image.
|
||||
Symbols that can not be rendered using the specified font are
|
||||
replaced by question marks. See \cvCppCross{getTextSize} for a text rendering code example.
|
||||
|
||||
\fi
|
File diff suppressed because it is too large
Load Diff
@ -1,663 +0,0 @@
|
||||
\ifCpp
|
||||
\chapter{Introduction}
|
||||
|
||||
Starting from OpenCV 2.0 the new modern C++ interface has been introduced.
|
||||
It is crisp (less typing is needed to code the same thing), type-safe (no more \texttt{CvArr*} a.k.a. \texttt{void*})
|
||||
and, in general, more convenient to use. Here is a short example of what it looks like:
|
||||
|
||||
\begin{lstlisting}
|
||||
//
|
||||
// Simple retro-style photo effect done by adding noise to
|
||||
// the luminance channel and reducing intensity of the chroma channels
|
||||
//
|
||||
|
||||
// include standard OpenCV headers, same as before
|
||||
#include "cv.h"
|
||||
#include "highgui.h"
|
||||
|
||||
// all the new API is put into "cv" namespace. Export its content
|
||||
using namespace cv;
|
||||
|
||||
// enable/disable use of mixed API in the code below.
|
||||
#define DEMO_MIXED_API_USE 1
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
const char* imagename = argc > 1 ? argv[1] : "lena.jpg";
|
||||
#if DEMO_MIXED_API_USE
|
||||
// Ptr<T> is safe ref-conting pointer class
|
||||
Ptr<IplImage> iplimg = cvLoadImage(imagename);
|
||||
|
||||
// cv::Mat replaces the CvMat and IplImage, but it's easy to convert
|
||||
// between the old and the new data structures
|
||||
// (by default, only the header is converted and the data is shared)
|
||||
Mat img(iplimg);
|
||||
#else
|
||||
// the newer cvLoadImage alternative with MATLAB-style name
|
||||
Mat img = imread(imagename);
|
||||
#endif
|
||||
|
||||
if( !img.data ) // check if the image has been loaded properly
|
||||
return -1;
|
||||
|
||||
Mat img_yuv;
|
||||
// convert image to YUV color space.
|
||||
// The output image will be allocated automatically
|
||||
cvtColor(img, img_yuv, CV_BGR2YCrCb);
|
||||
|
||||
// split the image into separate color planes
|
||||
vector<Mat> planes;
|
||||
split(img_yuv, planes);
|
||||
|
||||
// another Mat constructor; allocates a matrix of the specified
|
||||
// size and type
|
||||
Mat noise(img.size(), CV_8U);
|
||||
|
||||
// fills the matrix with normally distributed random values;
|
||||
// there is also randu() for uniformly distributed random numbers.
|
||||
// Scalar replaces CvScalar, Scalar::all() replaces cvScalarAll().
|
||||
randn(noise, Scalar::all(128), Scalar::all(20));
|
||||
|
||||
// blur the noise a bit, kernel size is 3x3 and both sigma's
|
||||
// are set to 0.5
|
||||
GaussianBlur(noise, noise, Size(3, 3), 0.5, 0.5);
|
||||
|
||||
const double brightness_gain = 0;
|
||||
const double contrast_gain = 1.7;
|
||||
#if DEMO_MIXED_API_USE
|
||||
// it's easy to pass the new matrices to the functions that
|
||||
// only work with IplImage or CvMat:
|
||||
// step 1) - convert the headers, data will not be copied
|
||||
IplImage cv_planes_0 = planes[0], cv_noise = noise;
|
||||
// step 2) call the function; do not forget unary "&" to form pointers
|
||||
cvAddWeighted(&cv_planes_0, contrast_gain, &cv_noise, 1,
|
||||
-128 + brightness_gain, &cv_planes_0);
|
||||
#else
|
||||
addWeighted(planes[0], constrast_gain, noise, 1,
|
||||
-128 + brightness_gain, planes[0]);
|
||||
#endif
|
||||
const double color_scale = 0.5;
|
||||
// Mat::convertTo() replaces cvConvertScale.
|
||||
// One must explicitly specify the output matrix type
|
||||
// (we keep it intact, i.e. pass planes[1].type())
|
||||
planes[1].convertTo(planes[1], planes[1].type(),
|
||||
color_scale, 128*(1-color_scale));
|
||||
|
||||
// alternative form of convertTo if we know the datatype
|
||||
// at compile time ("uchar" here).
|
||||
// This expression will not create any temporary arrays
|
||||
// and should be almost as fast as the above variant
|
||||
planes[2] = Mat_<uchar>(planes[2]*color_scale + 128*(1-color_scale));
|
||||
|
||||
// Mat::mul replaces cvMul(). Again, no temporary arrays are
|
||||
// created in the case of simple expressions.
|
||||
planes[0] = planes[0].mul(planes[0], 1./255);
|
||||
|
||||
// now merge the results back
|
||||
merge(planes, img_yuv);
|
||||
// and produce the output RGB image
|
||||
cvtColor(img_yuv, img, CV_YCrCb2BGR);
|
||||
|
||||
// this is counterpart for cvNamedWindow
|
||||
namedWindow("image with grain", CV_WINDOW_AUTOSIZE);
|
||||
#if DEMO_MIXED_API_USE
|
||||
// this is to demonstrate that img and iplimg really share the data -
|
||||
// the result of the above processing is stored to img and thus
|
||||
// in iplimg too.
|
||||
cvShowImage("image with grain", iplimg);
|
||||
#else
|
||||
imshow("image with grain", img);
|
||||
#endif
|
||||
waitKey();
|
||||
|
||||
return 0;
|
||||
// all the memory will automatically be released
|
||||
// by vector<>, Mat and Ptr<> destructors.
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Following a summary "cheatsheet" below, the rest of the introduction will discuss the key features of the new interface in more detail.
|
||||
|
||||
|
||||
|
||||
\section{C++ Cheatsheet}\label{cheatSheet}
|
||||
The section is just a summary "cheatsheet" of common things you may want to do with cv::Mat:. The code snippets below all assume the correct
|
||||
namespace is used:
|
||||
\begin{lstlisting}
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
Convert an IplImage or CvMat to an cv::Mat and a cv::Mat to an IplImage or CvMat:
|
||||
\begin{lstlisting}
|
||||
// Assuming somewhere IplImage *iplimg; exists
|
||||
// and has been allocated and cv::Mat Mimg has been defined
|
||||
Mat imgMat(iplimg); //Construct an Mat image "img" out of an IplImage
|
||||
Mimg = iplimg; //Or just set the header of pre existing cv::Mat
|
||||
//Ming to iplimg's data (no copying is done)
|
||||
|
||||
//Convert to IplImage or CvMat, no data copying
|
||||
IplImage ipl_img = img;
|
||||
CvMat cvmat = img; // convert cv::Mat -> CvMat
|
||||
\end{lstlisting}
|
||||
|
||||
A very simple way to operate on a rectanglular sub-region of an image (ROI -- "Region of Interest"):
|
||||
\begin{lstlisting}
|
||||
//Make a rectangle
|
||||
Rect roi(10, 20, 100, 50);
|
||||
//Point a cv::Mat header at it (no allocation is done)
|
||||
Mat image_roi = image(roi);
|
||||
\end{lstlisting}
|
||||
|
||||
A bit advanced, but should you want efficiently to sample from a circular region in an image
|
||||
(below, instead of sampling, we just draw into a BGR image) :
|
||||
|
||||
\begin{lstlisting}
|
||||
// the function returns x boundary coordinates of
|
||||
// the circle for each y. RxV[y1] = x1 means that
|
||||
// when y=y1, -x1 <=x<=x1 is inside the circle
|
||||
void getCircularROI(int R, vector < int > & RxV)
|
||||
{
|
||||
RxV.resize(R+1);
|
||||
for( int y = 0; y <= R; y++ )
|
||||
RxV[y] = cvRound(sqrt((double)R*R - y*y));
|
||||
}
|
||||
|
||||
// This draws a circle in the green channel
|
||||
// (note the "[1]" for a BGR" image,
|
||||
// blue and red channels are not modified),
|
||||
// but is really an example of how to *sample* from a circular region.
|
||||
void drawCircle(Mat &image, int R, Point center)
|
||||
{
|
||||
vector<int> RxV;
|
||||
getCircularROI(R, RxV);
|
||||
|
||||
Mat_<Vec3b>& img = (Mat_<Vec3b>&)image; //3 channel pointer to image
|
||||
for( int dy = -R; dy <= R; dy++ )
|
||||
{
|
||||
int Rx = RxV[abs(dy)];
|
||||
for( int dx = -Rx; dx <= Rx; dx++ )
|
||||
img(center.y+dy, center.x+dx)[1] = 255;
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\section{Namespace cv and Function Naming}
|
||||
|
||||
All the newly introduced classes and functions are placed into \texttt{cv} namespace. Therefore, to access this functionality from your code, use \texttt{cv::} specifier or \texttt{"using namespace cv;"} directive:
|
||||
\begin{lstlisting}
|
||||
#include "cv.h"
|
||||
|
||||
...
|
||||
cv::Mat H = cv::findHomography(points1, points2, cv::RANSAC, 5);
|
||||
...
|
||||
\end{lstlisting}
|
||||
or
|
||||
\begin{lstlisting}
|
||||
#include "cv.h"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
...
|
||||
Mat H = findHomography(points1, points2, RANSAC, 5 );
|
||||
...
|
||||
\end{lstlisting}
|
||||
|
||||
It is probable that some of the current or future OpenCV external names conflict with STL
|
||||
or other libraries, in this case use explicit namespace specifiers to resolve the name conflicts:
|
||||
\begin{lstlisting}
|
||||
Mat a(100, 100, CV_32F);
|
||||
randu(a, Scalar::all(1), Scalar::all(std::rand()%256+1));
|
||||
cv::log(a, a);
|
||||
a /= std::log(2.);
|
||||
\end{lstlisting}
|
||||
|
||||
For the most of the C functions and structures from OpenCV 1.x you may find the direct counterparts in the new C++ interface. The name is usually formed by omitting \texttt{cv} or \texttt{Cv} prefix and turning the first letter to the low case (unless it's a own name, like Canny, Sobel etc). In case when there is no the new-style counterpart, it's possible to use the old functions with the new structures, as shown the first sample in the chapter.
|
||||
|
||||
\section{Memory Management}
|
||||
|
||||
When using the new interface, the most of memory deallocation and even memory allocation operations are done automatically when needed.
|
||||
|
||||
First of all, \cross{Mat}, \cross{SparseMat} and other classes have destructors
|
||||
that deallocate memory buffers occupied by the structures when needed.
|
||||
|
||||
Secondly, this "when needed" means that the destructors do not always deallocate the buffers, they take into account possible data sharing.
|
||||
That is, in a destructor the reference counter associated with the underlying data is decremented and the data is deallocated
|
||||
if and only if the reference counter becomes zero, that is, when no other structures refer to the same buffer. When such a structure
|
||||
containing a reference counter is copied, usually just the header is duplicated, while the underlying data is not; instead, the reference counter is incremented to memorize that there is another owner of the same data.
|
||||
Also, some structures, such as \texttt{Mat}, can refer to the user-allocated data.
|
||||
In this case the reference counter is \texttt{NULL} pointer and then no reference counting is done - the data is not deallocated by the destructors and should be deallocated manually by the user. We saw this scheme in the first example in the chapter:
|
||||
\begin{lstlisting}
|
||||
// allocates IplImages and wraps it into shared pointer class.
|
||||
Ptr<IplImage> iplimg = cvLoadImage(...);
|
||||
|
||||
// constructs Mat header for IplImage data;
|
||||
// does not copy the data;
|
||||
// the reference counter will be NULL
|
||||
Mat img(iplimg);
|
||||
...
|
||||
// in the end of the block img destructor is called,
|
||||
// which does not try to deallocate the data because
|
||||
// of NULL pointer to the reference counter.
|
||||
//
|
||||
// Then Ptr<IplImage> destructor is called that decrements
|
||||
// the reference counter and, as the counter becomes 0 in this case,
|
||||
// the destructor calls cvReleaseImage().
|
||||
\end{lstlisting}
|
||||
|
||||
The copying semantics was mentioned in the above paragraph, but deserves a dedicated discussion.
|
||||
By default, the new OpenCV structures implement shallow, so called O(1) (i.e. constant-time) assignment operations. It gives user possibility to pass quite big data structures to functions (though, e.g. passing \texttt{const Mat\&} is still faster than passing \texttt{Mat}), return them (e.g. see the example with \cross{findHomography} above), store them in OpenCV and STL containers etc. - and do all of this very efficiently. On the other hand, most of the new data structures provide \texttt{clone()} method that creates a full copy of an object. Here is the sample:
|
||||
\begin{lstlisting}
|
||||
// create a big 8Mb matrix
|
||||
Mat A(1000, 1000, CV_64F);
|
||||
|
||||
// create another header for the same matrix;
|
||||
// this is instant operation, regardless of the matrix size.
|
||||
Mat B = A;
|
||||
// create another header for the 3-rd row of A; no data is copied either
|
||||
Mat C = B.row(3);
|
||||
// now create a separate copy of the matrix
|
||||
Mat D = B.clone();
|
||||
// copy the 5-th row of B to C, that is, copy the 5-th row of A
|
||||
// to the 3-rd row of A.
|
||||
B.row(5).copyTo(C);
|
||||
// now let A and D share the data; after that the modified version
|
||||
// of A is still referenced by B and C.
|
||||
A = D;
|
||||
// now make B an empty matrix (which references no memory buffers),
|
||||
// but the modified version of A will still be referenced by C,
|
||||
// despite that C is just a single row of the original A
|
||||
B.release();
|
||||
|
||||
// finally, make a full copy of C. In result, the big modified
|
||||
// matrix will be deallocated, since it's not referenced by anyone
|
||||
C = C.clone();
|
||||
\end{lstlisting}
|
||||
|
||||
Memory management of the new data structures is automatic and thus easy. If, however, your code uses \cross{IplImage},
|
||||
\cross{CvMat} or other C data structures a lot, memory management can still be automated without immediate migration
|
||||
to \cross{Mat} by using the already mentioned template class \cross{Ptr}, similar to \texttt{shared\_ptr} from Boost and C++ TR1.
|
||||
It wraps a pointer to an arbitrary object, provides transparent access to all the object fields and associates a reference counter with it.
|
||||
Instance of the class can be passed to any function that expects the original pointer. For correct deallocation of the object, you should specialize \texttt{Ptr<T>::delete\_obj()} method. Such specialized methods already exist for the classical OpenCV structures, e.g.:
|
||||
\begin{lstlisting}
|
||||
// cxoperations.hpp:
|
||||
...
|
||||
template<> inline Ptr<IplImage>::delete_obj() {
|
||||
cvReleaseImage(&obj);
|
||||
}
|
||||
...
|
||||
\end{lstlisting}
|
||||
See \cross{Ptr} description for more details and other usage scenarios.
|
||||
|
||||
|
||||
\section{Memory Management Part II. Automatic Data Allocation}\label{AutomaticMemoryManagement2}
|
||||
|
||||
With the new interface not only explicit memory deallocation is not needed anymore,
|
||||
but the memory allocation is often done automatically too. That was demonstrated in the example
|
||||
in the beginning of the chapter when \texttt{cvtColor} was called, and here are some more details.
|
||||
|
||||
\cross{Mat} and other array classes provide method \texttt{create} that allocates a new buffer for array
|
||||
data if and only if the currently allocated array is not of the required size and type.
|
||||
If a new buffer is needed, the previously allocated buffer is released
|
||||
(by engaging all the reference counting mechanism described in the previous section).
|
||||
Now, since it is very quick to check whether the needed memory buffer is already allocated,
|
||||
most new OpenCV functions that have arrays as output parameters call the \texttt{create} method and
|
||||
this way the \emph{automatic data allocation} concept is implemented. Here is the example:
|
||||
\begin{lstlisting}
|
||||
#include "cv.h"
|
||||
#include "highgui.h"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
VideoCapture cap(0);
|
||||
if(!cap.isOpened()) return -1;
|
||||
|
||||
Mat edges;
|
||||
namedWindow("edges",1);
|
||||
for(;;)
|
||||
{
|
||||
Mat frame;
|
||||
cap >> frame;
|
||||
cvtColor(frame, edges, CV_BGR2GRAY);
|
||||
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
|
||||
Canny(edges, edges, 0, 30, 3);
|
||||
imshow("edges", edges);
|
||||
if(waitKey(30) >= 0) break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
\end{lstlisting}
|
||||
The matrix \texttt{edges} is allocated during the first frame processing and unless the resolution will suddenly change,
|
||||
the same buffer will be reused for every next frame's edge map.
|
||||
|
||||
In many cases the output array type and size can be inferenced from the input arrays' respective characteristics, but not always.
|
||||
In these rare cases the corresponding functions take separate input parameters that specify the data type and/or size of the output arrays,
|
||||
like \cross{resize}. Anyway, a vast majority of the new-style array processing functions call \texttt{create}
|
||||
for each of the output array, with just a few exceptions like \texttt{mixChannels}, \texttt{RNG::fill} and some others.
|
||||
|
||||
Note that this output array allocation semantic is only implemented in the new functions. If you want to pass the new structures to some old OpenCV function, you should first allocate the output arrays using \texttt{create} method, then make \texttt{CvMat} or \texttt{IplImage} headers and after that call the function.
|
||||
|
||||
\section{Algebraic Operations}
|
||||
|
||||
Just like in v1.x, OpenCV 2.x provides some basic functions operating on matrices, like \texttt{add},
|
||||
\texttt{subtract}, \texttt{gemm} etc. In addition, it introduces overloaded operators that give the user a convenient
|
||||
algebraic notation, which is nearly as fast as using the functions directly. For example, here is how the least squares problem $Ax=b$
|
||||
can be solved using normal equations:
|
||||
\begin{lstlisting}
|
||||
Mat x = (A.t()*A).inv()*(A.t()*b);
|
||||
\end{lstlisting}
|
||||
|
||||
The complete list of overloaded operators can be found in \cross{Matrix Expressions}.
|
||||
|
||||
\section{Fast Element Access}
|
||||
|
||||
Historically, OpenCV provided many different ways to access image and matrix elements, and none of them was both fast and convenient.
|
||||
With the new data structures, OpenCV 2.x introduces a few more alternatives, hopefully more convenient than before. For detailed description of the operations, please, check \cross{Mat} and \hyperref[MatT]{Mat\_} description. Here is part of the retro-photo-styling example rewritten (in simplified form) using the element access operations:
|
||||
|
||||
\begin{lstlisting}
|
||||
...
|
||||
// split the image into separate color planes
|
||||
vector<Mat> planes;
|
||||
split(img_yuv, planes);
|
||||
|
||||
// method 1. process Y plane using an iterator
|
||||
MatIterator_<uchar> it = planes[0].begin<uchar>(),
|
||||
it_end = planes[0].end<uchar>();
|
||||
for(; it != it_end; ++it)
|
||||
{
|
||||
double v = *it*1.7 + rand()%21-10;
|
||||
*it = saturate_cast<uchar>(v*v/255.);
|
||||
}
|
||||
|
||||
// method 2. process the first chroma plane using pre-stored row pointer.
|
||||
// method 3. process the second chroma plane using
|
||||
// individual element access operations
|
||||
for( int y = 0; y < img_yuv.rows; y++ )
|
||||
{
|
||||
uchar* Uptr = planes[1].ptr<uchar>(y);
|
||||
for( int x = 0; x < img_yuv.cols; x++ )
|
||||
{
|
||||
Uptr[x] = saturate_cast<uchar>((Uptr[x]-128)/2 + 128);
|
||||
uchar& Vxy = planes[2].at<uchar>(y, x);
|
||||
Vxy = saturate_cast<uchar>((Vxy-128)/2 + 128);
|
||||
}
|
||||
}
|
||||
|
||||
merge(planes, img_yuv);
|
||||
...
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\section{Saturation Arithmetics}
|
||||
|
||||
In the above sample you may have noticed \hyperref[saturatecast]{saturate\_cast} operator, and that's how all the pixel processing is done in OpenCV. When a result of image operation is 8-bit image with pixel values ranging from 0 to 255, each output pixel value is clipped to this available range:
|
||||
|
||||
\[
|
||||
I(x,y)=\min(\max(value, 0), 255)
|
||||
\]
|
||||
|
||||
and the similar rules are applied to 8-bit signed and 16-bit signed and unsigned types. This "saturation" semantics (different from usual C language "wrapping" semantics, where lowest bits are taken, is implemented in every image processing function, from the simple \texttt{cv::add} to
|
||||
\texttt{cv::cvtColor}, \texttt{cv::resize}, \texttt{cv::filter2D} etc.
|
||||
It is not a new feature of OpenCV v2.x, it was there from very beginning. In the new version this special \hyperref[saturatecast]{saturate\_cast} template operator is introduced to simplify implementation of this semantic in your own functions.
|
||||
|
||||
|
||||
\section{Error handling}
|
||||
|
||||
The modern error handling mechanism in OpenCV uses exceptions, as opposite to the manual stack unrolling used in previous versions.
|
||||
|
||||
If you to check some conditions in your code and raise an error if they are not satisfied, use \hyperref[CV Assert]{CV\_Assert}() or \hyperref[cppfunc.error]{CV\_Error}().
|
||||
|
||||
\begin{lstlisting}
|
||||
CV_Assert(mymat.type() == CV_32FC1);
|
||||
...
|
||||
|
||||
if( scaleValue < 0 || scaleValue > 1000 )
|
||||
CV_Error(CV_StsOutOfRange, "The scale value is out of range");
|
||||
\end{lstlisting}
|
||||
|
||||
There is also \hyperref[CV Assert]{CV\_DbgAssert} that yields no code in the Release configuration.
|
||||
|
||||
To handle the errors, use the standard exception handling mechanism:
|
||||
|
||||
\begin{lstlisting}
|
||||
try
|
||||
{
|
||||
...
|
||||
}
|
||||
catch( cv::Exception& e )
|
||||
{
|
||||
const char* err_msg = e.what();
|
||||
...
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
instead of \hyperref[Exception]{cv::Exception} you can write \texttt{std::exception}, since the former is derived from the latter.
|
||||
|
||||
Then, obviously, to make it all work and do not worry about the object destruction, try not to use \texttt{IplImage*}, \texttt{CvMat*} and plain pointers in general. Use \hyperref[Mat]{cv::Mat}, \texttt{std::vector<>}, \hyperref[Ptr]{cv::Ptr} etc.
|
||||
|
||||
\section{Threading and Reenterability}
|
||||
|
||||
OpenCV uses OpenMP to run some time-consuming operations in parallel. Threading can be explicitly controlled by \cross{setNumThreads} function. Also, functions and "const" methods of the classes are generally re-enterable, that is, they can be called from different threads asynchronously.
|
||||
|
||||
\fi
|
||||
|
||||
\ifPy
|
||||
\chapter{Introduction}
|
||||
|
||||
Starting with release 2.0, OpenCV has a new Python interface. This replaces the previous
|
||||
\href{http://opencv.willowgarage.com/wiki/SwigPythonInterface}{SWIG-based Python interface}.
|
||||
|
||||
Some highlights of the new bindings:
|
||||
|
||||
\begin{itemize}
|
||||
\item{single import of all of OpenCV using \texttt{import cv}}
|
||||
\item{OpenCV functions no longer have the "cv" prefix}
|
||||
\item{simple types like CvRect and CvScalar use Python tuples}
|
||||
\item{sharing of Image storage, so image transport between OpenCV and other systems (e.g. numpy and ROS) is very efficient}
|
||||
\item{complete documentation for the Python functions}
|
||||
\end{itemize}
|
||||
|
||||
This cookbook section contains a few illustrative examples of OpenCV Python code.
|
||||
|
||||
\section{Cookbook}
|
||||
|
||||
Here is a collection of code fragments demonstrating some features
|
||||
of the OpenCV Python bindings.
|
||||
|
||||
\subsection{Convert an image}
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv
|
||||
>>> im = cv.LoadImageM("building.jpg")
|
||||
>>> print type(im)
|
||||
<type 'cv.cvmat'>
|
||||
>>> cv.SaveImage("foo.png", im)
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Resize an image}
|
||||
|
||||
To resize an image in OpenCV, create a destination image of the appropriate size, then call \cross{Resize}.
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv
|
||||
>>> original = cv.LoadImageM("building.jpg")
|
||||
>>> thumbnail = cv.CreateMat(original.rows / 10, original.cols / 10, cv.CV_8UC3)
|
||||
>>> cv.Resize(original, thumbnail)
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Compute the Laplacian}
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv
|
||||
>>> im = cv.LoadImageM("building.jpg", 1)
|
||||
>>> dst = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_16S, 3)
|
||||
>>> laplace = cv.Laplace(im, dst)
|
||||
>>> cv.SaveImage("foo-laplace.png", dst)
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\subsection{Using GoodFeaturesToTrack}
|
||||
|
||||
To find the 10 strongest corner features in an image, use \cross{GoodFeaturesToTrack} like this:
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv
|
||||
>>> img = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE)
|
||||
>>> eig_image = cv.CreateMat(img.rows, img.cols, cv.CV_32FC1)
|
||||
>>> temp_image = cv.CreateMat(img.rows, img.cols, cv.CV_32FC1)
|
||||
>>> for (x,y) in cv.GoodFeaturesToTrack(img, eig_image, temp_image, 10, 0.04, 1.0, useHarris = True):
|
||||
... print "good feature at", x,y
|
||||
good feature at 198.0 514.0
|
||||
good feature at 791.0 260.0
|
||||
good feature at 370.0 467.0
|
||||
good feature at 374.0 469.0
|
||||
good feature at 490.0 520.0
|
||||
good feature at 262.0 278.0
|
||||
good feature at 781.0 134.0
|
||||
good feature at 3.0 247.0
|
||||
good feature at 667.0 321.0
|
||||
good feature at 764.0 304.0
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\subsection{Using GetSubRect}
|
||||
|
||||
GetSubRect returns a rectangular part of another image. It does this without copying any data.
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv
|
||||
>>> img = cv.LoadImageM("building.jpg")
|
||||
>>> sub = cv.GetSubRect(img, (60, 70, 32, 32)) # sub is 32x32 patch within img
|
||||
>>> cv.SetZero(sub) # clear sub to zero, which also clears 32x32 pixels in img
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{Using CreateMat, and accessing an element}
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv
|
||||
>>> mat = cv.CreateMat(5, 5, cv.CV_32FC1)
|
||||
>>> cv.Set(mat, 1.0)
|
||||
>>> mat[3,1] += 0.375
|
||||
>>> print mat[3,1]
|
||||
1.375
|
||||
>>> print [mat[3,i] for i in range(5)]
|
||||
[1.0, 1.375, 1.0, 1.0, 1.0]
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{ROS image message to OpenCV}
|
||||
|
||||
See this tutorial: \href{http://www.ros.org/wiki/cv\_bridge/Tutorials/UsingCvBridgeToConvertBetweenROSImagesAndOpenCVImages}{Using CvBridge to convert between ROS images And OpenCV images}.
|
||||
|
||||
\subsection{PIL Image to OpenCV}
|
||||
|
||||
(For details on PIL see the \href{http://www.pythonware.com/library/pil/handbook/image.htm}{PIL handbook}.)
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import Image, cv
|
||||
>>> pi = Image.open('building.jpg') # PIL image
|
||||
>>> cv_im = cv.CreateImageHeader(pi.size, cv.IPL_DEPTH_8U, 3)
|
||||
>>> cv.SetData(cv_im, pi.tostring())
|
||||
>>> print pi.size, cv.GetSize(cv_im)
|
||||
(868, 600) (868, 600)
|
||||
>>> print pi.tostring() == cv_im.tostring()
|
||||
True
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{OpenCV to PIL Image}
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import Image, cv
|
||||
>>> cv_im = cv.CreateImage((320,200), cv.IPL_DEPTH_8U, 1)
|
||||
>>> pi = Image.fromstring("L", cv.GetSize(cv_im), cv_im.tostring())
|
||||
>>> print pi.size
|
||||
(320, 200)
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{NumPy and OpenCV}
|
||||
|
||||
Using the \href{http://docs.scipy.org/doc/numpy/reference/arrays.interface.html}{array interface}, to use an OpenCV CvMat in NumPy:
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv, numpy
|
||||
>>> mat = cv.CreateMat(3, 5, cv.CV_32FC1)
|
||||
>>> cv.Set(mat, 7)
|
||||
>>> a = numpy.asarray(mat)
|
||||
>>> print a
|
||||
[[ 7. 7. 7. 7. 7.]
|
||||
[ 7. 7. 7. 7. 7.]
|
||||
[ 7. 7. 7. 7. 7.]]
|
||||
\end{lstlisting}
|
||||
|
||||
and to use a NumPy array in OpenCV:
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv, numpy
|
||||
>>> a = numpy.ones((480, 640))
|
||||
>>> mat = cv.fromarray(a)
|
||||
>>> print mat.rows
|
||||
480
|
||||
>>> print mat.cols
|
||||
640
|
||||
\end{lstlisting}
|
||||
|
||||
also, most OpenCV functions can work on NumPy arrays directly, for example:
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> picture = numpy.ones((640, 480))
|
||||
>>> cv.Smooth(picture, picture, cv.CV_GAUSSIAN, 15, 15)
|
||||
\end{lstlisting}
|
||||
|
||||
Given a 2D array,
|
||||
the \cross{fromarray} function (or the implicit version shown above)
|
||||
returns a single-channel \cross{CvMat} of the same size.
|
||||
For a 3D array of size $j \times k \times l$, it returns a
|
||||
\cross{CvMat} sized $j \times k$ with $l$ channels.
|
||||
|
||||
Alternatively, use \cross{fromarray} with the \texttt{allowND} option to always return a \cross{cvMatND}.
|
||||
|
||||
\subsection{OpenCV to pygame}
|
||||
|
||||
To convert an OpenCV image to a \href{http://www.pygame.org/}{pygame} surface:
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import pygame.image, cv
|
||||
>>> src = cv.LoadImage("lena.jpg")
|
||||
>>> src_rgb = cv.CreateMat(src.height, src.width, cv.CV_8UC3)
|
||||
>>> cv.CvtColor(src, src_rgb, cv.CV_BGR2RGB)
|
||||
>>> pg_img = pygame.image.frombuffer(src_rgb.tostring(), cv.GetSize(src_rgb), "RGB")
|
||||
>>> print pg_img
|
||||
<Surface(512x512x24 SW)>
|
||||
\end{lstlisting}
|
||||
|
||||
\subsection{OpenCV and OpenEXR}
|
||||
|
||||
Using \href{http://www.excamera.com/sphinx/articles-openexr.html}{OpenEXR's Python bindings} you can make a simple
|
||||
image viewer:
|
||||
|
||||
\begin{lstlisting}
|
||||
import OpenEXR, Imath, cv
|
||||
filename = "GoldenGate.exr"
|
||||
exrimage = OpenEXR.InputFile(filename)
|
||||
|
||||
dw = exrimage.header()['dataWindow']
|
||||
(width, height) = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1)
|
||||
|
||||
def fromstr(s):
|
||||
mat = cv.CreateMat(height, width, cv.CV_32FC1)
|
||||
cv.SetData(mat, s)
|
||||
return mat
|
||||
|
||||
pt = Imath.PixelType(Imath.PixelType.FLOAT)
|
||||
(r, g, b) = [fromstr(s) for s in exrimage.channels("RGB", pt)]
|
||||
|
||||
bgr = cv.CreateMat(height, width, cv.CV_32FC3)
|
||||
cv.Merge(b, g, r, None, bgr)
|
||||
|
||||
cv.ShowImage(filename, bgr)
|
||||
cv.WaitKey()
|
||||
\end{lstlisting}
|
||||
|
||||
\fi
|
File diff suppressed because it is too large
Load Diff
@ -1,752 +0,0 @@
|
||||
\section{Utility and System Functions and Macros}
|
||||
|
||||
\ifCPy
|
||||
\subsection{Error Handling}\label{Error handling}
|
||||
|
||||
\ifPy
|
||||
Errors in argument type cause a \texttt{TypeError} exception.
|
||||
OpenCV errors cause an \texttt{cv.error} exception.
|
||||
|
||||
For example a function argument that is the wrong type produces a \texttt{TypeError}:
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv
|
||||
>>> cv.LoadImage(4)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
TypeError: argument 1 must be string, not int
|
||||
\end{lstlisting}
|
||||
|
||||
A function with the
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> cv.CreateMat(-1, -1, cv.CV_8UC1)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
error: Non-positive width or height
|
||||
\end{lstlisting}
|
||||
|
||||
\fi
|
||||
|
||||
\ifC % {
|
||||
Error handling in OpenCV is similar to IPL (Image Processing
|
||||
Library). In the case of an error, functions do not return the error
|
||||
code. Instead, they raise an error using \texttt{CV\_ERROR}
|
||||
macro that calls \cvCPyCross{Error} that, in its turn, sets the error
|
||||
status with \cvCPyCross{SetErrStatus} and calls a standard or user-defined
|
||||
error handler (that can display a message box, write to log, etc., see
|
||||
\cvCPyCross{RedirectError}). There is a global variable, one per each program
|
||||
thread, that contains current error status (an integer value). The status
|
||||
can be retrieved with the \cvCPyCross{GetErrStatus} function.
|
||||
|
||||
There are three modes of error handling (see \cvCPyCross{SetErrMode} and
|
||||
\cvCPyCross{GetErrMode}):
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{Leaf}. The program is terminated after the error handler is
|
||||
called. This is the default value. It is useful for debugging, as the
|
||||
error is signalled immediately after it occurs. However, for production
|
||||
systems, other two methods may be preferable as they provide more
|
||||
control.
|
||||
\item \textbf{Parent}. The program is not terminated, but the error handler
|
||||
is called. The stack is unwound (it is done w/o using a C++ exception
|
||||
mechanism). The user may check error code after calling the \texttt{CxCore} function with
|
||||
\cvCPyCross{GetErrStatus} and react.
|
||||
\item \textbf{Silent}. Similar to \texttt{Parent} mode, but no error handler
|
||||
is called.
|
||||
\end{itemize}
|
||||
|
||||
Actually, the semantics of the \texttt{Leaf} and \texttt{Parent} modes are implemented by error handlers and the above description is true for them. \cvCPyCross{GuiBoxReport} behaves slightly differently, and some custom error handlers may implement quite different semantics.
|
||||
|
||||
Macros for raising an error, checking for errors, etc.
|
||||
\begin{lstlisting}
|
||||
|
||||
/* special macros for enclosing processing statements within a function and separating
|
||||
them from prologue (resource initialization) and epilogue (guaranteed resource release) */
|
||||
#define __BEGIN__ {
|
||||
#define __END__ goto exit; exit: ; }
|
||||
/* proceeds to "resource release" stage */
|
||||
#define EXIT goto exit
|
||||
|
||||
/* Declares locally the function name for CV_ERROR() use */
|
||||
#define CV_FUNCNAME( Name ) \
|
||||
static char cvFuncName[] = Name
|
||||
|
||||
/* Raises an error within the current context */
|
||||
#define CV_ERROR( Code, Msg ) \
|
||||
{ \
|
||||
cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); \
|
||||
EXIT; \
|
||||
}
|
||||
|
||||
/* Checks status after calling CXCORE function */
|
||||
#define CV_CHECK() \
|
||||
{ \
|
||||
if( cvGetErrStatus() < 0 ) \
|
||||
CV_ERROR( CV_StsBackTrace, "Inner function failed." ); \
|
||||
}
|
||||
|
||||
/* Provies shorthand for CXCORE function call and CV_CHECK() */
|
||||
#define CV_CALL( Statement ) \
|
||||
{ \
|
||||
Statement; \
|
||||
CV_CHECK(); \
|
||||
}
|
||||
|
||||
/* Checks some condition in both debug and release configurations */
|
||||
#define CV_ASSERT( Condition ) \
|
||||
{ \
|
||||
if( !(Condition) ) \
|
||||
CV_ERROR( CV_StsInternal, "Assertion: " #Condition " failed" ); \
|
||||
}
|
||||
|
||||
/* these macros are similar to their CV_... counterparts, but they
|
||||
do not need exit label nor cvFuncName to be defined */
|
||||
#define OPENCV_ERROR(status,func_name,err_msg) ...
|
||||
#define OPENCV_ERRCHK(func_name,err_msg) ...
|
||||
#define OPENCV_ASSERT(condition,func_name,err_msg) ...
|
||||
#define OPENCV_CALL(statement) ...
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Instead of a discussion, below is a documented example of a typical CXCORE function and an example of the function use.
|
||||
|
||||
\subsection{Example: Use of Error Handling Macros}
|
||||
\begin{lstlisting}
|
||||
|
||||
#include "cxcore.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void cvResizeDCT( CvMat* input_array, CvMat* output_array )
|
||||
{
|
||||
CvMat* temp_array = 0; // declare pointer that should be released anyway.
|
||||
|
||||
CV_FUNCNAME( "cvResizeDCT" ); // declare cvFuncName
|
||||
|
||||
__BEGIN__; // start processing. There may be some declarations just after
|
||||
// this macro, but they could not be accessed from the epilogue.
|
||||
|
||||
if( !CV_IS_MAT(input_array) || !CV_IS_MAT(output_array) )
|
||||
// use CV_ERROR() to raise an error
|
||||
CV_ERROR( CV_StsBadArg,
|
||||
"input_array or output_array are not valid matrices" );
|
||||
|
||||
// some restrictions that are going to be removed later, may be checked
|
||||
// with CV_ASSERT()
|
||||
CV_ASSERT( input_array->rows == 1 && output_array->rows == 1 );
|
||||
|
||||
// use CV_CALL for safe function call
|
||||
CV_CALL( temp_array = cvCreateMat( input_array->rows,
|
||||
MAX(input_array->cols,
|
||||
output_array->cols),
|
||||
input_array->type ));
|
||||
|
||||
if( output_array->cols > input_array->cols )
|
||||
CV_CALL( cvZero( temp_array ));
|
||||
|
||||
temp_array->cols = input_array->cols;
|
||||
CV_CALL( cvDCT( input_array, temp_array, CV_DXT_FORWARD ));
|
||||
temp_array->cols = output_array->cols;
|
||||
CV_CALL( cvDCT( temp_array, output_array, CV_DXT_INVERSE ));
|
||||
CV_CALL( cvScale( output_array,
|
||||
output_array,
|
||||
1./sqrt((double)input_array->cols*output_array->cols), 0 ));
|
||||
|
||||
__END__; // finish processing. Epilogue follows after the macro.
|
||||
|
||||
// release temp_array. If temp_array has not been allocated
|
||||
// before an error occured, cvReleaseMat
|
||||
// takes care of it and does nothing in this case.
|
||||
cvReleaseMat( &temp_array );
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
CvMat* src = cvCreateMat( 1, 512, CV_32F );
|
||||
#if 1 /* no errors */
|
||||
CvMat* dst = cvCreateMat( 1, 256, CV_32F );
|
||||
#else
|
||||
CvMat* dst = 0; /* test error processing mechanism */
|
||||
#endif
|
||||
cvSet( src, cvRealScalar(1.), 0 );
|
||||
#if 0 /* change 0 to 1 to suppress error handler invocation */
|
||||
cvSetErrMode( CV_ErrModeSilent );
|
||||
#endif
|
||||
cvResizeDCT( src, dst ); // if some error occurs, the message
|
||||
// box will popup, or a message will be
|
||||
// written to log, or some user-defined
|
||||
// processing will be done
|
||||
if( cvGetErrStatus() < 0 )
|
||||
printf("Some error occured" );
|
||||
else
|
||||
printf("Everything is OK" );
|
||||
return 0;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCPyFunc{GetErrStatus}
|
||||
Returns the current error status.
|
||||
|
||||
\cvdefC{int cvGetErrStatus( void );}
|
||||
|
||||
The function returns the current error status -
|
||||
the value set with the last \cvCPyCross{SetErrStatus} call. Note that in
|
||||
\texttt{Leaf} mode, the program terminates immediately after an
|
||||
error occurs, so to always gain control after the function call,
|
||||
one should call \cvCPyCross{SetErrMode} and set the \texttt{Parent}
|
||||
or \texttt{Silent} error mode.
|
||||
|
||||
\cvCPyFunc{SetErrStatus}
|
||||
Sets the error status.
|
||||
|
||||
\cvdefC{void cvSetErrStatus( int status );}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{status}{The error status}
|
||||
\end{description}
|
||||
|
||||
The function sets the error status to the specified value. Mostly, the function is used to reset the error status (set to it \texttt{CV\_StsOk}) to recover after an error. In other cases it is more natural to call \cvCPyCross{Error} or \texttt{CV\_ERROR}.
|
||||
|
||||
\cvCPyFunc{GetErrMode}
|
||||
Returns the current error mode.
|
||||
|
||||
\cvdefC{int cvGetErrMode(void);}
|
||||
|
||||
The function returns the current error mode - the value set with the last \cvCPyCross{SetErrMode} call.
|
||||
|
||||
\cvCPyFunc{SetErrMode}
|
||||
Sets the error mode.
|
||||
|
||||
\begin{lstlisting}
|
||||
#define CV_ErrModeLeaf 0
|
||||
#define CV_ErrModeParent 1
|
||||
#define CV_ErrModeSilent 2
|
||||
\end{lstlisting}
|
||||
|
||||
\cvdefC{int cvSetErrMode( int mode );}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{mode}{The error mode}
|
||||
\end{description}
|
||||
|
||||
The function sets the specified error mode. For descriptions of different error modes, see the beginning of the error section.
|
||||
|
||||
\cvCPyFunc{Error}
|
||||
Raises an error.
|
||||
|
||||
\cvdefC{int cvError( \par int status,\par const char* func\_name,\par const char* err\_msg,\par const char* filename,\par int line );}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{status}{The error status}
|
||||
\cvarg{func\_name}{Name of the function where the error occured}
|
||||
\cvarg{err\_msg}{Additional information/diagnostics about the error}
|
||||
\cvarg{filename}{Name of the file where the error occured}
|
||||
\cvarg{line}{Line number, where the error occured}
|
||||
\end{description}
|
||||
|
||||
The function sets the error status to the specified value (via \cvCPyCross{SetErrStatus}) and, if the error mode is not \texttt{Silent}, calls the error handler.
|
||||
|
||||
\cvCPyFunc{ErrorStr}
|
||||
Returns textual description of an error status code.
|
||||
|
||||
\cvdefC{const char* cvErrorStr( int status );}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{status}{The error status}
|
||||
\end{description}
|
||||
|
||||
The function returns the textual description for
|
||||
the specified error status code. In the case of unknown status, the function
|
||||
returns a NULL pointer.
|
||||
|
||||
\cvCPyFunc{RedirectError}
|
||||
Sets a new error handler.
|
||||
|
||||
|
||||
\cvdefC{CvErrorCallback cvRedirectError( \par CvErrorCallback error\_handler,\par void* userdata=NULL,\par void** prevUserdata=NULL );}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{error\_handler}{The new error\_handler}
|
||||
\cvarg{userdata}{Arbitrary pointer that is transparently passed to the error handler}
|
||||
\cvarg{prevUserdata}{Pointer to the previously assigned user data pointer}
|
||||
\end{description}
|
||||
|
||||
\begin{lstlisting}
|
||||
typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name,
|
||||
const char* err_msg, const char* file_name, int line );
|
||||
\end{lstlisting}
|
||||
|
||||
The function sets a new error handler that
|
||||
can be one of the standard handlers or a custom handler
|
||||
that has a specific interface. The handler takes the same parameters
|
||||
as the \cvCPyCross{Error} function. If the handler returns a non-zero value, the
|
||||
program is terminated; otherwise, it continues. The error handler may
|
||||
check the current error mode with \cvCPyCross{GetErrMode} to make a decision.
|
||||
|
||||
|
||||
\cvfunc{cvNulDevReport cvStdErrReport cvGuiBoxReport}
|
||||
\label{cvNulDevReport}
|
||||
\label{cvStdErrReport}
|
||||
\label{cvGuiBoxReport}
|
||||
|
||||
Provide standard error handling.
|
||||
|
||||
\cvdefC{
|
||||
int cvNulDevReport( int status, const char* func\_name,
|
||||
const char* err\_msg, const char* file\_name,
|
||||
int line, void* userdata ); \newline
|
||||
|
||||
int cvStdErrReport( int status, const char* func\_name,
|
||||
const char* err\_msg, const char* file\_name,
|
||||
int line, void* userdata ); \newline
|
||||
|
||||
int cvGuiBoxReport( int status, const char* func\_name,
|
||||
const char* err\_msg, const char* file\_name,
|
||||
int line, void* userdata );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{status}{The error status}
|
||||
\cvarg{func\_name}{Name of the function where the error occured}
|
||||
\cvarg{err\_msg}{Additional information/diagnostics about the error}
|
||||
\cvarg{filename}{Name of the file where the error occured}
|
||||
\cvarg{line}{Line number, where the error occured}
|
||||
\cvarg{userdata}{Pointer to the user data. Ignored by the standard handlers}
|
||||
\end{description}
|
||||
|
||||
The functions \texttt{cvNullDevReport}, \texttt{cvStdErrReport},
|
||||
and \texttt{cvGuiBoxReport} provide standard error
|
||||
handling. \texttt{cvGuiBoxReport} is the default error
|
||||
handler on Win32 systems, \texttt{cvStdErrReport} is the default on other
|
||||
systems. \texttt{cvGuiBoxReport} pops up a message box with the error
|
||||
description and suggest a few options. Below is an example message box
|
||||
that may be recieved with the sample code above, if one introduces an
|
||||
error as described in the sample.
|
||||
|
||||
\textbf{Error Message Box}
|
||||
\includegraphics[width=0.5\textwidth]{pics/errmsg.png}
|
||||
|
||||
If the error handler is set to \texttt{cvStdErrReport}, the above message will be printed to standard error output and the program will be terminated or continued, depending on the current error mode.
|
||||
|
||||
\textbf{Error Message printed to Standard Error Output (in \texttt{Leaf} mode)}
|
||||
|
||||
\begin{lstlisting}
|
||||
OpenCV ERROR: Bad argument (input_array or output_array are not valid matrices)
|
||||
in function cvResizeDCT, D:\User\VP\Projects\avl\_proba\a.cpp(75)
|
||||
Terminating the application...
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCPyFunc{Alloc}
|
||||
Allocates a memory buffer.
|
||||
|
||||
\cvdefC{void* cvAlloc( size\_t size );}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{size}{Buffer size in bytes}
|
||||
\end{description}
|
||||
|
||||
The function allocates \texttt{size} bytes and returns
|
||||
a pointer to the allocated buffer. In the case of an error the function reports an
|
||||
error and returns a NULL pointer. By default, \texttt{cvAlloc} calls
|
||||
\texttt{icvAlloc} which
|
||||
itself calls \texttt{malloc}. However it is possible to assign user-defined memory
|
||||
allocation/deallocation functions using the \cvCPyCross{SetMemoryManager} function.
|
||||
|
||||
\cvCPyFunc{Free}
|
||||
Deallocates a memory buffer.
|
||||
|
||||
\cvdefC{void cvFree( void** ptr );}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{ptr}{Double pointer to released buffer}
|
||||
\end{description}
|
||||
|
||||
The function deallocates a memory buffer allocated by
|
||||
\cvCPyCross{Alloc}. It clears the pointer to buffer upon exit, which is why
|
||||
the double pointer is used. If the \texttt{*buffer} is already NULL, the function
|
||||
does nothing.
|
||||
|
||||
\fi % }
|
||||
|
||||
\cvCPyFunc{GetTickCount}
|
||||
Returns the number of ticks.
|
||||
|
||||
\cvdefC{int64 cvGetTickCount( void );}
|
||||
\cvdefPy{GetTickCount() -> long}
|
||||
|
||||
The function returns number of the ticks starting from some platform-dependent event (number of CPU ticks from the startup, number of milliseconds from 1970th year, etc.). The function is useful for accurate measurement of a function/user-code execution time. To convert the number of ticks to time units, use \cvCPyCross{GetTickFrequency}.
|
||||
|
||||
\cvCPyFunc{GetTickFrequency}
|
||||
Returns the number of ticks per microsecond.
|
||||
|
||||
\cvdefC{double cvGetTickFrequency( void );}
|
||||
\cvdefPy{GetTickFrequency() -> long}
|
||||
|
||||
The function returns the number of ticks per microsecond. Thus, the quotient of \cvCPyCross{GetTickCount} and \cvCPyCross{GetTickFrequency} will give the number of microseconds starting from the platform-dependent event.
|
||||
|
||||
\ifC % {
|
||||
|
||||
\cvCPyFunc{RegisterModule}
|
||||
Registers another module.
|
||||
|
||||
\begin{lstlisting}
|
||||
typedef struct CvPluginFuncInfo
|
||||
{
|
||||
void** func_addr;
|
||||
void* default_func_addr;
|
||||
const char* func_names;
|
||||
int search_modules;
|
||||
int loaded_from;
|
||||
}
|
||||
CvPluginFuncInfo;
|
||||
|
||||
typedef struct CvModuleInfo
|
||||
{
|
||||
struct CvModuleInfo* next;
|
||||
const char* name;
|
||||
const char* version;
|
||||
CvPluginFuncInfo* func_tab;
|
||||
}
|
||||
CvModuleInfo;
|
||||
\end{lstlisting}
|
||||
|
||||
\cvdefC{int cvRegisterModule( const CvModuleInfo* moduleInfo );}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{moduleInfo}{Information about the module}
|
||||
\end{description}
|
||||
|
||||
The function adds a module to the list of
|
||||
registered modules. After the module is registered, information about
|
||||
it can be retrieved using the \cvCPyCross{GetModuleInfo} function. Also, the
|
||||
registered module makes full use of optimized plugins (IPP, MKL, ...),
|
||||
supported by CXCORE. CXCORE itself, CV (computer vision), CVAUX (auxilary
|
||||
computer vision), and HIGHGUI (visualization and image/video acquisition) are
|
||||
examples of modules. Registration is usually done when the shared library
|
||||
is loaded. See \texttt{cxcore/src/cxswitcher.cpp} and
|
||||
\texttt{cv/src/cvswitcher.cpp} for details about how registration is done
|
||||
and look at \texttt{cxcore/src/cxswitcher.cpp}, \texttt{cxcore/src/\_cxipp.h}
|
||||
on how IPP and MKL are connected to the modules.
|
||||
|
||||
\cvCPyFunc{GetModuleInfo}
|
||||
Retrieves information about registered module(s) and plugins.
|
||||
|
||||
\cvdefC{
|
||||
void cvGetModuleInfo( \par const char* moduleName,\par const char** version,\par const char** loadedAddonPlugins);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{moduleName}{Name of the module of interest, or NULL, which means all the modules}
|
||||
\cvarg{version}{The output parameter. Information about the module(s), including version}
|
||||
\cvarg{loadedAddonPlugins}{The list of names and versions of the optimized plugins that CXCORE was able to find and load}
|
||||
\end{description}
|
||||
|
||||
The function returns information about one or
|
||||
all of the registered modules. The returned information is stored inside
|
||||
the libraries, so the user should not deallocate or modify the returned
|
||||
text strings.
|
||||
|
||||
\cvCPyFunc{UseOptimized}
|
||||
Switches between optimized/non-optimized modes.
|
||||
|
||||
\cvdefC{int cvUseOptimized( int onoff );}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{onoff}{Use optimized ($\ne 0$) or not ($=0$)}
|
||||
\end{description}
|
||||
|
||||
The function switches between the mode, where
|
||||
only pure C implementations from cxcore, OpenCV, etc. are used, and
|
||||
the mode, where IPP and MKL functions are used if available. When
|
||||
\texttt{cvUseOptimized(0)} is called, all the optimized libraries are
|
||||
unloaded. The function may be useful for debugging, IPP and MKL upgrading on
|
||||
the fly, online speed comparisons, etc. It returns the number of optimized
|
||||
functions loaded. Note that by default, the optimized plugins are loaded,
|
||||
so it is not necessary to call \texttt{cvUseOptimized(1)} in the beginning of
|
||||
the program (actually, it will only increase the startup time).
|
||||
|
||||
\cvCPyFunc{SetMemoryManager}
|
||||
Accesses custom/default memory managing functions.
|
||||
|
||||
\begin{lstlisting}
|
||||
typedef void* (CV_CDECL *CvAllocFunc)(size_t size, void* userdata);
|
||||
typedef int (CV_CDECL *CvFreeFunc)(void* pptr, void* userdata);
|
||||
\end{lstlisting}
|
||||
|
||||
\cvdefC{
|
||||
void cvSetMemoryManager( \par CvAllocFunc allocFunc=NULL,\par CvFreeFunc freeFunc=NULL,\par void* userdata=NULL );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{allocFunc}{Allocation function; the interface is similar to \texttt{malloc}, except that \texttt{userdata} may be used to determine the context}
|
||||
\cvarg{freeFunc}{Deallocation function; the interface is similar to \texttt{free}}
|
||||
\cvarg{userdata}{User data that is transparently passed to the custom functions}
|
||||
\end{description}
|
||||
|
||||
The function sets user-defined memory
|
||||
managment functions (substitutes for \texttt{malloc} and \texttt{free}) that will be called
|
||||
by \texttt{cvAlloc, cvFree} and higher-level functions (e.g., \texttt{cvCreateImage}). Note
|
||||
that the function should be called when there is data allocated using
|
||||
\texttt{cvAlloc}. Also, to avoid infinite recursive calls, it is not
|
||||
allowed to call \texttt{cvAlloc} and \cvCPyCross{Free} from the custom
|
||||
allocation/deallocation functions.
|
||||
|
||||
If the \texttt{alloc\_func} and \texttt{free\_func} pointers are
|
||||
\texttt{NULL}, the default memory managing functions are restored.
|
||||
|
||||
\cvCPyFunc{SetIPLAllocators}
|
||||
Switches to IPL functions for image allocation/deallocation.
|
||||
|
||||
\begin{lstlisting}
|
||||
typedef IplImage* (CV_STDCALL* Cv_iplCreateImageHeader)
|
||||
(int,int,int,char*,char*,int,int,int,int,int,
|
||||
IplROI*,IplImage*,void*,IplTileInfo*);
|
||||
typedef void (CV_STDCALL* Cv_iplAllocateImageData)(IplImage*,int,int);
|
||||
typedef void (CV_STDCALL* Cv_iplDeallocate)(IplImage*,int);
|
||||
typedef IplROI* (CV_STDCALL* Cv_iplCreateROI)(int,int,int,int,int);
|
||||
typedef IplImage* (CV_STDCALL* Cv_iplCloneImage)(const IplImage*);
|
||||
|
||||
#define CV_TURN_ON_IPL_COMPATIBILITY() \
|
||||
cvSetIPLAllocators( iplCreateImageHeader, iplAllocateImage, \
|
||||
iplDeallocate, iplCreateROI, iplCloneImage )
|
||||
\end{lstlisting}
|
||||
|
||||
\cvdefC{
|
||||
void cvSetIPLAllocators( \par
|
||||
Cv\_iplCreateImageHeader create\_header, \par
|
||||
Cv\_iplAllocateImageData allocate\_data, \par
|
||||
Cv\_iplDeallocate deallocate, \par
|
||||
Cv\_iplCreateROI create\_roi, \par
|
||||
Cv\_iplCloneImage clone\_image );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{create\_header}{Pointer to iplCreateImageHeader}
|
||||
\cvarg{allocate\_data}{Pointer to iplAllocateImage}
|
||||
\cvarg{deallocate}{Pointer to iplDeallocate}
|
||||
\cvarg{create\_roi}{Pointer to iplCreateROI}
|
||||
\cvarg{clone\_image}{Pointer to iplCloneImage}
|
||||
\end{description}
|
||||
|
||||
|
||||
The function causes CXCORE to use IPL functions
|
||||
for image allocation/deallocation operations. For convenience, there
|
||||
is the wrapping macro \texttt{CV\_TURN\_ON\_IPL\_COMPATIBILITY}. The
|
||||
function is useful for applications where IPL and CXCORE/OpenCV are used
|
||||
together and still there are calls to \texttt{iplCreateImageHeader},
|
||||
etc. The function is not necessary if IPL is called only for data
|
||||
processing and all the allocation/deallocation is done by CXCORE, or
|
||||
if all the allocation/deallocation is done by IPL and some of OpenCV
|
||||
functions are used to process the data.
|
||||
|
||||
\fi
|
||||
|
||||
\fi
|
||||
|
||||
\ifCpp
|
||||
|
||||
\cvCppFunc{alignPtr}
|
||||
Aligns pointer to the specified number of bytes
|
||||
|
||||
\cvdefCpp{template<typename \_Tp> \_Tp* alignPtr(\_Tp* ptr, int n=sizeof(\_Tp));}
|
||||
\begin{description}
|
||||
\cvarg{ptr}{The aligned pointer}
|
||||
\cvarg{n}{The alignment size; must be a power of two}
|
||||
\end{description}
|
||||
|
||||
The function returns the aligned pointer of the same type as the input pointer:
|
||||
\[\texttt{(\_Tp*)(((size\_t)ptr + n-1) \& -n)}\]
|
||||
|
||||
|
||||
\cvCppFunc{alignSize}
|
||||
Aligns a buffer size to the specified number of bytes
|
||||
|
||||
\cvdefCpp{size\_t alignSize(size\_t sz, int n);}
|
||||
\begin{description}
|
||||
\cvarg{sz}{The buffer size to align}
|
||||
\cvarg{n}{The alignment size; must be a power of two}
|
||||
\end{description}
|
||||
|
||||
The function returns the minimum number that is greater or equal to \texttt{sz} and is divisble by \texttt{n}:
|
||||
\[\texttt{(sz + n-1) \& -n}\]
|
||||
|
||||
|
||||
\cvCppFunc{allocate}
|
||||
Allocates an array of elements
|
||||
|
||||
\cvdefCpp{template<typename \_Tp> \_Tp* allocate(size\_t n);}
|
||||
\begin{description}
|
||||
\cvarg{n}{The number of elements to allocate}
|
||||
\end{description}
|
||||
|
||||
The generic function \texttt{allocate} allocates buffer for the specified number of elements. For each element the default constructor is called.
|
||||
|
||||
|
||||
\cvCppFunc{deallocate}
|
||||
Allocates an array of elements
|
||||
|
||||
\cvdefCpp{template<typename \_Tp> void deallocate(\_Tp* ptr, size\_t n);}
|
||||
\begin{description}
|
||||
\cvarg{ptr}{Pointer to the deallocated buffer}
|
||||
\cvarg{n}{The number of elements in the buffer}
|
||||
\end{description}
|
||||
|
||||
The generic function \texttt{deallocate} deallocates the buffer allocated with \cvCppCross{allocate}. The number of elements must match the number passed to \cvCppCross{allocate}.
|
||||
|
||||
\cvfunc{CV\_Assert}\label{CV Assert}
|
||||
Checks a condition at runtime.
|
||||
|
||||
\cvdefC{CV\_Assert(expr)}
|
||||
\cvdefCpp{CV\_Assert(expr)}
|
||||
\cvdefPy{CV\_Assert(expr)}
|
||||
|
||||
\begin{lstlisting}
|
||||
#define CV_Assert( expr ) ...
|
||||
#define CV_DbgAssert(expr) ...
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{expr}{The checked expression}
|
||||
\end{description}
|
||||
|
||||
The macros \texttt{CV\_Assert} and \texttt{CV\_DbgAssert} evaluate the specified expression and if it is 0, the macros raise an error (see \cvCppCross{error}). The macro \texttt{CV\_Assert} checks the condition in both Debug and Release configurations, while \texttt{CV\_DbgAssert} is only retained in the Debug configuration.
|
||||
|
||||
\cvCppFunc{error}
|
||||
Signals an error and raises the exception
|
||||
|
||||
\cvdefCpp{void error( const Exception\& exc );\newline
|
||||
\#define CV\_Error( code, msg ) <...>\newline
|
||||
\#define CV\_Error\_( code, args ) <...>}
|
||||
\begin{description}
|
||||
\cvarg{exc}{The exception to throw}
|
||||
\cvarg{code}{The error code, normally, a negative value. The list of pre-defined error codes can be found in \texttt{cxerror.h}}
|
||||
\cvarg{msg}{Text of the error message}
|
||||
\cvarg{args}{printf-like formatted error message in parantheses}
|
||||
\end{description}
|
||||
|
||||
The function and the helper macros \texttt{CV\_Error} and \texttt{CV\_Error\_} call the error handler. Currently, the error handler prints the error code (\texttt{exc.code}), the context (\texttt{exc.file}, \texttt{exc.line} and the error message \texttt{exc.err} to the standard error stream \texttt{stderr}. In Debug configuration it then provokes memory access violation, so that the execution stack and all the parameters can be analyzed in debugger. In Release configuration the exception \texttt{exc} is thrown.
|
||||
|
||||
The macro \texttt{CV\_Error\_} can be used to construct the error message on-fly to include some dynamic information, for example:
|
||||
|
||||
\begin{lstlisting}
|
||||
// note the extra parentheses around the formatted text message
|
||||
CV_Error_(CV_StsOutOfRange,
|
||||
("the matrix element (%d,%d)=%g is out of range",
|
||||
i, j, mtx.at<float>(i,j)))
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvclass{Exception}\label{Exception}
|
||||
The exception class passed to error
|
||||
|
||||
\begin{lstlisting}
|
||||
class Exception
|
||||
{
|
||||
public:
|
||||
// various constructors and the copy operation
|
||||
Exception() { code = 0; line = 0; }
|
||||
Exception(int _code, const string& _err,
|
||||
const string& _func, const string& _file, int _line);
|
||||
Exception(const Exception& exc);
|
||||
Exception& operator = (const Exception& exc);
|
||||
|
||||
// the error code
|
||||
int code;
|
||||
// the error text message
|
||||
string err;
|
||||
// function name where the error happened
|
||||
string func;
|
||||
// the source file name where the error happened
|
||||
string file;
|
||||
// the source file line where the error happened
|
||||
int line;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class \texttt{Exception} encapsulates all or almost all the necessary information about the error happened in the program. The exception is usually constructed and thrown implicitly, via \texttt{CV\_Error} and \texttt{CV\_Error\_} macros, see \cvCppCross{error}.
|
||||
|
||||
|
||||
\cvCppFunc{fastMalloc}
|
||||
Allocates aligned memory buffer
|
||||
|
||||
\cvdefCpp{void* fastMalloc(size\_t size);}
|
||||
\begin{description}
|
||||
\cvarg{size}{The allocated buffer size}
|
||||
\end{description}
|
||||
|
||||
The function allocates buffer of the specified size and returns it. When the buffer size is 16 bytes or more, the returned buffer is aligned on 16 bytes.
|
||||
|
||||
\cvCppFunc{fastFree}
|
||||
Deallocates memory buffer
|
||||
|
||||
\cvdefCpp{void fastFree(void* ptr);}
|
||||
\begin{description}
|
||||
\cvarg{ptr}{Pointer to the allocated buffer}
|
||||
\end{description}
|
||||
|
||||
The function deallocates the buffer, allocated with \cvCppCross{fastMalloc}.
|
||||
If NULL pointer is passed, the function does nothing.
|
||||
|
||||
\cvCppFunc{format}
|
||||
Returns a text string formatted using printf-like expression
|
||||
|
||||
\cvdefCpp{string format( const char* fmt, ... );}
|
||||
\begin{description}
|
||||
\cvarg{fmt}{The printf-compatible formatting specifiers}
|
||||
\end{description}
|
||||
|
||||
The function acts like \texttt{sprintf}, but forms and returns STL string. It can be used for form the error message in \cvCppCross{Exception} constructor.
|
||||
|
||||
\cvCppFunc{getNumThreads}
|
||||
Returns the number of threads used by OpenCV
|
||||
|
||||
\cvdefCpp{int getNumThreads();}
|
||||
|
||||
The function returns the number of threads that is used by OpenCV.
|
||||
|
||||
See also: \cvCppCross{setNumThreads}, \cvCppCross{getThreadNum}.
|
||||
|
||||
|
||||
\cvCppFunc{getThreadNum}
|
||||
Returns index of the currently executed thread
|
||||
|
||||
\cvdefCpp{int getThreadNum();}
|
||||
|
||||
The function returns 0-based index of the currently executed thread. The function is only valid inside a parallel OpenMP region. When OpenCV is built without OpenMP support, the function always returns 0.
|
||||
|
||||
See also: \cvCppCross{setNumThreads}, \cvCppCross{getNumThreads}.
|
||||
|
||||
\cvCppFunc{getTickCount}
|
||||
Returns the number of ticks
|
||||
|
||||
\cvdefCpp{int64 getTickCount();}
|
||||
|
||||
The function returns the number of ticks since the certain event (e.g. when the machine was turned on).
|
||||
It can be used to initialize \cvCppCross{RNG} or to measure a function execution time by reading the tick count before and after the function call. See also the tick frequency.
|
||||
|
||||
\cvCppFunc{getTickFrequency}
|
||||
Returns the number of ticks per second
|
||||
|
||||
\cvdefCpp{double getTickFrequency();}
|
||||
|
||||
The function returns the number of ticks per second.
|
||||
That is, the following code computes the execution time in seconds.
|
||||
\begin{lstlisting}
|
||||
double t = (double)getTickCount();
|
||||
// do something ...
|
||||
t = ((double)getTickCount() - t)/getTickFrequency();
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{setNumThreads}
|
||||
Sets the number of threads used by OpenCV
|
||||
|
||||
\cvdefCpp{void setNumThreads(int nthreads);}
|
||||
\begin{description}
|
||||
\cvarg{nthreads}{The number of threads used by OpenCV}
|
||||
\end{description}
|
||||
|
||||
The function sets the number of threads used by OpenCV in parallel OpenMP regions. If \texttt{nthreads=0}, the function will use the default number of threads, which is usually equal to the number of the processing cores.
|
||||
|
||||
See also: \cvCppCross{getNumThreads}, \cvCppCross{getThreadNum}
|
||||
|
||||
\fi
|
File diff suppressed because it is too large
Load Diff
@ -1,830 +0,0 @@
|
||||
\section{Feature detection and description}
|
||||
|
||||
\ifCpp
|
||||
\cvCppFunc{FAST}
|
||||
Detects corners using FAST algorithm by E. Rosten (''Machine learning for high-speed corner detection'', 2006).
|
||||
\fi
|
||||
|
||||
\cvdefCpp{
|
||||
void FAST( const Mat\& image, vector<KeyPoint>\& keypoints,
|
||||
int threshold, bool nonmaxSupression=true );
|
||||
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{The image. Keypoints (corners) will be detected on this.}
|
||||
\cvarg{keypoints}{Keypoints detected on the image.}
|
||||
\cvarg{threshold}{Threshold on difference between intensity of center pixel and
|
||||
pixels on circle around this pixel. See description of the algorithm.}
|
||||
\cvarg{nonmaxSupression}{If it is true then non-maximum supression will be applied to detected corners (keypoints). }
|
||||
\end{description}
|
||||
|
||||
\ifCPy
|
||||
\ifPy
|
||||
\cvclass{CvSURFPoint}
|
||||
A SURF keypoint, represented as a tuple \texttt{((x, y), laplacian, size, dir, hessian)}.
|
||||
|
||||
\begin{description}
|
||||
\cvarg{x}{x-coordinate of the feature within the image}
|
||||
\cvarg{y}{y-coordinate of the feature within the image}
|
||||
\cvarg{laplacian}{-1, 0 or +1. sign of the laplacian at the point. Can be used to speedup feature comparison since features with laplacians of different signs can not match}
|
||||
\cvarg{size}{size of the feature}
|
||||
\cvarg{dir}{orientation of the feature: 0..360 degrees}
|
||||
\cvarg{hessian}{value of the hessian (can be used to approximately estimate the feature strengths; see also params.hessianThreshold)}
|
||||
\end{description}
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{ExtractSURF}
|
||||
Extracts Speeded Up Robust Features from an image.
|
||||
|
||||
\cvdefC{
|
||||
void cvExtractSURF( \par const CvArr* image,\par const CvArr* mask,\par CvSeq** keypoints,\par CvSeq** descriptors,\par CvMemStorage* storage,\par CvSURFParams params );
|
||||
}
|
||||
\cvdefPy{ExtractSURF(image,mask,storage,params)-> (keypoints,descriptors)}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{The input 8-bit grayscale image}
|
||||
\cvarg{mask}{The optional input 8-bit mask. The features are only found in the areas that contain more than 50\% of non-zero mask pixels}
|
||||
\ifC
|
||||
\cvarg{keypoints}{The output parameter; double pointer to the sequence of keypoints. The sequence of CvSURFPoint structures is as follows:}
|
||||
\begin{lstlisting}
|
||||
typedef struct CvSURFPoint
|
||||
{
|
||||
CvPoint2D32f pt; // position of the feature within the image
|
||||
int laplacian; // -1, 0 or +1. sign of the laplacian at the point.
|
||||
// can be used to speedup feature comparison
|
||||
// (normally features with laplacians of different
|
||||
// signs can not match)
|
||||
int size; // size of the feature
|
||||
float dir; // orientation of the feature: 0..360 degrees
|
||||
float hessian; // value of the hessian (can be used to
|
||||
// approximately estimate the feature strengths;
|
||||
// see also params.hessianThreshold)
|
||||
}
|
||||
CvSURFPoint;
|
||||
\end{lstlisting}
|
||||
\cvarg{descriptors}{The optional output parameter; double pointer to the sequence of descriptors. Depending on the params.extended value, each element of the sequence will be either a 64-element or a 128-element floating-point (\texttt{CV\_32F}) vector. If the parameter is NULL, the descriptors are not computed}
|
||||
\else
|
||||
\cvarg{keypoints}{sequence of keypoints.}
|
||||
\cvarg{descriptors}{sequence of descriptors. Each SURF descriptor is a list of floats, of length 64 or 128.}
|
||||
\fi
|
||||
\cvarg{storage}{Memory storage where keypoints and descriptors will be stored}
|
||||
\ifC
|
||||
\cvarg{params}{Various algorithm parameters put to the structure CvSURFParams:}
|
||||
\begin{lstlisting}
|
||||
typedef struct CvSURFParams
|
||||
{
|
||||
int extended; // 0 means basic descriptors (64 elements each),
|
||||
// 1 means extended descriptors (128 elements each)
|
||||
double hessianThreshold; // only features with keypoint.hessian
|
||||
// larger than that are extracted.
|
||||
// good default value is ~300-500 (can depend on the
|
||||
// average local contrast and sharpness of the image).
|
||||
// user can further filter out some features based on
|
||||
// their hessian values and other characteristics.
|
||||
int nOctaves; // the number of octaves to be used for extraction.
|
||||
// With each next octave the feature size is doubled
|
||||
// (3 by default)
|
||||
int nOctaveLayers; // The number of layers within each octave
|
||||
// (4 by default)
|
||||
}
|
||||
CvSURFParams;
|
||||
|
||||
CvSURFParams cvSURFParams(double hessianThreshold, int extended=0);
|
||||
// returns default parameters
|
||||
\end{lstlisting}
|
||||
\else
|
||||
\cvarg{params}{Various algorithm parameters in a tuple \texttt{(extended, hessianThreshold, nOctaves, nOctaveLayers)}:
|
||||
\begin{description}
|
||||
\cvarg{extended}{0 means basic descriptors (64 elements each), 1 means extended descriptors (128 elements each)}
|
||||
\cvarg{hessianThreshold}{only features with hessian larger than that are extracted. good default value is ~300-500 (can depend on the average local contrast and sharpness of the image). user can further filter out some features based on their hessian values and other characteristics.}
|
||||
\cvarg{nOctaves}{the number of octaves to be used for extraction. With each next octave the feature size is doubled (3 by default)}
|
||||
\cvarg{nOctaveLayers}{The number of layers within each octave (4 by default)}
|
||||
\end{description}}
|
||||
\fi
|
||||
\end{description}
|
||||
|
||||
The function cvExtractSURF finds robust features in the image, as
|
||||
described in \cite{Bay06}. For each feature it returns its location, size,
|
||||
orientation and optionally the descriptor, basic or extended. The function
|
||||
can be used for object tracking and localization, image stitching etc.
|
||||
|
||||
\ifC
|
||||
See the
|
||||
\texttt{find\_obj.cpp} demo in OpenCV samples directory.
|
||||
\else
|
||||
To extract strong SURF features from an image
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv
|
||||
>>> im = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE)
|
||||
>>> (keypoints, descriptors) = cv.ExtractSURF(im, None, cv.CreateMemStorage(), (0, 30000, 3, 1))
|
||||
>>> print len(keypoints), len(descriptors)
|
||||
6 6
|
||||
>>> for ((x, y), laplacian, size, dir, hessian) in keypoints:
|
||||
... print "x=\%d y=\%d laplacian=\%d size=\%d dir=\%f hessian=\%f" \% (x, y, laplacian, size, dir, hessian)
|
||||
x=30 y=27 laplacian=-1 size=31 dir=69.778503 hessian=36979.789062
|
||||
x=296 y=197 laplacian=1 size=33 dir=111.081039 hessian=31514.349609
|
||||
x=296 y=266 laplacian=1 size=32 dir=107.092300 hessian=31477.908203
|
||||
x=254 y=284 laplacian=1 size=31 dir=279.137360 hessian=34169.800781
|
||||
x=498 y=525 laplacian=-1 size=33 dir=278.006592 hessian=31002.759766
|
||||
x=777 y=281 laplacian=1 size=70 dir=167.940964 hessian=35538.363281
|
||||
\end{lstlisting}
|
||||
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{GetStarKeypoints}
|
||||
Retrieves keypoints using the StarDetector algorithm.
|
||||
|
||||
\cvdefC{
|
||||
CvSeq* cvGetStarKeypoints( \par const CvArr* image,\par CvMemStorage* storage,\par CvStarDetectorParams params=cvStarDetectorParams() );
|
||||
}
|
||||
\cvdefPy{GetStarKeypoints(image,storage,params)-> keypoints}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{The input 8-bit grayscale image}
|
||||
\cvarg{storage}{Memory storage where the keypoints will be stored}
|
||||
\ifC
|
||||
\cvarg{params}{Various algorithm parameters given to the structure CvStarDetectorParams:}
|
||||
\begin{lstlisting}
|
||||
typedef struct CvStarDetectorParams
|
||||
{
|
||||
int maxSize; // maximal size of the features detected. The following
|
||||
// values of the parameter are supported:
|
||||
// 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128
|
||||
int responseThreshold; // threshold for the approximatd laplacian,
|
||||
// used to eliminate weak features
|
||||
int lineThresholdProjected; // another threshold for laplacian to
|
||||
// eliminate edges
|
||||
int lineThresholdBinarized; // another threshold for the feature
|
||||
// scale to eliminate edges
|
||||
int suppressNonmaxSize; // linear size of a pixel neighborhood
|
||||
// for non-maxima suppression
|
||||
}
|
||||
CvStarDetectorParams;
|
||||
\end{lstlisting}
|
||||
\else
|
||||
\cvarg{params}{Various algorithm parameters in a tuple \texttt{(maxSize, responseThreshold, lineThresholdProjected, lineThresholdBinarized, suppressNonmaxSize)}:
|
||||
\begin{description}
|
||||
\cvarg{maxSize}{maximal size of the features detected. The following values of the parameter are supported: 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128}
|
||||
\cvarg{responseThreshold}{threshold for the approximatd laplacian, used to eliminate weak features}
|
||||
\cvarg{lineThresholdProjected}{another threshold for laplacian to eliminate edges}
|
||||
\cvarg{lineThresholdBinarized}{another threshold for the feature scale to eliminate edges}
|
||||
\cvarg{suppressNonmaxSize}{linear size of a pixel neighborhood for non-maxima suppression}
|
||||
\end{description}
|
||||
}
|
||||
\fi
|
||||
\end{description}
|
||||
|
||||
The function GetStarKeypoints extracts keypoints that are local
|
||||
scale-space extremas. The scale-space is constructed by computing
|
||||
approximate values of laplacians with different sigma's at each
|
||||
pixel. Instead of using pyramids, a popular approach to save computing
|
||||
time, all of the laplacians are computed at each pixel of the original
|
||||
high-resolution image. But each approximate laplacian value is computed
|
||||
in O(1) time regardless of the sigma, thanks to the use of integral
|
||||
images. The algorithm is based on the paper
|
||||
Agrawal08
|
||||
, but instead
|
||||
of a square, hexagon or octagon it uses an 8-end star shape, hence the name,
|
||||
consisting of overlapping upright and tilted squares.
|
||||
|
||||
\ifC
|
||||
Each computed feature is represented by the following structure:
|
||||
|
||||
\begin{lstlisting}
|
||||
typedef struct CvStarKeypoint
|
||||
{
|
||||
CvPoint pt; // coordinates of the feature
|
||||
int size; // feature size, see CvStarDetectorParams::maxSize
|
||||
float response; // the approximated laplacian value at that point.
|
||||
}
|
||||
CvStarKeypoint;
|
||||
|
||||
inline CvStarKeypoint cvStarKeypoint(CvPoint pt, int size, float response);
|
||||
\end{lstlisting}
|
||||
\else
|
||||
Each keypoint is represented by a tuple \texttt{((x, y), size, response)}:
|
||||
\begin{description}
|
||||
\cvarg{x, y}{Screen coordinates of the keypoint}
|
||||
\cvarg{size}{feature size, up to \texttt{maxSize}}
|
||||
\cvarg{response}{approximated laplacian value for the keypoint}
|
||||
\end{description}
|
||||
\fi
|
||||
|
||||
\ifC
|
||||
Below is the small usage sample:
|
||||
|
||||
\begin{lstlisting}
|
||||
#include "cv.h"
|
||||
#include "highgui.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* filename = argc > 1 ? argv[1] : "lena.jpg";
|
||||
IplImage* img = cvLoadImage( filename, 0 ), *cimg;
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
CvSeq* keypoints = 0;
|
||||
int i;
|
||||
|
||||
if( !img )
|
||||
return 0;
|
||||
cvNamedWindow( "image", 1 );
|
||||
cvShowImage( "image", img );
|
||||
cvNamedWindow( "features", 1 );
|
||||
cimg = cvCreateImage( cvGetSize(img), 8, 3 );
|
||||
cvCvtColor( img, cimg, CV_GRAY2BGR );
|
||||
|
||||
keypoints = cvGetStarKeypoints( img, storage, cvStarDetectorParams(45) );
|
||||
|
||||
for( i = 0; i < (keypoints ? keypoints->total : 0); i++ )
|
||||
{
|
||||
CvStarKeypoint kpt = *(CvStarKeypoint*)cvGetSeqElem(keypoints, i);
|
||||
int r = kpt.size/2;
|
||||
cvCircle( cimg, kpt.pt, r, CV_RGB(0,255,0));
|
||||
cvLine( cimg, cvPoint(kpt.pt.x + r, kpt.pt.y + r),
|
||||
cvPoint(kpt.pt.x - r, kpt.pt.y - r), CV_RGB(0,255,0));
|
||||
cvLine( cimg, cvPoint(kpt.pt.x - r, kpt.pt.y + r),
|
||||
cvPoint(kpt.pt.x + r, kpt.pt.y - r), CV_RGB(0,255,0));
|
||||
}
|
||||
cvShowImage( "features", cimg );
|
||||
cvWaitKey();
|
||||
}
|
||||
\end{lstlisting}
|
||||
\fi
|
||||
|
||||
\fi
|
||||
\ifCpp
|
||||
|
||||
\cvclass{MSER}
|
||||
Maximally-Stable Extremal Region Extractor
|
||||
|
||||
\begin{lstlisting}
|
||||
class MSER : public CvMSERParams
|
||||
{
|
||||
public:
|
||||
// default constructor
|
||||
MSER();
|
||||
// constructor that initializes all the algorithm parameters
|
||||
MSER( int _delta, int _min_area, int _max_area,
|
||||
float _max_variation, float _min_diversity,
|
||||
int _max_evolution, double _area_threshold,
|
||||
double _min_margin, int _edge_blur_size );
|
||||
// runs the extractor on the specified image; returns the MSERs,
|
||||
// each encoded as a contour (vector<Point>, see findContours)
|
||||
// the optional mask marks the area where MSERs are searched for
|
||||
void operator()( const Mat& image, vector<vector<Point> >& msers, const Mat& mask ) const;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class encapsulates all the parameters of MSER (see \url{http://en.wikipedia.org/wiki/Maximally_stable_extremal_regions}) extraction algorithm.
|
||||
|
||||
\cvclass{StarDetector}
|
||||
Implements Star keypoint detector
|
||||
|
||||
\begin{lstlisting}
|
||||
class StarDetector : CvStarDetectorParams
|
||||
{
|
||||
public:
|
||||
// default constructor
|
||||
StarDetector();
|
||||
// the full constructor initialized all the algorithm parameters:
|
||||
// maxSize - maximum size of the features. The following
|
||||
// values of the parameter are supported:
|
||||
// 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128
|
||||
// responseThreshold - threshold for the approximated laplacian,
|
||||
// used to eliminate weak features. The larger it is,
|
||||
// the less features will be retrieved
|
||||
// lineThresholdProjected - another threshold for the laplacian to
|
||||
// eliminate edges
|
||||
// lineThresholdBinarized - another threshold for the feature
|
||||
// size to eliminate edges.
|
||||
// The larger the 2 threshold, the more points you get.
|
||||
StarDetector(int maxSize, int responseThreshold,
|
||||
int lineThresholdProjected,
|
||||
int lineThresholdBinarized,
|
||||
int suppressNonmaxSize);
|
||||
|
||||
// finds keypoints in an image
|
||||
void operator()(const Mat& image, vector<KeyPoint>& keypoints) const;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class implements a modified version of CenSurE keypoint detector described in
|
||||
\cite{Agrawal08}
|
||||
|
||||
\cvclass{SIFT}
|
||||
Class for extracting keypoints and computing descriptors using approach named Scale Invariant Feature Transform (SIFT).
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS SIFT
|
||||
{
|
||||
public:
|
||||
struct CommonParams
|
||||
{
|
||||
static const int DEFAULT_NOCTAVES = 4;
|
||||
static const int DEFAULT_NOCTAVE_LAYERS = 3;
|
||||
static const int DEFAULT_FIRST_OCTAVE = -1;
|
||||
enum{ FIRST_ANGLE = 0, AVERAGE_ANGLE = 1 };
|
||||
|
||||
CommonParams();
|
||||
CommonParams( int _nOctaves, int _nOctaveLayers, int _firstOctave,
|
||||
int _angleMode );
|
||||
int nOctaves, nOctaveLayers, firstOctave;
|
||||
int angleMode;
|
||||
};
|
||||
|
||||
struct DetectorParams
|
||||
{
|
||||
static double GET_DEFAULT_THRESHOLD()
|
||||
{ return 0.04 / SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS / 2.0; }
|
||||
static double GET_DEFAULT_EDGE_THRESHOLD() { return 10.0; }
|
||||
|
||||
DetectorParams();
|
||||
DetectorParams( double _threshold, double _edgeThreshold );
|
||||
double threshold, edgeThreshold;
|
||||
};
|
||||
|
||||
struct DescriptorParams
|
||||
{
|
||||
static double GET_DEFAULT_MAGNIFICATION() { return 3.0; }
|
||||
static const bool DEFAULT_IS_NORMALIZE = true;
|
||||
static const int DESCRIPTOR_SIZE = 128;
|
||||
|
||||
DescriptorParams();
|
||||
DescriptorParams( double _magnification, bool _isNormalize,
|
||||
bool _recalculateAngles );
|
||||
double magnification;
|
||||
bool isNormalize;
|
||||
bool recalculateAngles;
|
||||
};
|
||||
|
||||
SIFT();
|
||||
//! sift-detector constructor
|
||||
SIFT( double _threshold, double _edgeThreshold,
|
||||
int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
|
||||
int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
|
||||
int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
|
||||
int _angleMode=CommonParams::FIRST_ANGLE );
|
||||
//! sift-descriptor constructor
|
||||
SIFT( double _magnification, bool _isNormalize=true,
|
||||
bool _recalculateAngles = true,
|
||||
int _nOctaves=CommonParams::DEFAULT_NOCTAVES,
|
||||
int _nOctaveLayers=CommonParams::DEFAULT_NOCTAVE_LAYERS,
|
||||
int _firstOctave=CommonParams::DEFAULT_FIRST_OCTAVE,
|
||||
int _angleMode=CommonParams::FIRST_ANGLE );
|
||||
SIFT( const CommonParams& _commParams,
|
||||
const DetectorParams& _detectorParams = DetectorParams(),
|
||||
const DescriptorParams& _descriptorParams = DescriptorParams() );
|
||||
|
||||
//! returns the descriptor size in floats (128)
|
||||
int descriptorSize() const { return DescriptorParams::DESCRIPTOR_SIZE; }
|
||||
//! finds the keypoints using SIFT algorithm
|
||||
void operator()(const Mat& img, const Mat& mask,
|
||||
vector<KeyPoint>& keypoints) const;
|
||||
//! finds the keypoints and computes descriptors for them using SIFT algorithm.
|
||||
//! Optionally it can compute descriptors for the user-provided keypoints
|
||||
void operator()(const Mat& img, const Mat& mask,
|
||||
vector<KeyPoint>& keypoints,
|
||||
Mat& descriptors,
|
||||
bool useProvidedKeypoints=false) const;
|
||||
|
||||
CommonParams getCommonParams () const { return commParams; }
|
||||
DetectorParams getDetectorParams () const { return detectorParams; }
|
||||
DescriptorParams getDescriptorParams () const { return descriptorParams; }
|
||||
protected:
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvclass{SURF}\label{cv.class.SURF}
|
||||
Class for extracting Speeded Up Robust Features from an image.
|
||||
|
||||
\begin{lstlisting}
|
||||
class SURF : public CvSURFParams
|
||||
{
|
||||
public:
|
||||
// default constructor
|
||||
SURF();
|
||||
// constructor that initializes all the algorithm parameters
|
||||
SURF(double _hessianThreshold, int _nOctaves=4,
|
||||
int _nOctaveLayers=2, bool _extended=false);
|
||||
// returns the number of elements in each descriptor (64 or 128)
|
||||
int descriptorSize() const;
|
||||
// detects keypoints using fast multi-scale Hessian detector
|
||||
void operator()(const Mat& img, const Mat& mask,
|
||||
vector<KeyPoint>& keypoints) const;
|
||||
// detects keypoints and computes the SURF descriptors for them;
|
||||
// output vector "descriptors" stores elements of descriptors and has size
|
||||
// equal descriptorSize()*keypoints.size() as each descriptor is
|
||||
// descriptorSize() elements of this vector.
|
||||
void operator()(const Mat& img, const Mat& mask,
|
||||
vector<KeyPoint>& keypoints,
|
||||
vector<float>& descriptors,
|
||||
bool useProvidedKeypoints=false) const;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class \texttt{SURF} implements Speeded Up Robust Features descriptor \cite{Bay06}.
|
||||
There is fast multi-scale Hessian keypoint detector that can be used to find the keypoints
|
||||
(which is the default option), but the descriptors can be also computed for the user-specified keypoints.
|
||||
The function can be used for object tracking and localization, image stitching etc. See the
|
||||
\texttt{find\_obj.cpp} demo in OpenCV samples directory.
|
||||
|
||||
\cvclass{RandomizedTree}
|
||||
The class contains base structure for \texttt{RTreeClassifier}
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS RandomizedTree
|
||||
{
|
||||
public:
|
||||
friend class RTreeClassifier;
|
||||
|
||||
RandomizedTree();
|
||||
~RandomizedTree();
|
||||
|
||||
void train(std::vector<BaseKeypoint> const& base_set,
|
||||
cv::RNG &rng, int depth, int views,
|
||||
size_t reduced_num_dim, int num_quant_bits);
|
||||
void train(std::vector<BaseKeypoint> const& base_set,
|
||||
cv::RNG &rng, PatchGenerator &make_patch, int depth,
|
||||
int views, size_t reduced_num_dim, int num_quant_bits);
|
||||
|
||||
// following two funcs are EXPERIMENTAL
|
||||
//(do not use unless you know exactly what you do)
|
||||
static void quantizeVector(float *vec, int dim, int N, float bnds[2],
|
||||
int clamp_mode=0);
|
||||
static void quantizeVector(float *src, int dim, int N, float bnds[2],
|
||||
uchar *dst);
|
||||
|
||||
// patch_data must be a 32x32 array (no row padding)
|
||||
float* getPosterior(uchar* patch_data);
|
||||
const float* getPosterior(uchar* patch_data) const;
|
||||
uchar* getPosterior2(uchar* patch_data);
|
||||
|
||||
void read(const char* file_name, int num_quant_bits);
|
||||
void read(std::istream &is, int num_quant_bits);
|
||||
void write(const char* file_name) const;
|
||||
void write(std::ostream &os) const;
|
||||
|
||||
int classes() { return classes_; }
|
||||
int depth() { return depth_; }
|
||||
|
||||
void discardFloatPosteriors() { freePosteriors(1); }
|
||||
|
||||
inline void applyQuantization(int num_quant_bits)
|
||||
{ makePosteriors2(num_quant_bits); }
|
||||
|
||||
private:
|
||||
int classes_;
|
||||
int depth_;
|
||||
int num_leaves_;
|
||||
std::vector<RTreeNode> nodes_;
|
||||
float **posteriors_; // 16-bytes aligned posteriors
|
||||
uchar **posteriors2_; // 16-bytes aligned posteriors
|
||||
std::vector<int> leaf_counts_;
|
||||
|
||||
void createNodes(int num_nodes, cv::RNG &rng);
|
||||
void allocPosteriorsAligned(int num_leaves, int num_classes);
|
||||
void freePosteriors(int which);
|
||||
// which: 1=posteriors_, 2=posteriors2_, 3=both
|
||||
void init(int classes, int depth, cv::RNG &rng);
|
||||
void addExample(int class_id, uchar* patch_data);
|
||||
void finalize(size_t reduced_num_dim, int num_quant_bits);
|
||||
int getIndex(uchar* patch_data) const;
|
||||
inline float* getPosteriorByIndex(int index);
|
||||
inline uchar* getPosteriorByIndex2(int index);
|
||||
inline const float* getPosteriorByIndex(int index) const;
|
||||
void convertPosteriorsToChar();
|
||||
void makePosteriors2(int num_quant_bits);
|
||||
void compressLeaves(size_t reduced_num_dim);
|
||||
void estimateQuantPercForPosteriors(float perc[2]);
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{RandomizedTree::train}
|
||||
Trains a randomized tree using input set of keypoints
|
||||
|
||||
\cvdefCpp{
|
||||
void train(std::vector<BaseKeypoint> const\& base\_set, cv::RNG \&rng,
|
||||
PatchGenerator \&make\_patch, int depth, int views, size\_t reduced\_num\_dim,
|
||||
int num\_quant\_bits);
|
||||
}
|
||||
\cvdefCpp{
|
||||
void train(std::vector<BaseKeypoint> const\& base\_set, cv::RNG \&rng,
|
||||
PatchGenerator \&make\_patch, int depth, int views, size\_t reduced\_num\_dim,
|
||||
int num\_quant\_bits);
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{base\_set} {Vector of \texttt{BaseKeypoint} type. Contains keypoints from the image are used for training}
|
||||
\cvarg{rng} {Random numbers generator is used for training}
|
||||
\cvarg{make\_patch} {Patch generator is used for training}
|
||||
\cvarg{depth} {Maximum tree depth}
|
||||
%\cvarg{views} {}
|
||||
\cvarg{reduced\_num\_dim} {Number of dimensions are used in compressed signature}
|
||||
\cvarg{num\_quant\_bits} {Number of bits are used for quantization}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{RandomizedTree::read}
|
||||
Reads pre-saved randomized tree from file or stream
|
||||
\cvdefCpp{read(const char* file\_name, int num\_quant\_bits)}
|
||||
\cvdefCpp{read(std::istream \&is, int num\_quant\_bits)}
|
||||
\begin{description}
|
||||
\cvarg{file\_name}{Filename of file contains randomized tree data}
|
||||
\cvarg{is}{Input stream associated with file contains randomized tree data}
|
||||
\cvarg{num\_quant\_bits} {Number of bits are used for quantization}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{RandomizedTree::write}
|
||||
Writes current randomized tree to a file or stream
|
||||
\cvdefCpp{void write(const char* file\_name) const;}
|
||||
\cvdefCpp{void write(std::ostream \&os) const;}
|
||||
\begin{description}
|
||||
\cvarg{file\_name}{Filename of file where randomized tree data will be stored}
|
||||
\cvarg{is}{Output stream associated with file where randomized tree data will be stored}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{RandomizedTree::applyQuantization}
|
||||
Applies quantization to the current randomized tree
|
||||
\cvdefCpp{void applyQuantization(int num\_quant\_bits)}
|
||||
\begin{description}
|
||||
\cvarg{num\_quant\_bits} {Number of bits are used for quantization}
|
||||
\end{description}
|
||||
|
||||
\cvclass{RTreeNode}
|
||||
The class contains base structure for \texttt{RandomizedTree}
|
||||
|
||||
\begin{lstlisting}
|
||||
struct RTreeNode
|
||||
{
|
||||
short offset1, offset2;
|
||||
|
||||
RTreeNode() {}
|
||||
|
||||
RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2)
|
||||
: offset1(y1*PATCH_SIZE + x1),
|
||||
offset2(y2*PATCH_SIZE + x2)
|
||||
{}
|
||||
|
||||
//! Left child on 0, right child on 1
|
||||
inline bool operator() (uchar* patch_data) const
|
||||
{
|
||||
return patch_data[offset1] > patch_data[offset2];
|
||||
}
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvclass{RTreeClassifier}
|
||||
The class contains \texttt{RTreeClassifier}. It represents calonder descriptor which was originally introduced by Michael Calonder
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS RTreeClassifier
|
||||
{
|
||||
public:
|
||||
static const int DEFAULT_TREES = 48;
|
||||
static const size_t DEFAULT_NUM_QUANT_BITS = 4;
|
||||
|
||||
RTreeClassifier();
|
||||
|
||||
void train(std::vector<BaseKeypoint> const& base_set,
|
||||
cv::RNG &rng,
|
||||
int num_trees = RTreeClassifier::DEFAULT_TREES,
|
||||
int depth = DEFAULT_DEPTH,
|
||||
int views = DEFAULT_VIEWS,
|
||||
size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
|
||||
int num_quant_bits = DEFAULT_NUM_QUANT_BITS,
|
||||
bool print_status = true);
|
||||
void train(std::vector<BaseKeypoint> const& base_set,
|
||||
cv::RNG &rng,
|
||||
PatchGenerator &make_patch,
|
||||
int num_trees = RTreeClassifier::DEFAULT_TREES,
|
||||
int depth = DEFAULT_DEPTH,
|
||||
int views = DEFAULT_VIEWS,
|
||||
size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
|
||||
int num_quant_bits = DEFAULT_NUM_QUANT_BITS,
|
||||
bool print_status = true);
|
||||
|
||||
// sig must point to a memory block of at least
|
||||
//classes()*sizeof(float|uchar) bytes
|
||||
void getSignature(IplImage *patch, uchar *sig);
|
||||
void getSignature(IplImage *patch, float *sig);
|
||||
void getSparseSignature(IplImage *patch, float *sig,
|
||||
float thresh);
|
||||
|
||||
static int countNonZeroElements(float *vec, int n, double tol=1e-10);
|
||||
static inline void safeSignatureAlloc(uchar **sig, int num_sig=1,
|
||||
int sig_len=176);
|
||||
static inline uchar* safeSignatureAlloc(int num_sig=1,
|
||||
int sig_len=176);
|
||||
|
||||
inline int classes() { return classes_; }
|
||||
inline int original_num_classes()
|
||||
{ return original_num_classes_; }
|
||||
|
||||
void setQuantization(int num_quant_bits);
|
||||
void discardFloatPosteriors();
|
||||
|
||||
void read(const char* file_name);
|
||||
void read(std::istream &is);
|
||||
void write(const char* file_name) const;
|
||||
void write(std::ostream &os) const;
|
||||
|
||||
std::vector<RandomizedTree> trees_;
|
||||
|
||||
private:
|
||||
int classes_;
|
||||
int num_quant_bits_;
|
||||
uchar **posteriors_;
|
||||
ushort *ptemp_;
|
||||
int original_num_classes_;
|
||||
bool keep_floats_;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{RTreeClassifier::train}
|
||||
Trains a randomized tree classificator using input set of keypoints
|
||||
\cvdefCpp{
|
||||
void train(std::vector<BaseKeypoint> const\& base\_set,
|
||||
cv::RNG \&rng,
|
||||
int num\_trees = RTreeClassifier::DEFAULT\_TREES,
|
||||
int depth = DEFAULT\_DEPTH,
|
||||
int views = DEFAULT\_VIEWS,
|
||||
size\_t reduced\_num\_dim = DEFAULT\_REDUCED\_NUM\_DIM,
|
||||
int num\_quant\_bits = DEFAULT\_NUM\_QUANT\_BITS, bool print\_status = true);
|
||||
}
|
||||
\cvdefCpp{
|
||||
void train(std::vector<BaseKeypoint> const\& base\_set,
|
||||
cv::RNG \&rng,
|
||||
PatchGenerator \&make\_patch,
|
||||
int num\_trees = RTreeClassifier::DEFAULT\_TREES,
|
||||
int depth = DEFAULT\_DEPTH,
|
||||
int views = DEFAULT\_VIEWS,
|
||||
size\_t reduced\_num\_dim = DEFAULT\_REDUCED\_NUM\_DIM,
|
||||
int num\_quant\_bits = DEFAULT\_NUM\_QUANT\_BITS, bool print\_status = true);
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{base\_set} {Vector of \texttt{BaseKeypoint} type. Contains keypoints from the image are used for training}
|
||||
\cvarg{rng} {Random numbers generator is used for training}
|
||||
\cvarg{make\_patch} {Patch generator is used for training}
|
||||
\cvarg{num\_trees} {Number of randomized trees used in RTreeClassificator}
|
||||
\cvarg{depth} {Maximum tree depth}
|
||||
%\cvarg{views} {}
|
||||
\cvarg{reduced\_num\_dim} {Number of dimensions are used in compressed signature}
|
||||
\cvarg{num\_quant\_bits} {Number of bits are used for quantization}
|
||||
\cvarg{print\_status} {Print current status of training on the console}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{RTreeClassifier::getSignature}
|
||||
Returns signature for image patch
|
||||
\cvdefCpp{
|
||||
void getSignature(IplImage *patch, uchar *sig)
|
||||
}
|
||||
\cvdefCpp{
|
||||
void getSignature(IplImage *patch, float *sig)
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{patch} {Image patch to calculate signature for}
|
||||
\cvarg{sig} {Output signature (array dimension is \texttt{reduced\_num\_dim)}}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{RTreeClassifier::getSparseSignature}
|
||||
The function is simular to \texttt{getSignature} but uses the threshold for removing all signature elements less than the threshold. So that the signature is compressed
|
||||
\cvdefCpp{
|
||||
void getSparseSignature(IplImage *patch, float *sig,
|
||||
float thresh);
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{patch} {Image patch to calculate signature for}
|
||||
\cvarg{sig} {Output signature (array dimension is \texttt{reduced\_num\_dim)}}
|
||||
\cvarg{tresh} {The threshold that is used for compressing the signature}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{RTreeClassifier::countNonZeroElements}
|
||||
The function returns the number of non-zero elements in the input array.
|
||||
\cvdefCpp{
|
||||
static int countNonZeroElements(float *vec, int n, double tol=1e-10);
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{vec}{Input vector contains float elements}
|
||||
\cvarg{n}{Input vector size}
|
||||
\cvarg{tol} {The threshold used for elements counting. We take all elements are less than \texttt{tol} as zero elements}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{RTreeClassifier::read}
|
||||
Reads pre-saved RTreeClassifier from file or stream
|
||||
\cvdefCpp{read(const char* file\_name)}
|
||||
\cvdefCpp{read(std::istream \&is)}
|
||||
\begin{description}
|
||||
\cvarg{file\_name}{Filename of file contains randomized tree data}
|
||||
\cvarg{is}{Input stream associated with file contains randomized tree data}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{RTreeClassifier::write}
|
||||
Writes current RTreeClassifier to a file or stream
|
||||
\cvdefCpp{void write(const char* file\_name) const;}
|
||||
\cvdefCpp{void write(std::ostream \&os) const;}
|
||||
\begin{description}
|
||||
\cvarg{file\_name}{Filename of file where randomized tree data will be stored}
|
||||
\cvarg{is}{Output stream associated with file where randomized tree data will be stored}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{RTreeClassifier::setQuantization}
|
||||
Applies quantization to the current randomized tree
|
||||
\cvdefCpp{void setQuantization(int num\_quant\_bits)}
|
||||
\begin{description}
|
||||
\cvarg{num\_quant\_bits} {Number of bits are used for quantization}
|
||||
\end{description}
|
||||
|
||||
Below there is an example of \texttt{RTreeClassifier} usage for feature matching. There are test and train images and we extract features from both with SURF. Output is $best\_corr$ and $best\_corr\_idx$ arrays which keep the best probabilities and corresponding features indexes for every train feature.
|
||||
% ===== Example. Using RTreeClassifier for features matching =====
|
||||
\begin{lstlisting}
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
CvSeq *objectKeypoints = 0, *objectDescriptors = 0;
|
||||
CvSeq *imageKeypoints = 0, *imageDescriptors = 0;
|
||||
CvSURFParams params = cvSURFParams(500, 1);
|
||||
cvExtractSURF( test_image, 0, &imageKeypoints, &imageDescriptors,
|
||||
storage, params );
|
||||
cvExtractSURF( train_image, 0, &objectKeypoints, &objectDescriptors,
|
||||
storage, params );
|
||||
|
||||
cv::RTreeClassifier detector;
|
||||
int patch_width = cv::PATCH_SIZE;
|
||||
iint patch_height = cv::PATCH_SIZE;
|
||||
vector<cv::BaseKeypoint> base_set;
|
||||
int i=0;
|
||||
CvSURFPoint* point;
|
||||
for (i=0;i<(n_points > 0 ? n_points : objectKeypoints->total);i++)
|
||||
{
|
||||
point=(CvSURFPoint*)cvGetSeqElem(objectKeypoints,i);
|
||||
base_set.push_back(
|
||||
cv::BaseKeypoint(point->pt.x,point->pt.y,train_image));
|
||||
}
|
||||
|
||||
//Detector training
|
||||
cv::RNG rng( cvGetTickCount() );
|
||||
cv::PatchGenerator gen(0,255,2,false,0.7,1.3,-CV_PI/3,CV_PI/3,
|
||||
-CV_PI/3,CV_PI/3);
|
||||
|
||||
printf("RTree Classifier training...\n");
|
||||
detector.train(base_set,rng,gen,24,cv::DEFAULT_DEPTH,2000,
|
||||
(int)base_set.size(), detector.DEFAULT_NUM_QUANT_BITS);
|
||||
printf("Done\n");
|
||||
|
||||
float* signature = new float[detector.original_num_classes()];
|
||||
float* best_corr;
|
||||
int* best_corr_idx;
|
||||
if (imageKeypoints->total > 0)
|
||||
{
|
||||
best_corr = new float[imageKeypoints->total];
|
||||
best_corr_idx = new int[imageKeypoints->total];
|
||||
}
|
||||
|
||||
for(i=0; i < imageKeypoints->total; i++)
|
||||
{
|
||||
point=(CvSURFPoint*)cvGetSeqElem(imageKeypoints,i);
|
||||
int part_idx = -1;
|
||||
float prob = 0.0f;
|
||||
|
||||
CvRect roi = cvRect((int)(point->pt.x) - patch_width/2,
|
||||
(int)(point->pt.y) - patch_height/2,
|
||||
patch_width, patch_height);
|
||||
cvSetImageROI(test_image, roi);
|
||||
roi = cvGetImageROI(test_image);
|
||||
if(roi.width != patch_width || roi.height != patch_height)
|
||||
{
|
||||
best_corr_idx[i] = part_idx;
|
||||
best_corr[i] = prob;
|
||||
}
|
||||
else
|
||||
{
|
||||
cvSetImageROI(test_image, roi);
|
||||
IplImage* roi_image =
|
||||
cvCreateImage(cvSize(roi.width, roi.height),
|
||||
test_image->depth, test_image->nChannels);
|
||||
cvCopy(test_image,roi_image);
|
||||
|
||||
detector.getSignature(roi_image, signature);
|
||||
for (int j = 0; j< detector.original_num_classes();j++)
|
||||
{
|
||||
if (prob < signature[j])
|
||||
{
|
||||
part_idx = j;
|
||||
prob = signature[j];
|
||||
}
|
||||
}
|
||||
|
||||
best_corr_idx[i] = part_idx;
|
||||
best_corr[i] = prob;
|
||||
|
||||
|
||||
if (roi_image)
|
||||
cvReleaseImage(&roi_image);
|
||||
}
|
||||
cvResetImageROI(test_image);
|
||||
}
|
||||
|
||||
\end{lstlisting}
|
||||
\fi
|
@ -1,159 +0,0 @@
|
||||
\cvclass{DynamicAdaptedFeatureDetector}
|
||||
An adaptively adjusting detector that iteratively detects until the desired number
|
||||
of features are found.
|
||||
|
||||
If the detector is persisted, it will "remember" the parameters
|
||||
used on the last detection. In this way, the detector may be used for consistent numbers
|
||||
of keypoints in a sets of images that are temporally related such as video streams or
|
||||
panorama series.
|
||||
|
||||
The DynamicAdaptedFeatureDetector uses another detector such as FAST or SURF to do the dirty work,
|
||||
with the help of an AdjusterAdapter.
|
||||
After a detection, and an unsatisfactory number of features are detected,
|
||||
the AdjusterAdapter will adjust the detection parameters so that the next detection will
|
||||
result in more or less features. This is repeated until either the number of desired features are found
|
||||
or the parameters are maxed out.
|
||||
|
||||
Adapters can easily be implemented for any detector via the
|
||||
AdjusterAdapter interface.
|
||||
|
||||
Beware that this is not thread safe - as the adjustment of parameters breaks the const
|
||||
of the detection routine...
|
||||
|
||||
Here is a sample of how to create a DynamicAdaptedFeatureDetector.
|
||||
\begin{lstlisting}
|
||||
//sample usage:
|
||||
//will create a detector that attempts to find
|
||||
//100 - 110 FAST Keypoints, and will at most run
|
||||
//FAST feature detection 10 times until that
|
||||
//number of keypoints are found
|
||||
Ptr<FeatureDetector> detector(new DynamicAdaptedFeatureDetector (100, 110, 10,
|
||||
new FastAdjuster(20,true)));
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{lstlisting}
|
||||
class DynamicAdaptedFeatureDetector: public FeatureDetector
|
||||
{
|
||||
public:
|
||||
DynamicAdaptedFeatureDetector( const Ptr<AdjusterAdapter>& adjaster,
|
||||
int min_features=400, int max_features=500, int max_iters=5 );
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{DynamicAdaptedFeatureDetector::DynamicAdaptedFeatureDetector}
|
||||
DynamicAdaptedFeatureDetector constructor.
|
||||
\cvdefCpp{
|
||||
DynamicAdaptedFeatureDetector::DynamicAdaptedFeatureDetector(
|
||||
\par const Ptr<AdjusterAdapter>\& adjaster,
|
||||
\par int min\_features, \par int max\_features, \par int max\_iters );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{adjaster}{ An \cvCppCross{AdjusterAdapter} that will do the detection and parameter
|
||||
adjustment}
|
||||
\cvarg{min\_features}{This minimum desired number features.}
|
||||
\cvarg{max\_features}{The maximum desired number of features.}
|
||||
\cvarg{max\_iters}{The maximum number of times to try to adjust the feature detector parameters. For the \cvCppCross{FastAdjuster} this number can be high,
|
||||
but with Star or Surf, many iterations can get time consuming. At each iteration the detector is rerun, so keep this in mind when choosing this value.}
|
||||
\end{description}
|
||||
|
||||
\cvclass{AdjusterAdapter}
|
||||
A feature detector parameter adjuster interface, this is used by the \cvCppCross{DynamicAdaptedFeatureDetector}
|
||||
and is a wrapper for \cvCppCross{FeatureDetecto}r that allow them to be adjusted after a detection.
|
||||
|
||||
See \cvCppCross{FastAdjuster}, \cvCppCross{StarAdjuster}, \cvCppCross{SurfAdjuster} for concrete implementations.
|
||||
\begin{lstlisting}
|
||||
class AdjusterAdapter: public FeatureDetector
|
||||
{
|
||||
public:
|
||||
virtual ~AdjusterAdapter() {}
|
||||
virtual void tooFew(int min, int n_detected) = 0;
|
||||
virtual void tooMany(int max, int n_detected) = 0;
|
||||
virtual bool good() const = 0;
|
||||
};
|
||||
\end{lstlisting}
|
||||
\cvCppFunc{AdjusterAdapter::tooFew}
|
||||
\cvdefCpp{
|
||||
virtual void tooFew(int min, int n\_detected) = 0;
|
||||
}
|
||||
Too few features were detected so, adjust the detector parameters accordingly - so that the next
|
||||
detection detects more features.
|
||||
\begin{description}
|
||||
\cvarg{min}{This minimum desired number features.}
|
||||
\cvarg{n\_detected}{The actual number detected last run.}
|
||||
\end{description}
|
||||
An example implementation of this is
|
||||
\begin{lstlisting}
|
||||
void FastAdjuster::tooFew(int min, int n_detected)
|
||||
{
|
||||
thresh_--;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{AdjusterAdapter::tooMany}
|
||||
Too many features were detected so, adjust the detector parameters accordingly - so that the next
|
||||
detection detects less features.
|
||||
\cvdefCpp{
|
||||
virtual void tooMany(int max, int n\_detected) = 0;
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{max}{This maximum desired number features.}
|
||||
\cvarg{n\_detected}{The actual number detected last run.}
|
||||
\end{description}
|
||||
An example implementation of this is
|
||||
\begin{lstlisting}
|
||||
void FastAdjuster::tooMany(int min, int n_detected)
|
||||
{
|
||||
thresh_++;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{AdjusterAdapter::good}
|
||||
Are params maxed out or still valid? Returns false if the parameters can't be adjusted any more.
|
||||
\cvdefCpp{
|
||||
virtual bool good() const = 0;
|
||||
}
|
||||
An example implementation of this is
|
||||
\begin{lstlisting}
|
||||
bool FastAdjuster::good() const
|
||||
{
|
||||
return (thresh_ > 1) && (thresh_ < 200);
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\cvclass{FastAdjuster}
|
||||
An \cvCppCross{AdjusterAdapter} for the \cvCppCross{FastFeatureDetector}. This will basically decrement or increment the
|
||||
threshhold by 1
|
||||
|
||||
\begin{lstlisting}
|
||||
class FastAdjuster FastAdjuster: public AdjusterAdapter
|
||||
{
|
||||
public:
|
||||
FastAdjuster(int init_thresh = 20, bool nonmax = true);
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvclass{StarAdjuster}
|
||||
An \cvCppCross{AdjusterAdapter} for the \cvCppCross{StarFeatureDetector}. This adjusts the responseThreshhold of
|
||||
StarFeatureDetector.
|
||||
\begin{lstlisting}
|
||||
class StarAdjuster: public AdjusterAdapter
|
||||
{
|
||||
StarAdjuster(double initial_thresh = 30.0);
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvclass{SurfAdjuster}
|
||||
An \cvCppCross{AdjusterAdapter} for the \cvCppCross{SurfFeatureDetector}. This adjusts the hessianThreshold of
|
||||
SurfFeatureDetector.
|
||||
\begin{lstlisting}
|
||||
class SurfAdjuster: public SurfAdjuster
|
||||
{
|
||||
SurfAdjuster();
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
@ -1,200 +0,0 @@
|
||||
\ifCpp
|
||||
\section{Object Categorization}
|
||||
Some approaches based on local 2D features and used to object categorization
|
||||
are described in this section.
|
||||
|
||||
\cvclass{BOWTrainer}
|
||||
Abstract base class for training ''bag of visual words'' vocabulary from a set of descriptors.
|
||||
See e.g. ''Visual Categorization with Bags of Keypoints'' of Gabriella Csurka, Christopher R. Dance,
|
||||
Lixin Fan, Jutta Willamowski, Cedric Bray, 2004.
|
||||
|
||||
\begin{lstlisting}
|
||||
class BOWTrainer
|
||||
{
|
||||
public:
|
||||
BOWTrainer(){}
|
||||
virtual ~BOWTrainer(){}
|
||||
|
||||
void add( const Mat& descriptors );
|
||||
const vector<Mat>& getDescriptors() const;
|
||||
int descripotorsCount() const;
|
||||
|
||||
virtual void clear();
|
||||
|
||||
virtual Mat cluster() const = 0;
|
||||
virtual Mat cluster( const Mat& descriptors ) const = 0;
|
||||
|
||||
protected:
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{BOWTrainer::add}
|
||||
Add descriptors to training set. The training set will be clustered using \texttt{cluster}
|
||||
method to construct vocabulary.
|
||||
|
||||
\cvdefCpp{
|
||||
void BOWTrainer::add( const Mat\& descriptors );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{descriptors}{Descriptors to add to training set. Each row of \texttt{descriptors}
|
||||
matrix is a one descriptor.}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{BOWTrainer::getDescriptors}
|
||||
Returns training set of descriptors.
|
||||
|
||||
\cvdefCpp{
|
||||
const vector<Mat>\& BOWTrainer::getDescriptors() const;
|
||||
}
|
||||
|
||||
\cvCppFunc{BOWTrainer::descripotorsCount}
|
||||
Returns count of all descriptors stored in the training set.
|
||||
|
||||
\cvdefCpp{
|
||||
const vector<Mat>\& BOWTrainer::descripotorsCount() const;
|
||||
}
|
||||
|
||||
\cvCppFunc{BOWTrainer::cluster}
|
||||
Cluster train descriptors. Vocabulary consists from cluster centers. So this method
|
||||
returns vocabulary. In first method variant the stored in object train descriptors will be
|
||||
clustered, in second variant -- input descriptors will be clustered.
|
||||
|
||||
\cvdefCpp{
|
||||
Mat BOWTrainer::cluster() const;
|
||||
}
|
||||
|
||||
\cvdefCpp{
|
||||
Mat BOWTrainer::cluster( const Mat\& descriptors ) const;
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{descriptors}{Descriptors to cluster. Each row of \texttt{descriptors}
|
||||
matrix is a one descriptor. Descriptors will not be added
|
||||
to the inner train descriptor set.}
|
||||
\end{description}
|
||||
|
||||
\cvclass{BOWKMeansTrainer}
|
||||
\cvCppCross{kmeans} based class to train visual vocabulary using the ''bag of visual words'' approach.
|
||||
|
||||
\begin{lstlisting}
|
||||
class BOWKMeansTrainer : public BOWTrainer
|
||||
{
|
||||
public:
|
||||
BOWKMeansTrainer( int clusterCount, const TermCriteria& termcrit=TermCriteria(),
|
||||
int attempts=3, int flags=KMEANS_PP_CENTERS );
|
||||
virtual ~BOWKMeansTrainer(){}
|
||||
|
||||
// Returns trained vocabulary (i.e. cluster centers).
|
||||
virtual Mat cluster() const;
|
||||
virtual Mat cluster( const Mat& descriptors ) const;
|
||||
|
||||
protected:
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
To gain an understanding of constructor parameters see \cvCppCross{kmeans} function
|
||||
arguments.
|
||||
|
||||
|
||||
\cvclass{BOWImgDescriptorExtractor}
|
||||
Class to compute image descriptor using ''bad of visual words''. In few,
|
||||
such computing consists from the following steps:
|
||||
1. Compute descriptors for given image and it's keypoints set, \\
|
||||
2. Find nearest visual words from vocabulary for each keypoint descriptor, \\
|
||||
3. Image descriptor is a normalized histogram of vocabulary words encountered in the image. I.e.
|
||||
\texttt{i}-bin of the histogram is a frequency of \texttt{i}-word of vocabulary in the given image.
|
||||
|
||||
\begin{lstlisting}
|
||||
class BOWImgDescriptorExtractor
|
||||
{
|
||||
public:
|
||||
BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor,
|
||||
const Ptr<DescriptorMatcher>& dmatcher );
|
||||
virtual ~BOWImgDescriptorExtractor(){}
|
||||
|
||||
void setVocabulary( const Mat& vocabulary );
|
||||
const Mat& getVocabulary() const;
|
||||
void compute( const Mat& image, vector<KeyPoint>& keypoints,
|
||||
Mat& imgDescriptor,
|
||||
vector<vector<int> >* pointIdxsOfClusters=0,
|
||||
Mat* descriptors=0 );
|
||||
int descriptorSize() const;
|
||||
int descriptorType() const;
|
||||
|
||||
protected:
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{BOWImgDescriptorExtractor::BOWImgDescriptorExtractor}
|
||||
Constructor.
|
||||
|
||||
\cvdefCpp{
|
||||
BOWImgDescriptorExtractor::BOWImgDescriptorExtractor(
|
||||
\par const Ptr<DescriptorExtractor>\& dextractor,
|
||||
\par const Ptr<DescriptorMatcher>\& dmatcher );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{dextractor}{Descriptor extractor that will be used to compute descriptors
|
||||
for input image and it's keypoints.}
|
||||
\cvarg{dmatcher}{Descriptor matcher that will be used to find nearest word of trained vocabulary to
|
||||
each keupoints descriptor of the image.}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{BOWImgDescriptorExtractor::setVocabulary}
|
||||
Method to set visual vocabulary.
|
||||
|
||||
\cvdefCpp{
|
||||
void BOWImgDescriptorExtractor::setVocabulary( const Mat\& vocabulary );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{vocabulary}{Vocabulary (can be trained using inheritor of \cvCppCross{BOWTrainer}).
|
||||
Each row of vocabulary is a one visual word (cluster center).}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{BOWImgDescriptorExtractor::getVocabulary}
|
||||
Returns set vocabulary.
|
||||
|
||||
\cvdefCpp{
|
||||
const Mat\& BOWImgDescriptorExtractor::getVocabulary() const;
|
||||
}
|
||||
|
||||
\cvCppFunc{BOWImgDescriptorExtractor::compute}
|
||||
Compute image descriptor using set visual vocabulary.
|
||||
|
||||
\cvdefCpp{
|
||||
void BOWImgDescriptorExtractor::compute( const Mat\& image,
|
||||
\par vector<KeyPoint>\& keypoints, Mat\& imgDescriptor,
|
||||
\par vector<vector<int> >* pointIdxsOfClusters=0,
|
||||
\par Mat* descriptors=0 );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{The image. Image descriptor will be computed for this.}
|
||||
\cvarg{keypoints}{Keypoints detected in the input image.}
|
||||
\cvarg{imgDescriptor}{This is output, i.e. computed image descriptor.}
|
||||
\cvarg{pointIdxsOfClusters}{Indices of keypoints which belong to the cluster, i.e.
|
||||
\texttt{pointIdxsOfClusters[i]} is keypoint indices which belong
|
||||
to the \texttt{i-}cluster (word of vocabulary) (returned if it is not 0.)}
|
||||
\cvarg{descriptors}{Descriptors of the image keypoints (returned if it is not 0.)}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{BOWImgDescriptorExtractor::descriptorSize}
|
||||
Returns image discriptor size, if vocabulary was set, and 0 otherwise.
|
||||
|
||||
\cvdefCpp{
|
||||
int BOWImgDescriptorExtractor::descriptorSize() const;
|
||||
}
|
||||
|
||||
\cvCppFunc{BOWImgDescriptorExtractor::descriptorType}
|
||||
Returns image descriptor type.
|
||||
|
||||
\cvdefCpp{
|
||||
int BOWImgDescriptorExtractor::descriptorType() const;
|
||||
}
|
||||
|
||||
\fi
|
253
doc/flann.tex
253
doc/flann.tex
@ -1,253 +0,0 @@
|
||||
\section{Fast Approximate Nearest Neighbor Search}
|
||||
|
||||
\ifCpp
|
||||
|
||||
This section documents OpenCV's interface to the FLANN\footnote{http://people.cs.ubc.ca/\~mariusm/flann} library. FLANN (Fast Library for Approximate Nearest Neighbors) is a library that
|
||||
contains a collection of algorithms optimized for fast nearest neighbor search in large datasets and for high dimensional features. More
|
||||
information about FLANN can be found in \cite{muja_flann_2009}.
|
||||
|
||||
\ifplastex
|
||||
\cvclass{cv::flann::Index_}
|
||||
\else
|
||||
\subsection{cv::flann::Index\_}\label{cvflann.Index}
|
||||
\fi
|
||||
The FLANN nearest neighbor index class. This class is templated with the type of elements for which the index is built.
|
||||
|
||||
\begin{lstlisting}
|
||||
namespace cv
|
||||
{
|
||||
namespace flann
|
||||
{
|
||||
template <typename T>
|
||||
class Index_
|
||||
{
|
||||
public:
|
||||
Index_(const Mat& features, const IndexParams& params);
|
||||
|
||||
~Index_();
|
||||
|
||||
void knnSearch(const vector<T>& query,
|
||||
vector<int>& indices,
|
||||
vector<float>& dists,
|
||||
int knn,
|
||||
const SearchParams& params);
|
||||
void knnSearch(const Mat& queries,
|
||||
Mat& indices,
|
||||
Mat& dists,
|
||||
int knn,
|
||||
const SearchParams& params);
|
||||
|
||||
int radiusSearch(const vector<T>& query,
|
||||
vector<int>& indices,
|
||||
vector<float>& dists,
|
||||
float radius,
|
||||
const SearchParams& params);
|
||||
int radiusSearch(const Mat& query,
|
||||
Mat& indices,
|
||||
Mat& dists,
|
||||
float radius,
|
||||
const SearchParams& params);
|
||||
|
||||
void save(std::string filename);
|
||||
|
||||
int veclen() const;
|
||||
|
||||
int size() const;
|
||||
|
||||
const IndexParams* getIndexParameters();
|
||||
};
|
||||
|
||||
typedef Index_<float> Index;
|
||||
|
||||
} } // namespace cv::flann
|
||||
\end{lstlisting}
|
||||
|
||||
\ifplastex
|
||||
\cvCppFunc{cv::flann::Index_<T>::Index_}
|
||||
\else
|
||||
\subsection{cvflann::Index\_$<T>$::Index\_}\label{cvflann.Index.Index}
|
||||
\fi
|
||||
Constructs a nearest neighbor search index for a given dataset.
|
||||
|
||||
\cvdefCpp{Index\_<T>::Index\_(const Mat\& features, const IndexParams\& params);}
|
||||
\begin{description}
|
||||
\cvarg{features}{ Matrix of containing the features(points) to index. The size of the matrix is num\_features x feature\_dimensionality and
|
||||
the data type of the elements in the matrix must coincide with the type of the index.}
|
||||
\cvarg{params}{Structure containing the index parameters. The type of index that will be constructed depends on the type of this parameter.
|
||||
The possible parameter types are:}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{LinearIndexParams}{When passing an object of this type, the index will perform a linear, brute-force search.}
|
||||
\begin{lstlisting}
|
||||
struct LinearIndexParams : public IndexParams
|
||||
{
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvarg{KDTreeIndexParams}{When passing an object of this type the index constructed will consist of a set of randomized kd-trees which will be searched in parallel.}
|
||||
\begin{lstlisting}
|
||||
struct KDTreeIndexParams : public IndexParams
|
||||
{
|
||||
KDTreeIndexParams( int trees = 4 );
|
||||
};
|
||||
\end{lstlisting}
|
||||
\begin{description}
|
||||
\cvarg{trees}{The number of parallel kd-trees to use. Good values are in the range [1..16]}
|
||||
\end{description}
|
||||
|
||||
\cvarg{KMeansIndexParams}{When passing an object of this type the index constructed will be a hierarchical k-means tree.}
|
||||
\begin{lstlisting}
|
||||
struct KMeansIndexParams : public IndexParams
|
||||
{
|
||||
KMeansIndexParams(
|
||||
int branching = 32,
|
||||
int iterations = 11,
|
||||
flann_centers_init_t centers_init = FLANN_CENTERS_RANDOM,
|
||||
float cb_index = 0.2 );
|
||||
};
|
||||
\end{lstlisting}
|
||||
\begin{description}
|
||||
\cvarg{branching}{ The branching factor to use for the hierarchical k-means tree }
|
||||
\cvarg{iterations}{ The maximum number of iterations to use in the k-means clustering stage when building the k-means tree. A value of -1 used here means that the k-means clustering should be iterated until convergence}
|
||||
\cvarg{centers\_init}{The algorithm to use for selecting the initial centers when performing a k-means clustering step. The possible values are \texttt{FLANN\_CENTERS\_RANDOM} (picks the initial cluster centers randomly), \texttt{FLANN\_CENTERS\_GONZALES} (picks the initial centers using Gonzales' algorithm) and \texttt{FLANN\_CENTERS\_KMEANSPP} (picks the initial centers using the algorithm suggested in \cite{arthur_kmeanspp_2007})}
|
||||
\cvarg{cb\_index}{This parameter (cluster boundary index) influences the way exploration is performed in the hierarchical kmeans tree. When \texttt{cb\_index} is zero the next kmeans domain to be explored is choosen to be the one with the closest center. A value greater then zero also takes into account the size of the domain.}
|
||||
\end{description}
|
||||
|
||||
\cvarg{CompositeIndexParams}{When using a parameters object of this type the index created combines the randomized kd-trees and the hierarchical k-means tree.}
|
||||
\begin{lstlisting}
|
||||
struct CompositeIndexParams : public IndexParams
|
||||
{
|
||||
CompositeIndexParams(
|
||||
int trees = 4,
|
||||
int branching = 32,
|
||||
int iterations = 11,
|
||||
flann_centers_init_t centers_init = FLANN_CENTERS_RANDOM,
|
||||
float cb_index = 0.2 );
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvarg{AutotunedIndexParams}{When passing an object of this type the index created is automatically tuned to offer the best performance, by choosing the optimal index type (randomized kd-trees, hierarchical kmeans, linear) and parameters for the dataset provided.}
|
||||
\begin{lstlisting}
|
||||
struct AutotunedIndexParams : public IndexParams
|
||||
{
|
||||
AutotunedIndexParams(
|
||||
float target_precision = 0.9,
|
||||
float build_weight = 0.01,
|
||||
float memory_weight = 0,
|
||||
float sample_fraction = 0.1 );
|
||||
};
|
||||
\end{lstlisting}
|
||||
\begin{description}
|
||||
\cvarg{target\_precision}{ Is a number between 0 and 1 specifying the percentage of the approximate nearest-neighbor searches that return the exact nearest-neighbor. Using a higher value for this parameter gives more accurate results, but the search takes longer. The optimum value usually depends on the application. }
|
||||
|
||||
\cvarg{build\_weight}{ Specifies the importance of the index build time raported to the nearest-neighbor search time. In some applications it's acceptable for the index build step to take a long time if the subsequent searches in the index can be performed very fast. In other applications it's required that the index be build as fast as possible even if that leads to slightly longer search times.}
|
||||
|
||||
\cvarg{memory\_weight}{Is used to specify the tradeoff between time (index build time and search time) and memory used by the index. A value less than 1 gives more importance to the time spent and a value greater than 1 gives more importance to the memory usage.}
|
||||
|
||||
\cvarg{sample\_fraction}{Is a number between 0 and 1 indicating what fraction of the dataset to use in the automatic parameter configuration algorithm. Running the algorithm on the full dataset gives the most accurate results, but for very large datasets can take longer than desired. In such case using just a fraction of the data helps speeding up this algorithm while still giving good approximations of the optimum parameters.}
|
||||
\end{description}
|
||||
|
||||
\cvarg{SavedIndexParams}{This object type is used for loading a previously saved index from the disk.}
|
||||
\begin{lstlisting}
|
||||
struct SavedIndexParams : public IndexParams
|
||||
{
|
||||
SavedIndexParams( std::string filename );
|
||||
};
|
||||
\end{lstlisting}
|
||||
\begin{description}
|
||||
\cvarg{filename}{ The filename in which the index was saved. }
|
||||
\end{description}
|
||||
\end{description}
|
||||
\end{description}
|
||||
|
||||
\ifplastex
|
||||
\cvCppFunc{cv::flann::Index_<T>::knnSearch}
|
||||
\else
|
||||
\subsection{cv::flann::Index\_$<T>$::knnSearch}\label{cvflann.Index.knnSearch}
|
||||
\fi
|
||||
Performs a K-nearest neighbor search for a given query point using the index.
|
||||
\cvdefCpp{
|
||||
void Index\_<T>::knnSearch(const vector<T>\& query, \par
|
||||
vector<int>\& indices, \par
|
||||
vector<float>\& dists, \par
|
||||
int knn, \par
|
||||
const SearchParams\& params);\newline
|
||||
void Index\_<T>::knnSearch(const Mat\& queries,\par
|
||||
Mat\& indices, Mat\& dists,\par
|
||||
int knn, const SearchParams\& params);}
|
||||
\begin{description}
|
||||
\cvarg{query}{The query point}
|
||||
\cvarg{indices}{Vector that will contain the indices of the K-nearest neighbors found. It must have at least knn size.}
|
||||
\cvarg{dists}{Vector that will contain the distances to the K-nearest neighbors found. It must have at least knn size.}
|
||||
\cvarg{knn}{Number of nearest neighbors to search for.}
|
||||
\cvarg{params}{Search parameters}
|
||||
\begin{lstlisting}
|
||||
struct SearchParams {
|
||||
SearchParams(int checks = 32);
|
||||
};
|
||||
\end{lstlisting}
|
||||
\begin{description}
|
||||
\cvarg{checks}{ The number of times the tree(s) in the index should be recursively traversed. A higher value for this parameter would give better search precision, but also take more time. If automatic configuration was used when the index was created, the number of checks required to achieve the specified precision was also computed, in which case this parameter is ignored.}
|
||||
\end{description}
|
||||
\end{description}
|
||||
|
||||
\ifplastex
|
||||
\cvCppFunc{cv::flann::Index_<T>::radiusSearch}
|
||||
\else
|
||||
\subsection{cv::flann::Index\_$<T>$::radiusSearch}\label{cvflann.Index.radiusSearch}
|
||||
\fi
|
||||
Performs a radius nearest neighbor search for a given query point.
|
||||
\cvdefCpp{
|
||||
int Index\_<T>::radiusSearch(const vector<T>\& query, \par
|
||||
vector<int>\& indices, \par
|
||||
vector<float>\& dists, \par
|
||||
float radius, \par
|
||||
const SearchParams\& params);\newline
|
||||
int Index\_<T>::radiusSearch(const Mat\& query, \par
|
||||
Mat\& indices, \par
|
||||
Mat\& dists, \par
|
||||
float radius, \par
|
||||
const SearchParams\& params);}
|
||||
\begin{description}
|
||||
\cvarg{query}{The query point}
|
||||
\cvarg{indices}{Vector that will contain the indices of the points found within the search radius in decreasing order of the distance to the query point. If the number of neighbors in the search radius is bigger than the size of this vector, the ones that don't fit in the vector are ignored. }
|
||||
\cvarg{dists}{Vector that will contain the distances to the points found within the search radius}
|
||||
\cvarg{radius}{The search radius}
|
||||
\cvarg{params}{Search parameters}
|
||||
\end{description}
|
||||
|
||||
\ifplastex
|
||||
\cvCppFunc{cv::flann::Index_<T>::save}
|
||||
\else
|
||||
\subsection{cv::flann::Index\_$<T>$::save}\label{cvflann.Index.save}
|
||||
\fi
|
||||
|
||||
Saves the index to a file.
|
||||
\cvdefCpp{void Index\_<T>::save(std::string filename);}
|
||||
\begin{description}
|
||||
\cvarg{filename}{The file to save the index to}
|
||||
\end{description}
|
||||
|
||||
\ifplastex
|
||||
\cvCppFunc{cv::flann::Index_<T>::getIndexParameters}
|
||||
\else
|
||||
\subsection{cv::flann::Index\_$<T>$::getIndexParameters}\label{cvflann.Index.getIndexParameters}
|
||||
\fi
|
||||
|
||||
Returns the index paramreters. This is usefull in case of autotuned indices, when the parameters computed can be retrived using this method.
|
||||
\cvdefCpp{const IndexParams* Index\_<T>::getIndexParameters();}
|
||||
|
||||
\section{Clustering}
|
||||
|
||||
\cvCppFunc{cv::flann::hierarchicalClustering<ET,DT>}
|
||||
Clusters the given points by constructing a hierarchical k-means tree and choosing a cut in the tree that minimizes the cluster's variance.
|
||||
\cvdefCpp{int hierarchicalClustering<ET,DT>(const Mat\& features, Mat\& centers,\par
|
||||
const KMeansIndexParams\& params);}
|
||||
\begin{description}
|
||||
\cvarg{features}{The points to be clustered. The matrix must have elements of type ET.}
|
||||
\cvarg{centers}{The centers of the clusters obtained. The matrix must have type DT. The number of rows in this matrix represents the number of clusters desired, however, because of the way the cut in the hierarchical tree is chosen, the number of clusters computed will be the highest number of the form \texttt{(branching-1)*k+1} that's lower than the number of clusters desired, where \texttt{branching} is the tree's branching factor (see description of the KMeansIndexParams).}
|
||||
\cvarg{params}{Parameters used in the construction of the hierarchical k-means tree}
|
||||
\end{description}
|
||||
The function returns the number of clusters computed.
|
||||
|
||||
\fi
|
@ -1,461 +0,0 @@
|
||||
\section{Camera Calibration and 3d Reconstruction}
|
||||
|
||||
|
||||
\cvclass{gpu::StereoBM\_GPU}
|
||||
The class for computing stereo correspondence using block matching algorithm.
|
||||
|
||||
\begin{lstlisting}
|
||||
class StereoBM_GPU
|
||||
{
|
||||
public:
|
||||
enum { BASIC_PRESET = 0, PREFILTER_XSOBEL = 1 };
|
||||
|
||||
enum { DEFAULT_NDISP = 64, DEFAULT_WINSZ = 19 };
|
||||
|
||||
StereoBM_GPU();
|
||||
StereoBM_GPU(int preset, int ndisparities = DEFAULT_NDISP,
|
||||
int winSize = DEFAULT_WINSZ);
|
||||
|
||||
void operator() (const GpuMat& left, const GpuMat& right,
|
||||
GpuMat& disparity);
|
||||
void operator() (const GpuMat& left, const GpuMat& right,
|
||||
GpuMat& disparity, const Stream & stream);
|
||||
|
||||
static bool checkIfGpuCallReasonable();
|
||||
|
||||
int preset;
|
||||
int ndisp;
|
||||
int winSize;
|
||||
|
||||
float avergeTexThreshold;
|
||||
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
This class computes the disparity map using block matching algorithm. The class also performs pre- and post- filtering steps: sobel prefiltering (if PREFILTER\_XSOBEL flag is set) and low textureness filtering (if averageTexThreshols $>$ 0). If \texttt{avergeTexThreshold = 0} low textureness filtering is disabled, otherwise disparity is set to 0 in each point \texttt{(x, y)} where for left image $\sum HorizontalGradiensInWindow(x, y, winSize) < (winSize \cdot winSize) \cdot avergeTexThreshold$ i.e. input left image is low textured.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::StereoBM\_GPU::StereoBM\_GPU}\label{cppfunc.gpu.StereoBM.StereoBM}
|
||||
StereoBM\_GPU constructors.
|
||||
|
||||
\cvdefCpp{
|
||||
StereoBM\_GPU::StereoBM\_GPU();\newline
|
||||
StereoBM\_GPU::StereoBM\_GPU(int preset, \par int ndisparities = DEFAULT\_NDISP, \par int winSize = DEFAULT\_WINSZ);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{preset}{Preset:}
|
||||
\begin{description}
|
||||
\cvarg{BASIC\_PRESET}{Without preprocessing.}
|
||||
\cvarg{PREFILTER\_XSOBEL}{Sobel prefilter.}
|
||||
\end{description}
|
||||
\cvarg{ndisparities}{Number of disparities. Must be a multiple of 8 and less or equal then 256.}
|
||||
\cvarg{winSize}{Block size.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::StereoBM\_GPU::operator ()}\label{cppfunc.gpu.StereoBM.operator()}
|
||||
The stereo correspondence operator. Finds the disparity for the specified rectified stereo pair.
|
||||
|
||||
\cvdefCpp{
|
||||
void StereoBM\_GPU::operator() (const GpuMat\& left, const GpuMat\& right, \par GpuMat\& disparity);\newline
|
||||
void StereoBM\_GPU::operator() (const GpuMat\& left, const GpuMat\& right, \par GpuMat\& disparity, const Stream\& stream);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{left}{Left image; supports only \texttt{CV\_8UC1} type.}
|
||||
\cvarg{right}{Right image with the same size and the same type as the left one.}
|
||||
\cvarg{disparity}{Output disparity map. It will be \texttt{CV\_8UC1} image with the same size as the input images.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::StereoBM\_GPU::checkIfGpuCallReasonable}\label{cppfunc.gpu.StereoBM.checkIfGpuCallReasonable}
|
||||
Some heuristics that tries to estmate if the current GPU will be faster then CPU in this algorithm. It queries current active device.
|
||||
|
||||
\cvdefCpp{
|
||||
bool StereoBM\_GPU::checkIfGpuCallReasonable();
|
||||
}
|
||||
|
||||
|
||||
\cvclass{gpu::StereoBeliefPropagation}
|
||||
The class for computing stereo correspondence using belief propagation algorithm.
|
||||
|
||||
\begin{lstlisting}
|
||||
class StereoBeliefPropagation
|
||||
{
|
||||
public:
|
||||
enum { DEFAULT_NDISP = 64 };
|
||||
enum { DEFAULT_ITERS = 5 };
|
||||
enum { DEFAULT_LEVELS = 5 };
|
||||
|
||||
static void estimateRecommendedParams(int width, int height,
|
||||
int& ndisp, int& iters, int& levels);
|
||||
|
||||
explicit StereoBeliefPropagation(int ndisp = DEFAULT_NDISP,
|
||||
int iters = DEFAULT_ITERS,
|
||||
int levels = DEFAULT_LEVELS,
|
||||
int msg_type = CV_32F);
|
||||
StereoBeliefPropagation(int ndisp, int iters, int levels,
|
||||
float max_data_term, float data_weight,
|
||||
float max_disc_term, float disc_single_jump,
|
||||
int msg_type = CV_32F);
|
||||
|
||||
void operator()(const GpuMat& left, const GpuMat& right,
|
||||
GpuMat& disparity);
|
||||
void operator()(const GpuMat& left, const GpuMat& right,
|
||||
GpuMat& disparity, Stream& stream);
|
||||
void operator()(const GpuMat& data, GpuMat& disparity);
|
||||
void operator()(const GpuMat& data, GpuMat& disparity, Stream& stream);
|
||||
|
||||
int ndisp;
|
||||
|
||||
int iters;
|
||||
int levels;
|
||||
|
||||
float max_data_term;
|
||||
float data_weight;
|
||||
float max_disc_term;
|
||||
float disc_single_jump;
|
||||
|
||||
int msg_type;
|
||||
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class implements Pedro F. Felzenszwalb algorithm \cite{felzenszwalb_bp}. It can compute own data cost (using truncated linear model) or use user-provided data cost.
|
||||
|
||||
\textbf{Please note:} \texttt{StereoBeliefPropagation} requires a lot of memory:
|
||||
\[
|
||||
width\_step \cdot height \cdot ndisp \cdot 4 \cdot (1 + 0.25)
|
||||
\]
|
||||
for message storage and
|
||||
\[
|
||||
width\_step \cdot height \cdot ndisp \cdot (1 + 0.25 + 0.0625 + \dotsm + \frac{1}{4^{levels}}
|
||||
\]
|
||||
for data cost storage. \texttt{width\_step} is the number of bytes in a line including the padding.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::StereoBeliefPropagation::StereoBeliefPropagation}
|
||||
StereoBeliefPropagation constructors.
|
||||
|
||||
\cvdefCpp{
|
||||
StereoBeliefPropagation::StereoBeliefPropagation(\par int ndisp = DEFAULT\_NDISP, int iters = DEFAULT\_ITERS, \par int levels = DEFAULT\_LEVELS, int msg\_type = CV\_32F);\newline
|
||||
StereoBeliefPropagation::StereoBeliefPropagation(\par int ndisp, int iters, int levels, \par float max\_data\_term, float data\_weight, \par float max\_disc\_term, float disc\_single\_jump, \par int msg\_type = CV\_32F);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{ndisp}{Number of disparities.}
|
||||
\cvarg{iters}{Number of BP iterations on each level.}
|
||||
\cvarg{levels}{Number of levels.}
|
||||
\cvarg{max\_data\_term}{Threshold for data cost truncation.}
|
||||
\cvarg{data\_weight}{Data weight.}
|
||||
\cvarg{max\_disc\_term}{Threshold for discontinuity truncation.}
|
||||
\cvarg{disc\_single\_jump}{Discontinuity single jump.}
|
||||
\cvarg{msg\_type}{Type for messages. Supports \texttt{CV\_16SC1} and \texttt{CV\_32FC1}.}
|
||||
\end{description}
|
||||
|
||||
\texttt{StereoBeliefPropagation} uses truncated linear model for the data cost and discontinuity term:
|
||||
\[
|
||||
DataCost = data\_weight \cdot \min(\lvert I_2-I_1 \rvert, max\_data\_term)
|
||||
\]
|
||||
\[
|
||||
DiscTerm = \min(disc\_single\_jump \cdot \lvert f_1-f_2 \rvert, max\_disc\_term)
|
||||
\]
|
||||
|
||||
For more details please see \cite{felzenszwalb_bp}.
|
||||
|
||||
By default \texttt{StereoBeliefPropagation} uses floating-point arithmetics and \texttt{CV\_32FC1} type for messages. But also it can use fixed-point arithmetics and \texttt{CV\_16SC1} type for messages for better perfomance. To avoid overflow in this case, the parameters must satisfy
|
||||
\[
|
||||
10 \cdot 2^{levels-1} \cdot max\_data\_term < SHRT\_MAX
|
||||
\]
|
||||
|
||||
|
||||
\cvCppFunc{gpu::StereoBeliefPropagation::estimateRecommendedParams}
|
||||
Some heuristics that tries to compute recommended parameters (\texttt{ndisp}, \texttt{iters} and \texttt{levels}) for specified image size (\texttt{width} and \texttt{height}).
|
||||
|
||||
\cvdefCpp{
|
||||
void StereoBeliefPropagation::estimateRecommendedParams(\par int width, int height, int\& ndisp, int\& iters, int\& levels);
|
||||
}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::StereoBeliefPropagation::operator ()}
|
||||
The stereo correspondence operator. Finds the disparity for the specified rectified stereo pair or data cost.
|
||||
|
||||
\cvdefCpp{
|
||||
void StereoBeliefPropagation::operator()(\par const GpuMat\& left, const GpuMat\& right, \par GpuMat\& disparity);\newline
|
||||
void StereoBeliefPropagation::operator()(\par const GpuMat\& left, const GpuMat\& right, \par GpuMat\& disparity, Stream\& stream);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{left}{Left image; supports \texttt{CV\_8UC1}, \texttt{CV\_8UC3} and \texttt{CV\_8UC4} types.}
|
||||
\cvarg{right}{Right image with the same size and the same type as the left one.}
|
||||
\cvarg{disparity}{Output disparity map. If \texttt{disparity} is empty output type will be \texttt{CV\_16SC1}, otherwise output type will be \texttt{disparity.type()}.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{
|
||||
void StereoBeliefPropagation::operator()(\par const GpuMat\& data, GpuMat\& disparity);\newline
|
||||
void StereoBeliefPropagation::operator()(\par const GpuMat\& data, GpuMat\& disparity, Stream\& stream);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{data}{The user specified data cost. It must have \texttt{msg\_type} type and $\texttt{imgRows} \cdot \texttt{ndisp} \times \texttt{imgCols}$ size.}
|
||||
\cvarg{disparity}{Output disparity map. If \texttt{disparity} is empty output type will be \texttt{CV\_16SC1}, otherwise output type will be \texttt{disparity.type()}.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvclass{gpu::StereoConstantSpaceBP}
|
||||
The class for computing stereo correspondence using constant space belief propagation algorithm.
|
||||
|
||||
\begin{lstlisting}
|
||||
class StereoConstantSpaceBP
|
||||
{
|
||||
public:
|
||||
enum { DEFAULT_NDISP = 128 };
|
||||
enum { DEFAULT_ITERS = 8 };
|
||||
enum { DEFAULT_LEVELS = 4 };
|
||||
enum { DEFAULT_NR_PLANE = 4 };
|
||||
|
||||
static void estimateRecommendedParams(int width, int height,
|
||||
int& ndisp, int& iters, int& levels, int& nr_plane);
|
||||
|
||||
explicit StereoConstantSpaceBP(int ndisp = DEFAULT_NDISP,
|
||||
int iters = DEFAULT_ITERS,
|
||||
int levels = DEFAULT_LEVELS,
|
||||
int nr_plane = DEFAULT_NR_PLANE,
|
||||
int msg_type = CV_32F);
|
||||
StereoConstantSpaceBP(int ndisp, int iters, int levels, int nr_plane,
|
||||
float max_data_term, float data_weight,
|
||||
float max_disc_term, float disc_single_jump,
|
||||
int min_disp_th = 0,
|
||||
int msg_type = CV_32F);
|
||||
|
||||
void operator()(const GpuMat& left, const GpuMat& right,
|
||||
GpuMat& disparity);
|
||||
void operator()(const GpuMat& left, const GpuMat& right,
|
||||
GpuMat& disparity, Stream& stream);
|
||||
|
||||
int ndisp;
|
||||
|
||||
int iters;
|
||||
int levels;
|
||||
|
||||
int nr_plane;
|
||||
|
||||
float max_data_term;
|
||||
float data_weight;
|
||||
float max_disc_term;
|
||||
float disc_single_jump;
|
||||
|
||||
int min_disp_th;
|
||||
|
||||
int msg_type;
|
||||
|
||||
bool use_local_init_data_cost;
|
||||
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class implements Q. Yang algorithm \cite{qx_csbp}. \texttt{StereoConstantSpaceBP} supports both local minimum and global minimum data cost initialization algortihms. For more details please see the paper. By default local algorithm is used, and to enable global algorithm set \texttt{use\_local\_init\_data\_cost} to false.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::StereoConstantSpaceBP::StereoConstantSpaceBP}
|
||||
StereoConstantSpaceBP constructors.
|
||||
|
||||
\cvdefCpp{
|
||||
StereoConstantSpaceBP::StereoConstantSpaceBP(int ndisp = DEFAULT\_NDISP, \par int iters = DEFAULT\_ITERS, int levels = DEFAULT\_LEVELS, \par int nr\_plane = DEFAULT\_NR\_PLANE, int msg\_type = CV\_32F);\newline
|
||||
StereoConstantSpaceBP::StereoConstantSpaceBP(int ndisp, int iters, \par int levels, int nr\_plane, \par float max\_data\_term, float data\_weight, \par float max\_disc\_term, float disc\_single\_jump, \par int min\_disp\_th = 0, int msg\_type = CV\_32F);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{ndisp}{Number of disparities.}
|
||||
\cvarg{iters}{Number of BP iterations on each level.}
|
||||
\cvarg{levels}{Number of levels.}
|
||||
\cvarg{nr\_plane}{Number of disparity levels on the first level}
|
||||
\cvarg{max\_data\_term}{Truncation of data cost.}
|
||||
\cvarg{data\_weight}{Data weight.}
|
||||
\cvarg{max\_disc\_term}{Truncation of discontinuity.}
|
||||
\cvarg{disc\_single\_jump}{Discontinuity single jump.}
|
||||
\cvarg{min\_disp\_th}{Minimal disparity threshold.}
|
||||
\cvarg{msg\_type}{Type for messages. Supports \texttt{CV\_16SC1} and \texttt{CV\_32FC1}.}
|
||||
\end{description}
|
||||
|
||||
\texttt{StereoConstantSpaceBP} uses truncated linear model for the data cost and discontinuity term:
|
||||
\[
|
||||
DataCost = data\_weight \cdot \min(\lvert I_2-I_1 \rvert, max\_data\_term)
|
||||
\]
|
||||
\[
|
||||
DiscTerm = \min(disc\_single\_jump \cdot \lvert f_1-f_2 \rvert, max\_disc\_term)
|
||||
\]
|
||||
|
||||
For more details please see \cite{qx_csbp}.
|
||||
|
||||
By default \texttt{StereoConstantSpaceBP} uses floating-point arithmetics and \texttt{CV\_32FC1} type for messages. But also it can use fixed-point arithmetics and \texttt{CV\_16SC1} type for messages for better perfomance. To avoid overflow in this case, the parameters must satisfy
|
||||
\[
|
||||
10 \cdot 2^{levels-1} \cdot max\_data\_term < SHRT\_MAX
|
||||
\]
|
||||
|
||||
|
||||
\cvCppFunc{gpu::StereoConstantSpaceBP::estimateRecommendedParams}
|
||||
Some heuristics that tries to compute parameters (\texttt{ndisp}, \texttt{iters}, \texttt{levels} and \texttt{nr\_plane}) for specified image size (\texttt{width} and \texttt{height}).
|
||||
|
||||
\cvdefCpp{
|
||||
void StereoConstantSpaceBP::estimateRecommendedParams(\par int width, int height, \par int\& ndisp, int\& iters, int\& levels, int\& nr\_plane);
|
||||
}
|
||||
|
||||
\cvCppFunc{gpu::StereoConstantSpaceBP::operator ()}
|
||||
The stereo correspondence operator. Finds the disparity for the specified rectified stereo pair.
|
||||
|
||||
\cvdefCpp{
|
||||
void StereoConstantSpaceBP::operator()(\par const GpuMat\& left, const GpuMat\& right, \par GpuMat\& disparity);\newline
|
||||
void StereoConstantSpaceBP::operator()(\par const GpuMat\& left, const GpuMat\& right, \par GpuMat\& disparity, Stream\& stream);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{left}{Left image; supports \texttt{CV\_8UC1}, \texttt{CV\_8UC3} and \texttt{CV\_8UC4} types.}
|
||||
\cvarg{right}{Right image with the same size and the same type as the left one.}
|
||||
\cvarg{disparity}{Output disparity map. If \texttt{disparity} is empty output type will be \texttt{CV\_16SC1}, otherwise output type will be \texttt{disparity.type()}.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvclass{gpu::DisparityBilateralFilter}
|
||||
The class for disparity map refinement using joint bilateral filtering.
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS DisparityBilateralFilter
|
||||
{
|
||||
public:
|
||||
enum { DEFAULT_NDISP = 64 };
|
||||
enum { DEFAULT_RADIUS = 3 };
|
||||
enum { DEFAULT_ITERS = 1 };
|
||||
|
||||
explicit DisparityBilateralFilter(int ndisp = DEFAULT_NDISP,
|
||||
int radius = DEFAULT_RADIUS, int iters = DEFAULT_ITERS);
|
||||
|
||||
DisparityBilateralFilter(int ndisp, int radius, int iters,
|
||||
float edge_threshold, float max_disc_threshold,
|
||||
float sigma_range);
|
||||
|
||||
void operator()(const GpuMat& disparity, const GpuMat& image,
|
||||
GpuMat& dst);
|
||||
void operator()(const GpuMat& disparity, const GpuMat& image,
|
||||
GpuMat& dst, Stream& stream);
|
||||
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class implements Q. Yang algorithm \cite{qx_csbp}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::DisparityBilateralFilter::DisparityBilateralFilter}
|
||||
DisparityBilateralFilter constructors.
|
||||
|
||||
\cvdefCpp{
|
||||
DisparityBilateralFilter::DisparityBilateralFilter(\par int ndisp = DEFAULT\_NDISP, int radius = DEFAULT\_RADIUS, \par int iters = DEFAULT\_ITERS);\newline
|
||||
DisparityBilateralFilter::DisparityBilateralFilter(\par int ndisp, int radius, int iters, \par float edge\_threshold, float max\_disc\_threshold, \par float sigma\_range);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{ndisp}{Number of disparities.}
|
||||
\cvarg{radius}{Filter radius.}
|
||||
\cvarg{iters}{Number of iterations.}
|
||||
\cvarg{edge\_threshold}{Threshold for edges.}
|
||||
\cvarg{max\_disc\_threshold}{Constant to reject outliers.}
|
||||
\cvarg{sigma\_range}{Filter range.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::DisparityBilateralFilter::operator ()}
|
||||
Refines disparity map using joint bilateral filtering.
|
||||
|
||||
\cvdefCpp{
|
||||
void DisparityBilateralFilter::operator()(\par const GpuMat\& disparity, const GpuMat\& image, GpuMat\& dst);\newline
|
||||
void DisparityBilateralFilter::operator()(\par const GpuMat\& disparity, const GpuMat\& image, GpuMat\& dst, \par Stream\& stream);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{disparity}{Input disparity map; supports \texttt{CV\_8UC1} and \texttt{CV\_16SC1} types.}
|
||||
\cvarg{image}{Input image; supports \texttt{CV\_8UC1} and \texttt{CV\_8UC3} types.}
|
||||
\cvarg{dst}{Destination disparity map; will have the same size and type as \texttt{disparity}.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{gpu::drawColorDisp}
|
||||
Does coloring of disparity image.
|
||||
|
||||
\cvdefCpp{
|
||||
void drawColorDisp(const GpuMat\& src\_disp, GpuMat\& dst\_disp, int ndisp);\newline
|
||||
void drawColorDisp(const GpuMat\& src\_disp, GpuMat\& dst\_disp, int ndisp, \par const Stream\& stream);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src\_disp}{Source disparity image. Supports \texttt{CV\_8UC1} and \texttt{CV\_16SC1} types.}
|
||||
\cvarg{dst\_disp}{Output disparity image. Will have the same size as \texttt{src\_disp} and \texttt{CV\_8UC4} type in \texttt{BGRA} format (alpha = 255).}
|
||||
\cvarg{ndisp}{Number of disparities.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
This function converts $[0..ndisp)$ interval to $[0..240, 1, 1]$ in \texttt{HSV} color space, than convert \texttt{HSV} color space to \texttt{RGB}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::reprojectImageTo3D}
|
||||
Reprojects disparity image to 3D space.
|
||||
|
||||
\cvdefCpp{
|
||||
void reprojectImageTo3D(const GpuMat\& disp, GpuMat\& xyzw, \par const Mat\& Q);\newline
|
||||
void reprojectImageTo3D(const GpuMat\& disp, GpuMat\& xyzw, \par const Mat\& Q, const Stream\& stream);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{disp}{Input disparity image; supports \texttt{CV\_8U} and \texttt{CV\_16S} types.}
|
||||
\cvarg{xyzw}{Output 4-channel floating-point image of the same size as \texttt{disp}. Each element of \texttt{xyzw(x,y)} will contain the 3D coordinates \texttt{(x,y,z,1)} of the point \texttt{(x,y)}, computed from the disparity map.}
|
||||
\cvarg{Q}{$4 \times 4$ perspective transformation matrix that can be obtained via \cvCross{StereoRectify}{stereoRectify}.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{reprojectImageTo3D}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::transformPoints}
|
||||
Rotates and translates points.
|
||||
|
||||
\cvdefCpp{
|
||||
void transformPoints(const GpuMat\& src, const Mat\& rvec, \par const Mat\& tvec, GpuMat\& dst);\newline
|
||||
void transformPoints(const GpuMat\& src, const Mat\& rvec, \par const Mat\& tvec, GpuMat\& dst, const Stream\& stream);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source points. Single-row \texttt{CV\_32FC3} matrix.}
|
||||
\cvarg{rvec}{\texttt{CV\_32F} 3D rotation vector.}
|
||||
\cvarg{tvec}{\texttt{CV\_32F} 3D translation vector.}
|
||||
\cvarg{dst}{Transformed points. Single-row \texttt{CV\_32FC3} matrix.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::projectPoints}
|
||||
Projects points.
|
||||
|
||||
\cvdefCpp{
|
||||
void projectPoints(const GpuMat\& src, const Mat\& rvec, \par const Mat\& tvec, const Mat\& camera\_mat, \par const Mat\& dist\_coef, GpuMat\& dst);\newline
|
||||
void projectPoints(const GpuMat\& src, const Mat\& rvec, \par const Mat\& tvec, const Mat\& camera\_mat, \par const Mat\& dist\_coef, GpuMat\& dst, const Stream\& stream);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source points. Single-row \texttt{CV\_32FC3} matrix.}
|
||||
\cvarg{rvec}{\texttt{CV\_32F} 3D rotation vector.}
|
||||
\cvarg{tvec}{\texttt{CV\_32F} 3D translation vector.}
|
||||
\cvarg{camera\_mat}{\texttt{CV\_32F} 3x3 camera matrix.}
|
||||
\cvarg{dist\_coef}{Distortion coefficients. This parameter isn't supported for now, must be empty matrix.}
|
||||
\cvarg{dst}{Projected points. Single-row \texttt{CV\_32FC2} matrix.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{projectPoints}.
|
@ -1,275 +0,0 @@
|
||||
\section{Data Structures}
|
||||
|
||||
|
||||
\cvclass{gpu::DevMem2D\_}\label{cppfunc.gpu.DevMem2D}
|
||||
|
||||
This is a simple lightweight class that encapsulate pitched memory on GPU. It is intended to pass to nvcc-compiled code, i.e. CUDA kernels. So it is used internally by OpenCV and by users writes own device code. Its members can be called both from host and from device code.
|
||||
|
||||
\begin{lstlisting}
|
||||
template <typename T> struct DevMem2D_
|
||||
{
|
||||
int cols;
|
||||
int rows;
|
||||
T* data;
|
||||
size_t step;
|
||||
|
||||
DevMem2D_() : cols(0), rows(0), data(0), step(0){};
|
||||
DevMem2D_(int rows_, int cols_, T *data_, size_t step_);
|
||||
|
||||
template <typename U>
|
||||
explicit DevMem2D_(const DevMem2D_<U>& d);
|
||||
|
||||
typedef T elem_type;
|
||||
enum { elem_size = sizeof(elem_type) };
|
||||
|
||||
__CV_GPU_HOST_DEVICE__ size_t elemSize() const;
|
||||
|
||||
/* returns pointer to the beggining of given image row */
|
||||
__CV_GPU_HOST_DEVICE__ T* ptr(int y = 0);
|
||||
__CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvclass{gpu::PtrStep\_}\label{cppfunc.gpu.PtrStep}
|
||||
|
||||
This is structure is similar to DevMem2D\_ but contains only pointer and row step. Width and height fields are excluded due to performance reasons. The structure is for internal use or for users who write own device code.
|
||||
|
||||
\begin{lstlisting}
|
||||
template<typename T> struct PtrStep_
|
||||
{
|
||||
T* data;
|
||||
size_t step;
|
||||
|
||||
PtrStep_();
|
||||
PtrStep_(const DevMem2D_<T>& mem);
|
||||
|
||||
typedef T elem_type;
|
||||
enum { elem_size = sizeof(elem_type) };
|
||||
|
||||
__CV_GPU_HOST_DEVICE__ size_t elemSize() const;
|
||||
__CV_GPU_HOST_DEVICE__ T* ptr(int y = 0);
|
||||
__CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const;
|
||||
};
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\cvclass{gpu::PtrElemStrp\_}
|
||||
This is structure is similar to DevMem2D\_ but contains only pointer and row step in elements. Width and height fields are excluded due to performance reasons. This class is can only be constructed if sizeof(T) is a multiple of 256. The structure is for internal use or for users who write own device code.
|
||||
|
||||
\begin{lstlisting}
|
||||
template<typename T> struct PtrElemStep_ : public PtrStep_<T>
|
||||
{
|
||||
PtrElemStep_(const DevMem2D_<T>& mem);
|
||||
__CV_GPU_HOST_DEVICE__ T* ptr(int y = 0);
|
||||
__CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvclass{gpu::GpuMat}
|
||||
|
||||
The base storage class for GPU memory with reference counting. Its interface is almost \cvCppCross{Mat} interface with some limitations, so using it won't be a problem. The limitations are no arbitrary dimensions support (only 2D), no functions that returns references to its data (because references on GPU are not valid for CPU), no expression templates technique support. Because of last limitation please take care with overloaded matrix operators - they cause memory allocations. The GpuMat class is convertible to \hyperref[cppfunc.gpu.DevMem2D]{cv::gpu::DevMem2D\_} and \hyperref[cppfunc.gpu.PtrStep]{cv::gpu::PtrStep\_} so it can be passed to directly to kernel.
|
||||
|
||||
|
||||
|
||||
|
||||
\textbf{Please note:} In contrast with \cvCppCross{Mat}, In most cases \texttt{GpuMat::isContinuous() == false}, i.e. rows are aligned to size depending on hardware. Also single row GpuMat is always a continuous matrix.
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS GpuMat
|
||||
{
|
||||
public:
|
||||
//! default constructor
|
||||
GpuMat();
|
||||
|
||||
GpuMat(int rows, int cols, int type);
|
||||
GpuMat(Size size, int type);
|
||||
|
||||
.....
|
||||
|
||||
//! builds GpuMat from Mat. Perfom blocking upload to device.
|
||||
explicit GpuMat (const Mat& m);
|
||||
|
||||
//! returns lightweight DevMem2D_ structure for passing
|
||||
//to nvcc-compiled code. Contains size, data ptr and step.
|
||||
template <class T> operator DevMem2D_<T>() const;
|
||||
template <class T> operator PtrStep_<T>() const;
|
||||
|
||||
//! pefroms blocking upload data to GpuMat.
|
||||
void upload(const cv::Mat& m);
|
||||
void upload(const CudaMem& m, Stream& stream);
|
||||
|
||||
//! downloads data from device to host memory. Blocking calls.
|
||||
operator Mat() const;
|
||||
void download(cv::Mat& m) const;
|
||||
|
||||
//! download async
|
||||
void download(CudaMem& m, Stream& stream) const;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\textbf{Please note:} Is it a bad practice to leave static or global GpuMat variables allocated, i.e. to rely on its destructor. That is because destruction order of such variables and CUDA context is undefined and GPU memory release function returns error if CUDA context has been destroyed before.
|
||||
|
||||
|
||||
See also: \cvCppCross{Mat}
|
||||
|
||||
|
||||
\cvclass{gpu::CudaMem}
|
||||
This is a class with reference counting that wraps special memory type allocation functions from CUDA. Its interface is also \cvCppCross{Mat}-like but with additional memory type parameter:
|
||||
\begin{itemize}
|
||||
\item \texttt{ALLOC\_PAGE\_LOCKED} Set page locked memory type, used commonly for fast and asynchronous upload/download data from/to GPU.
|
||||
\item \texttt{ALLOC\_ZEROCOPY} Specifies zero copy memory allocation, i.e. with possibility to map host memory to GPU address space if supported.
|
||||
\item \texttt{ALLOC\_WRITE\_COMBINED} Sets write combined buffer which is not cached by CPU. Such buffers are used to supply GPU with data when GPU only reads it. The advantage is better CPU cache utilization.
|
||||
\end{itemize}
|
||||
Please note that allocation size of such memory types is usually limited. For more details please see "CUDA 2.2 Pinned Memory APIs" document or "CUDA\_C Programming Guide".
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS CudaMem
|
||||
{
|
||||
public:
|
||||
enum { ALLOC_PAGE_LOCKED = 1, ALLOC_ZEROCOPY = 2,
|
||||
ALLOC_WRITE_COMBINED = 4 };
|
||||
|
||||
CudaMem(Size size, int type, int alloc_type = ALLOC_PAGE_LOCKED);
|
||||
|
||||
//! creates from cv::Mat with coping data
|
||||
explicit CudaMem(const Mat& m, int alloc_type = ALLOC_PAGE_LOCKED);
|
||||
|
||||
......
|
||||
|
||||
void create(Size size, int type, int alloc_type = ALLOC_PAGE_LOCKED);
|
||||
|
||||
//! returns matrix header with disabled ref. counting for CudaMem data.
|
||||
Mat createMatHeader() const;
|
||||
operator Mat() const;
|
||||
|
||||
//! maps host memory into device address space
|
||||
GpuMat createGpuMatHeader() const;
|
||||
operator GpuMat() const;
|
||||
|
||||
//if host memory can be mapperd to gpu address space;
|
||||
static bool canMapHostMemory();
|
||||
|
||||
int alloc_type;
|
||||
};
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{gpu::CudaMem::createMatHeader}
|
||||
Creates \cvCppCross{Mat} header without reference counting to CudaMem data.
|
||||
|
||||
\cvdefCpp{
|
||||
Mat CudaMem::createMatHeader() const; \newline
|
||||
CudaMem::operator Mat() const;
|
||||
}
|
||||
|
||||
\cvCppFunc{gpu::CudaMem::createGpuMatHeader}
|
||||
Maps CPU memory to GPU address space and creates \cvCppCross{gpu::GpuMat} header without reference counting for it. This can be done only if memory was allocated with \texttt{ALLOC\_ZEROCOPY} flag and if it is supported by hardware (laptops often share video and CPU memory, so address spaces can be mapped, and that eliminates extra copy).
|
||||
|
||||
\cvdefCpp{
|
||||
GpuMat CudaMem::createGpuMatHeader() const; \newline
|
||||
CudaMem::operator GpuMat() const;
|
||||
}
|
||||
|
||||
\cvCppFunc{gpu::CudaMem::canMapHostMemory}
|
||||
Returns true if the current hardware supports address space mapping and \texttt{ALLOC\_ZEROCOPY} memory allocation
|
||||
\cvdefCpp{static bool CudaMem::canMapHostMemory();}
|
||||
|
||||
|
||||
\cvclass{gpu::Stream}
|
||||
|
||||
|
||||
This class encapsulated queue of the asynchronous calls. Some functions have overloads with additional \cvCppCross{gpu::Stream} parameter. The overloads do initialization work (allocate output buffers, upload constants, etc.), start GPU kernel and return before results are ready. A check if all operation are complete can be performed via \cvCppCross{gpu::Stream::queryIfComplete()}. Asynchronous upload/download have to be performed from/to page-locked buffers, i.e. using \cvCppCross{gpu::CudaMem} or \cvCppCross{Mat} header that points to a region of \cvCppCross{gpu::CudaMem}.
|
||||
|
||||
\textbf{Please note the limitation}: currently it is not guaranteed that all will work properly if one operation will be enqueued twice with different data. Some functions use constant GPU memory and next call may update the memory before previous has been finished. But calling asynchronously different operations is safe because each operation has own constant buffer. Memory copy/upload/download/set operations to buffers hold by user are also safe.
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS Stream
|
||||
{
|
||||
public:
|
||||
Stream();
|
||||
~Stream();
|
||||
|
||||
Stream(const Stream&);
|
||||
Stream& operator=(const Stream&);
|
||||
|
||||
bool queryIfComplete();
|
||||
void waitForCompletion();
|
||||
|
||||
//! downloads asynchronously.
|
||||
// Warning! cv::Mat must point to page locked memory
|
||||
(i.e. to CudaMem data or to its subMat)
|
||||
void enqueueDownload(const GpuMat& src, CudaMem& dst);
|
||||
void enqueueDownload(const GpuMat& src, Mat& dst);
|
||||
|
||||
//! uploads asynchronously.
|
||||
// Warning! cv::Mat must point to page locked memory
|
||||
(i.e. to CudaMem data or to its ROI)
|
||||
void enqueueUpload(const CudaMem& src, GpuMat& dst);
|
||||
void enqueueUpload(const Mat& src, GpuMat& dst);
|
||||
|
||||
void enqueueCopy(const GpuMat& src, GpuMat& dst);
|
||||
|
||||
void enqueueMemSet(const GpuMat& src, Scalar val);
|
||||
void enqueueMemSet(const GpuMat& src, Scalar val, const GpuMat& mask);
|
||||
|
||||
// converts matrix type, ex from float to uchar depending on type
|
||||
void enqueueConvert(const GpuMat& src, GpuMat& dst, int type,
|
||||
double a = 1, double b = 0);
|
||||
};
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{gpu::Stream::queryIfComplete}
|
||||
Returns true if the current stream queue is finished, otherwise false.
|
||||
\cvdefCpp{bool Stream::queryIfComplete()}
|
||||
|
||||
\cvCppFunc{gpu::Stream::waitForCompletion}
|
||||
Blocks until all operations in the stream are complete.
|
||||
\cvdefCpp{void Stream::waitForCompletion();}
|
||||
|
||||
|
||||
\cvclass{gpu::StreamAccessor}
|
||||
|
||||
This class provides possibility to get \texttt{cudaStream\_t} from \cvCppCross{gpu::Stream}. This class is declared in \texttt{stream\_accessor.hpp} because that is only public header that depend on Cuda Runtime API. Including it will bring the dependency to your code.
|
||||
|
||||
\begin{lstlisting}
|
||||
struct StreamAccessor
|
||||
{
|
||||
CV_EXPORTS static cudaStream_t getStream(const Stream& stream);
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{gpu::createContinuous}
|
||||
Creates continuous matrix in GPU memory.
|
||||
|
||||
\cvdefCpp{void createContinuous(int rows, int cols, int type, GpuMat\& m);}
|
||||
\begin{description}
|
||||
\cvarg{rows}{Row count.}
|
||||
\cvarg{cols}{Column count.}
|
||||
\cvarg{type}{Type of the matrix.}
|
||||
\cvarg{m}{Destination matrix. Will be only reshaped if it has proper type and area (\texttt{rows} $\times$ \texttt{cols}).}
|
||||
\end{description}
|
||||
|
||||
Also the following wrappers are available:
|
||||
\cvdefCpp{GpuMat createContinuous(int rows, int cols, int type);\newline
|
||||
void createContinuous(Size size, int type, GpuMat\& m);\newline
|
||||
GpuMat createContinuous(Size size, int type);}
|
||||
|
||||
Matrix is called continuous if its elements are stored continuously, i.e. wuthout gaps in the end of each row.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::ensureSizeIsEnough}
|
||||
Ensures that size of matrix is big enough and matrix has proper type. The function doesn't reallocate memory if the matrix has proper attributes already.
|
||||
|
||||
\cvdefCpp{void ensureSizeIsEnough(int rows, int cols, int type, GpuMat\& m);}
|
||||
\begin{description}
|
||||
\cvarg{rows}{Minimum desired number of rows.}
|
||||
\cvarg{cols}{Minimum desired number of cols.}
|
||||
\cvarg{type}{Desired matrix type.}
|
||||
\cvarg{m}{Destination matrix.}
|
||||
\end{description}
|
||||
|
||||
Also the following wrapper is available:
|
||||
\cvdefCpp{void ensureSizeIsEnough(Size size, int type, GpuMat\& m);}
|
@ -1,352 +0,0 @@
|
||||
\section{Feature Detection and Description}
|
||||
|
||||
|
||||
\cvclass{gpu::SURFParams\_GPU}\label{class.gpu.SURFParams}
|
||||
Various SURF algorithm parameters.
|
||||
|
||||
\begin{lstlisting}
|
||||
struct SURFParams_GPU
|
||||
{
|
||||
SURFParams_GPU() : threshold(0.1f), nOctaves(4), nIntervals(4),
|
||||
initialScale(2.f), l1(3.f/1.5f), l2(5.f/1.5f), l3(3.f/1.5f),
|
||||
l4(1.f/1.5f), edgeScale(0.81f), initialStep(1), extended(true),
|
||||
featuresRatio(0.01f) {}
|
||||
|
||||
//! The interest operator threshold
|
||||
float threshold;
|
||||
//! The number of octaves to process
|
||||
int nOctaves;
|
||||
//! The number of intervals in each octave
|
||||
int nIntervals;
|
||||
//! The scale associated with the first interval of the first octave
|
||||
float initialScale;
|
||||
|
||||
//! mask parameter l_1
|
||||
float l1;
|
||||
//! mask parameter l_2
|
||||
float l2;
|
||||
//! mask parameter l_3
|
||||
float l3;
|
||||
//! mask parameter l_4
|
||||
float l4;
|
||||
//! The amount to scale the edge rejection mask
|
||||
float edgeScale;
|
||||
//! The initial sampling step in pixels.
|
||||
int initialStep;
|
||||
|
||||
//! True, if generate 128-len descriptors, false - 64-len descriptors
|
||||
bool extended;
|
||||
|
||||
//! max features = featuresRatio * img.size().area()
|
||||
float featuresRatio;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
In contrast to \hyperref[cv.class.SURF]{cv::SURF} \texttt{SURF\_GPU} works with float sources (with range [0..1]). It performs conversion after calculation of the integral by division result by 255. Please take it into consideration when change some parameters (like hessian threshold).
|
||||
|
||||
Current \texttt{SURF\_GPU} implementation supports the number of intervals in each octave in range [3..21].
|
||||
|
||||
See also: \hyperref[class.gpu.SURF]{cv::gpu::SURF\_GPU}.
|
||||
|
||||
|
||||
\cvclass{gpu::SURF\_GPU}\label{class.gpu.SURF}
|
||||
Class for extracting Speeded Up Robust Features from an image.
|
||||
|
||||
\begin{lstlisting}
|
||||
class SURF_GPU : public SURFParams_GPU
|
||||
{
|
||||
public:
|
||||
//! returns the descriptor size in float's (64 or 128)
|
||||
int descriptorSize() const;
|
||||
|
||||
//! upload host keypoints to device memory
|
||||
static void uploadKeypoints(const vector<KeyPoint>& keypoints,
|
||||
GpuMat& keypointsGPU);
|
||||
//! download keypoints from device to host memory
|
||||
static void downloadKeypoints(const GpuMat& keypointsGPU,
|
||||
vector<KeyPoint>& keypoints);
|
||||
|
||||
//! download descriptors from device to host memory
|
||||
static void downloadDescriptors(const GpuMat& descriptorsGPU,
|
||||
vector<float>& descriptors);
|
||||
|
||||
void operator()(const GpuMat& img, const GpuMat& mask,
|
||||
GpuMat& keypoints);
|
||||
|
||||
void operator()(const GpuMat& img, const GpuMat& mask,
|
||||
GpuMat& keypoints, GpuMat& descriptors,
|
||||
bool useProvidedKeypoints = false,
|
||||
bool calcOrientation = true);
|
||||
|
||||
void operator()(const GpuMat& img, const GpuMat& mask,
|
||||
std::vector<KeyPoint>& keypoints);
|
||||
|
||||
void operator()(const GpuMat& img, const GpuMat& mask,
|
||||
std::vector<KeyPoint>& keypoints, GpuMat& descriptors,
|
||||
bool useProvidedKeypoints = false,
|
||||
bool calcOrientation = true);
|
||||
|
||||
void operator()(const GpuMat& img, const GpuMat& mask,
|
||||
std::vector<KeyPoint>& keypoints,
|
||||
std::vector<float>& descriptors,
|
||||
bool useProvidedKeypoints = false,
|
||||
bool calcOrientation = true);
|
||||
|
||||
GpuMat sum;
|
||||
GpuMat sumf;
|
||||
|
||||
GpuMat mask1;
|
||||
GpuMat maskSum;
|
||||
|
||||
GpuMat hessianBuffer;
|
||||
GpuMat maxPosBuffer;
|
||||
GpuMat featuresBuffer;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class \texttt{SURF\_GPU} implements Speeded Up Robust Features descriptor. There is fast multi-scale Hessian keypoint detector that can be used to find the keypoints (which is the default option), but the descriptors can be also computed for the user-specified keypoints. Supports only 8 bit grayscale images.
|
||||
|
||||
The class \texttt{SURF\_GPU} can store results to GPU and CPU memory and provides static functions to convert results between CPU and GPU version (\texttt{uploadKeypoints}, \texttt{downloadKeypoints}, \texttt{downloadDescriptors}). CPU results has the same format as \hyperref[cv.class.SURF]{cv::SURF} results. GPU results are stored to \texttt{GpuMat}. \texttt{keypoints} matrix is one row matrix with \texttt{CV\_32FC6} type. It contains 6 float values per feature: \texttt{x, y, size, response, angle, octave}. \texttt{descriptors} matrix is $\texttt{nFeatures} \times \texttt{descriptorSize}$ matrix with \texttt{CV\_32FC1} type.
|
||||
|
||||
The class \texttt{SURF\_GPU} uses some buffers and provides access to it. All buffers can be safely released between function calls.
|
||||
|
||||
See also: \hyperref[cv.class.SURF]{cv::SURF}, \hyperref[class.gpu.SURFParams]{cv::gpu::SURFParams\_GPU}.
|
||||
|
||||
|
||||
\cvclass{gpu::BruteForceMatcher\_GPU}
|
||||
Brute-force descriptor matcher. For each descriptor in the first set, this matcher finds the closest descriptor in the second set by trying each one. This descriptor matcher supports masking permissible matches between descriptor sets.
|
||||
|
||||
\begin{lstlisting}
|
||||
template<class Distance>
|
||||
class BruteForceMatcher_GPU
|
||||
{
|
||||
public:
|
||||
// Add descriptors to train descriptor collection.
|
||||
void add(const std::vector<GpuMat>& descCollection);
|
||||
|
||||
// Get train descriptors collection.
|
||||
const std::vector<GpuMat>& getTrainDescriptors() const;
|
||||
|
||||
// Clear train descriptors collection.
|
||||
void clear();
|
||||
|
||||
// Return true if there are not train descriptors in collection.
|
||||
bool empty() const;
|
||||
|
||||
// Return true if the matcher supports mask in match methods.
|
||||
bool isMaskSupported() const;
|
||||
|
||||
void matchSingle(const GpuMat& queryDescs, const GpuMat& trainDescs,
|
||||
GpuMat& trainIdx, GpuMat& distance,
|
||||
const GpuMat& mask = GpuMat());
|
||||
|
||||
static void matchDownload(const GpuMat& trainIdx,
|
||||
const GpuMat& distance, std::vector<DMatch>& matches);
|
||||
|
||||
void match(const GpuMat& queryDescs, const GpuMat& trainDescs,
|
||||
std::vector<DMatch>& matches, const GpuMat& mask = GpuMat());
|
||||
|
||||
void makeGpuCollection(GpuMat& trainCollection, GpuMat& maskCollection,
|
||||
const vector<GpuMat>& masks = std::vector<GpuMat>());
|
||||
|
||||
void matchCollection(const GpuMat& queryDescs,
|
||||
const GpuMat& trainCollection,
|
||||
GpuMat& trainIdx, GpuMat& imgIdx, GpuMat& distance,
|
||||
const GpuMat& maskCollection);
|
||||
|
||||
static void matchDownload(const GpuMat& trainIdx, GpuMat& imgIdx,
|
||||
const GpuMat& distance, std::vector<DMatch>& matches);
|
||||
|
||||
void match(const GpuMat& queryDescs, std::vector<DMatch>& matches,
|
||||
const std::vector<GpuMat>& masks = std::vector<GpuMat>());
|
||||
|
||||
void knnMatch(const GpuMat& queryDescs, const GpuMat& trainDescs,
|
||||
GpuMat& trainIdx, GpuMat& distance, GpuMat& allDist, int k,
|
||||
const GpuMat& mask = GpuMat());
|
||||
|
||||
static void knnMatchDownload(const GpuMat& trainIdx,
|
||||
const GpuMat& distance, std::vector< std::vector<DMatch> >& matches,
|
||||
bool compactResult = false);
|
||||
|
||||
void knnMatch(const GpuMat& queryDescs, const GpuMat& trainDescs,
|
||||
std::vector< std::vector<DMatch> >& matches, int k,
|
||||
const GpuMat& mask = GpuMat(), bool compactResult = false);
|
||||
|
||||
void knnMatch(const GpuMat& queryDescs,
|
||||
std::vector< std::vector<DMatch> >& matches, int knn,
|
||||
const std::vector<GpuMat>& masks = std::vector<GpuMat>(),
|
||||
bool compactResult = false );
|
||||
|
||||
void radiusMatch(const GpuMat& queryDescs, const GpuMat& trainDescs,
|
||||
GpuMat& trainIdx, GpuMat& nMatches, GpuMat& distance,
|
||||
float maxDistance, const GpuMat& mask = GpuMat());
|
||||
|
||||
static void radiusMatchDownload(const GpuMat& trainIdx,
|
||||
const GpuMat& nMatches, const GpuMat& distance,
|
||||
std::vector< std::vector<DMatch> >& matches,
|
||||
bool compactResult = false);
|
||||
|
||||
void radiusMatch(const GpuMat& queryDescs, const GpuMat& trainDescs,
|
||||
std::vector< std::vector<DMatch> >& matches, float maxDistance,
|
||||
const GpuMat& mask = GpuMat(), bool compactResult = false);
|
||||
|
||||
void radiusMatch(const GpuMat& queryDescs,
|
||||
std::vector< std::vector<DMatch> >& matches, float maxDistance,
|
||||
const std::vector<GpuMat>& masks = std::vector<GpuMat>(),
|
||||
bool compactResult = false);
|
||||
|
||||
private:
|
||||
std::vector<GpuMat> trainDescCollection;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class \texttt{BruteForceMatcher\_GPU} has the similar interface to class \hyperref[cv.class.DescriptorMatcher]{cv::DescriptorMatcher}. It has two groups of match methods: for matching descriptors of one image with other image or with image set. Also all functions have alternative: save results to GPU memory or to CPU memory.
|
||||
|
||||
\texttt{Distance} template parameter is kept for CPU/GPU interfaces similarity. \texttt{BruteForceMatcher\_GPU} supports only \texttt{L1<float>} and \texttt{L2<float>} distance types.
|
||||
|
||||
See also: \hyperref[cv.class.DescriptorMatcher]{cv::DescriptorMatcher}, \hyperref[cv.class.BruteForceMatcher]{cv::BruteForceMatcher}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::BruteForceMatcher\_GPU::match}\label{cppfunc.gpu.BruteForceMatcher.match}
|
||||
Finds the best match for each descriptor from a query set with train descriptors.
|
||||
|
||||
\cvdefCpp{
|
||||
void match(const GpuMat\& queryDescs, \par const GpuMat\& trainDescs, \par std::vector<DMatch>\& matches, \par const GpuMat\& mask = GpuMat());\newline
|
||||
void match(const GpuMat\& queryDescs, \par std::vector<DMatch>\& matches, \par const std::vector<GpuMat>\& masks = std::vector<GpuMat>());
|
||||
}
|
||||
|
||||
See also: \cvCppCross{DescriptorMatcher::match}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::BruteForceMatcher\_GPU::matchSingle}\label{cppfunc.gpu.BruteForceMatcher.matchSingle}
|
||||
Finds the best match for each query descriptor. Results will be stored to GPU memory.
|
||||
|
||||
\cvdefCpp{
|
||||
void matchSingle(const GpuMat\& queryDescs, \par const GpuMat\& trainDescs, \par GpuMat\& trainIdx, \par GpuMat\& distance, \par const GpuMat\& mask = GpuMat());
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{queryDescs} {Query set of descriptors.}
|
||||
\cvarg{trainDescs} {Train set of descriptors. This will not be added to train descriptors collection stored in class object.}
|
||||
\cvarg{trainIdx} {One row \texttt{CV\_32SC1} matrix. Will contain the best train index for each query. If some query descriptors are masked out in \texttt{mask} it will contain -1.}
|
||||
\cvarg{distance} {One row \texttt{CV\_32FC1} matrix. Will contain the best distance for each query. If some query descriptors are masked out in \texttt{mask} it will contain \texttt{FLT\_MAX}.}
|
||||
\cvarg{mask}{Mask specifying permissible matches between input query and train matrices of descriptors.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::BruteForceMatcher\_GPU::matchCollection}\label{cppfunc.gpu.BruteForceMatcher.matchCollection}
|
||||
Find the best match for each query descriptor from train collection. Results will be stored to GPU memory.
|
||||
|
||||
\cvdefCpp{
|
||||
void matchCollection(const GpuMat\& queryDescs, \par const GpuMat\& trainCollection, \par GpuMat\& trainIdx, \par GpuMat\& imgIdx, \par GpuMat\& distance, \par const GpuMat\& maskCollection);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{queryDescs} {Query set of descriptors.}
|
||||
\cvarg{trainCollection} {\texttt{GpuMat} containing train collection. It can be obtained from train descriptors collection that was set using \texttt{add} method by \hyperref[cppfunc.gpu.BruteForceMatcher.makeGpuCollection]{makeGpuCollection}. Or it can contain user defined collection. It must be one row matrix, each element is a \texttt{DevMem2D} that points to one train descriptors matrix.}
|
||||
\cvarg{trainIdx} {One row \texttt{CV\_32SC1} matrix. Will contain the best train index for each query. If some query descriptors are masked out in \texttt{maskCollection} it will contain -1.}
|
||||
\cvarg{imgIdx} {One row \texttt{CV\_32SC1} matrix. Will contain image train index for each query. If some query descriptors are masked out in \texttt{maskCollection} it will contain -1.}
|
||||
\cvarg{distance} {One row \texttt{CV\_32FC1} matrix. Will contain the best distance for each query. If some query descriptors are masked out in \texttt{maskCollection} it will contain \texttt{FLT\_MAX}.}
|
||||
\cvarg{maskCollection}{\texttt{GpuMat} containing set of masks. It can be obtained from \texttt{std::vector<GpuMat>} by \hyperref[cppfunc.gpu.BruteForceMatcher.makeGpuCollection]{makeGpuCollection}. Or it can contain user defined mask set. It must be empty matrix or one row matrix, each element is a \texttt{PtrStep} that points to one mask.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::BruteForceMatcher\_GPU::makeGpuCollection}\label{cppfunc.gpu.BruteForceMatcher.makeGpuCollection}
|
||||
Makes gpu collection of train descriptors and masks in suitable format for \hyperref[cppfunc.gpu.BruteForceMatcher.matchCollection]{matchCollection} function.
|
||||
|
||||
\cvdefCpp{
|
||||
void makeGpuCollection(GpuMat\& trainCollection, \par GpuMat\& maskCollection, \par const vector<GpuMat>\& masks = std::vector<GpuMat>());
|
||||
}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::BruteForceMatcher\_GPU::matchDownload}\label{cppfunc.gpu.BruteForceMatcher.matchDownload}
|
||||
Downloads \texttt{trainIdx}, \texttt{imgIdx} and \texttt{distance} matrices obtained via \hyperref[cppfunc.gpu.BruteForceMatcher.matchSingle]{matchSingle} or \hyperref[cppfunc.gpu.BruteForceMatcher.matchCollection]{matchCollection} to CPU vector with \hyperref[cv.class.DMatch]{cv::DMatch}.
|
||||
|
||||
\cvdefCpp{
|
||||
void matchDownload(const GpuMat\& trainIdx, \par const GpuMat\& distance, \par std::vector<DMatch>\& matches); \newline
|
||||
void matchDownload(const GpuMat\& trainIdx, \par GpuMat\& imgIdx, \par const GpuMat\& distance, \par std::vector<DMatch>\& matches);
|
||||
}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::BruteForceMatcher\_GPU::knnMatch}\label{cppfunc.gpu.BruteForceMatcher.knnMatch}
|
||||
Finds the k best matches for each descriptor from a query set with train descriptors. Found k (or less if not possible) matches are returned in distance increasing order.
|
||||
|
||||
\cvdefCpp{
|
||||
void knnMatch(const GpuMat\& queryDescs, \par const GpuMat\& trainDescs, \par std::vector< std::vector<DMatch> >\& matches, \par int k, \par const GpuMat\& mask = GpuMat(), \par bool compactResult = false);
|
||||
}
|
||||
\cvdefCpp{
|
||||
void knnMatch(const GpuMat\& queryDescs, \par std::vector< std::vector<DMatch> >\& matches, \par int k, \par const std::vector<GpuMat>\& masks = std::vector<GpuMat>(), \par bool compactResult = false );
|
||||
}
|
||||
|
||||
See also: \cvCppCross{DescriptorMatcher::knnMatch}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::BruteForceMatcher\_GPU::knnMatch}\label{cppfunc.gpu.BruteForceMatcher.knnMatchSingle}
|
||||
Finds the k best matches for each descriptor from a query set with train descriptors. Found k (or less if not possible) matches are returned in distance increasing order. Results will be stored to GPU memory.
|
||||
|
||||
\cvdefCpp{
|
||||
void knnMatch(const GpuMat\& queryDescs, \par const GpuMat\& trainDescs, \par GpuMat\& trainIdx, \par GpuMat\& distance, \par GpuMat\& allDist, \par int k, \par const GpuMat\& mask = GpuMat());
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{queryDescs} {Query set of descriptors.}
|
||||
\cvarg{trainDescs} {Train set of descriptors. This will not be added to train descriptors collection stored in class object.}
|
||||
\cvarg{trainIdx} {Matrix with $\texttt{nQueries} \times \texttt{k}$ size and \texttt{CV\_32SC1} type. \texttt{trainIdx.at<int>(queryIdx, i)} will contain index of the i'th best trains. If some query descriptors are masked out in \texttt{mask} it will contain -1.}
|
||||
\cvarg{distance} {Matrix with $\texttt{nQuery} \times \texttt{k}$ and \texttt{CV\_32FC1} type. Will contain distance for each query and the i'th best trains. If some query descriptors are masked out in \texttt{mask} it will contain \texttt{FLT\_MAX}.}
|
||||
\cvarg{allDist} {Buffer to store all distances between query descriptors and train descriptors. It will have $\texttt{nQuery} \times \texttt{nTrain}$ size and \texttt{CV\_32FC1} type. \texttt{allDist.at<float>(queryIdx, trainIdx)} will contain \texttt{FLT\_MAX}, if \texttt{trainIdx} is one from k best, otherwise it will contain distance between \texttt{queryIdx} and \texttt{trainIdx} descriptors.}
|
||||
\cvarg{k}{Number of the best matches will be found per each query descriptor (or less if it's not possible).}
|
||||
\cvarg{mask}{Mask specifying permissible matches between input query and train matrices of descriptors.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::BruteForceMatcher\_GPU::knnMatchDownload}\label{cppfunc.gpu.BruteForceMatcher.knnMatchDownload}
|
||||
Downloads \texttt{trainIdx} and \texttt{distance} matrices obtained via \hyperref[cppfunc.gpu.BruteForceMatcher.knnMatchSingle]{knnMatch} to CPU vector with \hyperref[cv.class.DMatch]{cv::DMatch}. If \texttt{compactResult} is true \texttt{matches} vector will not contain matches for fully masked out query descriptors.
|
||||
|
||||
\cvdefCpp{
|
||||
void knnMatchDownload(const GpuMat\& trainIdx, \par const GpuMat\& distance, \par std::vector< std::vector<DMatch> >\& matches, \par bool compactResult = false);
|
||||
}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::BruteForceMatcher\_GPU::radiusMatch}\label{cppfunc.gpu.BruteForceMatcher.radiusMatch}
|
||||
Finds the best matches for each query descriptor which have distance less than given threshold. Found matches are returned in distance increasing order.
|
||||
|
||||
\cvdefCpp{
|
||||
void radiusMatch(const GpuMat\& queryDescs, \par const GpuMat\& trainDescs, \par std::vector< std::vector<DMatch> >\& matches, \par float maxDistance, \par const GpuMat\& mask = GpuMat(), \par bool compactResult = false);
|
||||
}
|
||||
\cvdefCpp{
|
||||
void radiusMatch(const GpuMat\& queryDescs, \par std::vector< std::vector<DMatch> >\& matches, \par float maxDistance, \par const std::vector<GpuMat>\& masks = std::vector<GpuMat>(), \par bool compactResult = false);
|
||||
}
|
||||
|
||||
\textbf{Please note:} This function works only on devices with Compute Capability $>=$ 1.1.
|
||||
|
||||
See also: \cvCppCross{DescriptorMatcher::radiusMatch}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::BruteForceMatcher\_GPU::radiusMatch}\label{cppfunc.gpu.BruteForceMatcher.radiusMatchSingle}
|
||||
Finds the best matches for each query descriptor which have distance less than given threshold. Results will be stored to GPU memory.
|
||||
|
||||
\cvdefCpp{
|
||||
void radiusMatch(const GpuMat\& queryDescs, \par const GpuMat\& trainDescs, \par GpuMat\& trainIdx, \par GpuMat\& nMatches, \par GpuMat\& distance, \par float maxDistance, \par const GpuMat\& mask = GpuMat());
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{queryDescs} {Query set of descriptors.}
|
||||
\cvarg{trainDescs} {Train set of descriptors. This will not be added to train descriptors collection stored in class object.}
|
||||
\cvarg{trainIdx} {\texttt{trainIdx.at<int>(queryIdx, i)} will contain i'th train index \newline\texttt{(i < min(nMatches.at<unsigned int>(0, queryIdx), trainIdx.cols)}. If \texttt{trainIdx} is empty, it will be created with size $\texttt{nQuery} \times \texttt{nTrain}$. Or it can be allocated by user (it must have \texttt{nQuery} rows and \texttt{CV\_32SC1} type). Cols can be less than \texttt{nTrain}, but it can be that matcher won't find all matches, because it haven't enough memory to store results.}
|
||||
\cvarg{nMatches} {\texttt{nMatches.at<unsigned int>(0, queryIdx)} will contain matches count for \texttt{queryIdx}. Carefully, \texttt{nMatches} can be greater than \texttt{trainIdx.cols} - it means that matcher didn't find all matches, because it didn't have enough memory.}
|
||||
\cvarg{distance} {\texttt{distance.at<int>(queryIdx, i)} will contain i'th distance \newline\texttt{(i < min(nMatches.at<unsigned int>(0, queryIdx), trainIdx.cols)}. If \texttt{trainIdx} is empty, it will be created with size $\texttt{nQuery} \times \texttt{nTrain}$. Otherwise it must be also allocated by user (it must have the same size as \texttt{trainIdx} and \texttt{CV\_32FC1} type).}
|
||||
\cvarg{maxDistance}{Distance threshold.}
|
||||
\cvarg{mask}{Mask specifying permissible matches between input query and train matrices of descriptors.}
|
||||
\end{description}
|
||||
|
||||
In contrast to \hyperref[cppfunc.gpu.BruteForceMatcher.radiusMatch]{cv::gpu::BruteForceMather\_GPU::radiusMatch} results are not sorted by distance increasing order.
|
||||
|
||||
\textbf{Please note:} This function works only on devices with Compute Capability $>=$ 1.1.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::BruteForceMatcher\_GPU::radiusMatchDownload}\label{cppfunc.gpu.BruteForceMatcher.radiusMatchDownload}
|
||||
Downloads \texttt{trainIdx}, \texttt{nMatches} and \texttt{distance} matrices obtained via \hyperref[cppfunc.gpu.BruteForceMatcher.radiusMatchSingle]{radiusMatch} to CPU vector with \hyperref[cv.class.DMatch]{cv::DMatch}. If \texttt{compactResult} is true \texttt{matches} vector will not contain matches for fully masked out query descriptors.
|
||||
|
||||
\cvdefCpp{
|
||||
void radiusMatchDownload(const GpuMat\& trainIdx, \par const GpuMat\& nMatches, \par const GpuMat\& distance, \par std::vector< std::vector<DMatch> >\& matches, \par bool compactResult = false);
|
||||
}
|
@ -1,594 +0,0 @@
|
||||
\section{Image Filtering}
|
||||
|
||||
Functions and classes described in this section are used to perform various linear or non-linear filtering operations on 2D images.
|
||||
|
||||
See also: \hyperref[section.cpp.cpu.ImageFiltering]{Image Filtering}
|
||||
|
||||
|
||||
\cvclass{gpu::BaseRowFilter\_GPU}\label{class.gpu.BaseRowFilter}
|
||||
The base class for linear or non-linear filters that processes rows of 2D arrays. Such filters are used for the "horizontal" filtering passes in separable filters.
|
||||
|
||||
\begin{lstlisting}
|
||||
class BaseRowFilter_GPU
|
||||
{
|
||||
public:
|
||||
BaseRowFilter_GPU(int ksize_, int anchor_);
|
||||
virtual ~BaseRowFilter_GPU() {}
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst) = 0;
|
||||
int ksize, anchor;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\textbf{Please note:} This class doesn't allocate memory for destination image. Usually this class is used inside \hyperref[class.gpu.FilterEngine]{cv::gpu::FilterEngine\_GPU}.
|
||||
|
||||
|
||||
\cvclass{gpu::BaseColumnFilter\_GPU}\label{class.gpu.BaseColumnFilter}
|
||||
The base class for linear or non-linear filters that processes columns of 2D arrays. Such filters are used for the "vertical" filtering passes in separable filters.
|
||||
|
||||
\begin{lstlisting}
|
||||
class BaseColumnFilter_GPU
|
||||
{
|
||||
public:
|
||||
BaseColumnFilter_GPU(int ksize_, int anchor_);
|
||||
virtual ~BaseColumnFilter_GPU() {}
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst) = 0;
|
||||
int ksize, anchor;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\textbf{Please note:} This class doesn't allocate memory for destination image. Usually this class is used inside \hyperref[class.gpu.FilterEngine]{cv::gpu::FilterEngine\_GPU}.
|
||||
|
||||
|
||||
\cvclass{gpu::BaseFilter\_GPU}\label{class.gpu.BaseFilter}
|
||||
The base class for non-separable 2D filters.
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS BaseFilter_GPU
|
||||
{
|
||||
public:
|
||||
BaseFilter_GPU(const Size& ksize_, const Point& anchor_);
|
||||
virtual ~BaseFilter_GPU() {}
|
||||
virtual void operator()(const GpuMat& src, GpuMat& dst) = 0;
|
||||
Size ksize;
|
||||
Point anchor;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\textbf{Please note:} This class doesn't allocate memory for destination image. Usually this class is used inside \hyperref[class.gpu.FilterEngine]{cv::gpu::FilterEngine\_GPU}.
|
||||
|
||||
|
||||
\cvclass{gpu::FilterEngine\_GPU}\label{class.gpu.FilterEngine}
|
||||
The base class for Filter Engine.
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS FilterEngine_GPU
|
||||
{
|
||||
public:
|
||||
virtual ~FilterEngine_GPU() {}
|
||||
|
||||
virtual void apply(const GpuMat& src, GpuMat& dst,
|
||||
Rect roi = Rect(0,0,-1,-1)) = 0;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class can be used to apply an arbitrary filtering operation to an image. It contains all the necessary intermediate buffers. Pointers to the initialized \texttt{FilterEngine\_GPU} instances are returned by various \texttt{create*Filter\_GPU} functions, see below, and they are used inside high-level functions such as \cvCppCross{gpu::filter2D}, \cvCppCross{gpu::erode}, \cvCppCross{gpu::Sobel} etc.
|
||||
|
||||
By using \texttt{FilterEngine\_GPU} instead of functions you can avoid unnecessary memory allocation for intermediate buffers and get much better performance:
|
||||
|
||||
\begin{lstlisting}
|
||||
while (...)
|
||||
{
|
||||
cv::gpu::GpuMat src = getImg();
|
||||
cv::gpu::GpuMat dst;
|
||||
// Allocate and release buffers at each iterations
|
||||
cv::gpu::GaussianBlur(src, dst, ksize, sigma1);
|
||||
}
|
||||
|
||||
// Allocate buffers only once
|
||||
cv::Ptr<cv::gpu::FilterEngine_GPU> filter =
|
||||
cv::gpu::createGaussianFilter_GPU(CV_8UC4, ksize, sigma1);
|
||||
while (...)
|
||||
{
|
||||
cv::gpu::GpuMat src = getImg();
|
||||
cv::gpu::GpuMat dst;
|
||||
filter->apply(src, dst, cv::Rect(0, 0, src.cols, src.rows));
|
||||
}
|
||||
// Release buffers only once
|
||||
filter.release();
|
||||
\end{lstlisting}
|
||||
|
||||
\texttt{FilterEngine\_GPU} can process a rectangular sub-region of an image. By default, if \texttt{roi == Rect(0,0,-1,-1)}, \texttt{FilterEngine\_GPU} processes inner region of image (\texttt{Rect(anchor.x, anchor.y, src\_size.width - ksize.width, src\_size.height - ksize.height)}), because some filters doesn't check if indices are outside the image for better perfomace. See below which filters supports processing the whole image and which not and image type limitations.
|
||||
|
||||
\textbf{Please note:} The GPU filters doesn't support the in-place mode.
|
||||
|
||||
See also: \hyperref[class.gpu.BaseRowFilter]{cv::gpu::BaseRowFilter\_GPU}, \hyperref[class.gpu.BaseColumnFilter]{cv::gpu::BaseColumnFilter\_GPU}, \hyperref[class.gpu.BaseFilter]{cv::gpu::BaseFilter\_GPU}, \hyperref[cppfunc.gpu.createFilter2D]{cv::gpu::createFilter2D\_GPU}, \hyperref[cppfunc.gpu.createSeparableFilter]{cv::gpu::createSeparableFilter\_GPU}, \hyperref[cppfunc.gpu.createBoxFilter]{cv::gpu::createBoxFilter\_GPU}, \hyperref[cppfunc.gpu.createMorphologyFilter]{cv::gpu::createMorphologyFilter\_GPU}, \hyperref[cppfunc.gpu.createLinearFilter]{cv::gpu::createLinearFilter\_GPU}, \hyperref[cppfunc.gpu.createSeparableLinearFilter]{cv::gpu::createSeparableLinearFilter\_GPU}, \hyperref[cppfunc.gpu.createDerivFilter]{cv::gpu::createDerivFilter\_GPU}, \hyperref[cppfunc.gpu.createGaussianFilter]{cv::gpu::createGaussianFilter\_GPU}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::createFilter2D\_GPU}\label{cppfunc.gpu.createFilter2D}
|
||||
Creates non-separable filter engine with the specified filter.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<FilterEngine\_GPU> createFilter2D\_GPU(\par const Ptr<BaseFilter\_GPU>\& filter2D, \par int srcType, int dstType);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{filter2D} {Non-separable 2D filter.}
|
||||
\cvarg{srcType}{Input image type. It must be supported by \texttt{filter2D}.}
|
||||
\cvarg{dstType}{Output image type. It must be supported by \texttt{filter2D}.}
|
||||
\end{description}
|
||||
|
||||
Usually this function is used inside high-level functions, like \hyperref[cppfunc.gpu.createLinearFilter]{cv::gpu::createLinearFilter\_GPU}, \hyperref[cppfunc.gpu.createBoxFilter]{cv::gpu::createBoxFilter\_GPU}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::createSeparableFilter\_GPU}\label{cppfunc.gpu.createSeparableFilter}
|
||||
Creates separable filter engine with the specified filters.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<FilterEngine\_GPU> createSeparableFilter\_GPU(\par const Ptr<BaseRowFilter\_GPU>\& rowFilter, \par const Ptr<BaseColumnFilter\_GPU>\& columnFilter, \par int srcType, int bufType, int dstType);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{rowFilter} {"Horizontal" 1D filter.}
|
||||
\cvarg{columnFilter} {"Vertical" 1D filter.}
|
||||
\cvarg{srcType}{Input image type. It must be supported by \texttt{rowFilter}.}
|
||||
\cvarg{bufType}{Buffer image type. It must be supported by \texttt{rowFilter} and \texttt{columnFilter}.}
|
||||
\cvarg{dstType}{Output image type. It must be supported by \texttt{columnFilter}.}
|
||||
\end{description}
|
||||
|
||||
Usually this function is used inside high-level functions, like \hyperref[cppfunc.gpu.createSeparableLinearFilter]{cv::gpu::createSeparableLinearFilter\_GPU}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::getRowSumFilter\_GPU}\label{cppfunc.gpu.getRowSumFilter}
|
||||
Creates horizontal 1D box filter.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<BaseRowFilter\_GPU> getRowSumFilter\_GPU(int srcType, int sumType, \par int ksize, int anchor = -1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{srcType}{Input image type. Only \texttt{CV\_8UC1} type is supported for now.}
|
||||
\cvarg{sumType}{Output image type. Only \texttt{CV\_32FC1} type is supported for now.}
|
||||
\cvarg{ksize}{Kernel size.}
|
||||
\cvarg{anchor}{Anchor point. The default value (-1) means that the anchor is at the kernel center.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::getColumnSumFilter\_GPU}\label{cppfunc.gpu.getColumnSumFilter}
|
||||
Creates vertical 1D box filter.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<BaseColumnFilter\_GPU> getColumnSumFilter\_GPU(int sumType, \par int dstType, int ksize, int anchor = -1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{sumType}{Input image type. Only \texttt{CV\_8UC1} type is supported for now.}
|
||||
\cvarg{dstType}{Output image type. Only \texttt{CV\_32FC1} type is supported for now.}
|
||||
\cvarg{ksize}{Kernel size.}
|
||||
\cvarg{anchor}{Anchor point. The default value (-1) means that the anchor is at the kernel center.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::createBoxFilter\_GPU}\label{cppfunc.gpu.createBoxFilter}
|
||||
Creates normalized 2D box filter.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<FilterEngine\_GPU> createBoxFilter\_GPU(int srcType, int dstType, \par const Size\& ksize, \par const Point\& anchor = Point(-1,-1));
|
||||
}
|
||||
\cvdefCpp{
|
||||
Ptr<BaseFilter\_GPU> getBoxFilter\_GPU(int srcType, int dstType, \par const Size\& ksize, \par Point anchor = Point(-1, -1));
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{srcType}{Input image type. Supports \texttt{CV\_8UC1} and \texttt{CV\_8UC4}.}
|
||||
\cvarg{dstType}{Output image type. Supports only the same as source type.}
|
||||
\cvarg{ksize}{Kernel size.}
|
||||
\cvarg{anchor}{Anchor point. The default value Point(-1, -1) means that the anchor is at the kernel center.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
See also: \cvCppCross{boxFilter}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::boxFilter}
|
||||
Smooths the image using the normalized box filter.
|
||||
|
||||
\cvdefCpp{
|
||||
void boxFilter(const GpuMat\& src, GpuMat\& dst, int ddepth, Size ksize, \par Point anchor = Point(-1,-1));
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Input image. Supports \texttt{CV\_8UC1} and \texttt{CV\_8UC4} source types.}
|
||||
\cvarg{dst}{Output image type. Will have the same size and the same type as \texttt{src}.}
|
||||
\cvarg{ddepth}{Output image depth. Support only the same as source depth (\texttt{CV\_8U}) or -1 what means use source depth.}
|
||||
\cvarg{ksize}{Kernel size.}
|
||||
\cvarg{anchor}{Anchor point. The default value Point(-1, -1) means that the anchor is at the kernel center.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
See also: \cvCppCross{boxFilter}, \hyperref[cppfunc.gpu.createBoxFilter]{cv::gpu::createBoxFilter\_GPU}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::blur}
|
||||
A synonym for normalized box filter.
|
||||
|
||||
\cvdefCpp{
|
||||
void blur(const GpuMat\& src, GpuMat\& dst, Size ksize, \par Point anchor = Point(-1,-1));
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Input image. Supports \texttt{CV\_8UC1} and \texttt{CV\_8UC4} source type.}
|
||||
\cvarg{dst}{Output image type. Will have the same size and the same type as \texttt{src}.}
|
||||
\cvarg{ksize}{Kernel size.}
|
||||
\cvarg{anchor}{Anchor point. The default value Point(-1, -1) means that the anchor is at the kernel center.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
See also: \cvCppCross{blur}, \cvCppCross{gpu::boxFilter}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::createMorphologyFilter\_GPU}\label{cppfunc.gpu.createMorphologyFilter}
|
||||
Creates 2D morphological filter.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<FilterEngine\_GPU> createMorphologyFilter\_GPU(int op, int type, \par const Mat\& kernel, \par const Point\& anchor = Point(-1,-1), \par int iterations = 1);
|
||||
}
|
||||
\cvdefCpp{
|
||||
Ptr<BaseFilter\_GPU> getMorphologyFilter\_GPU(int op, int type, \par const Mat\& kernel, const Size\& ksize, \par Point anchor=Point(-1,-1));
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{op} {Morphology operation id. Only \texttt{MORPH\_ERODE} and \texttt{MORPH\_DILATE} are supported.}
|
||||
\cvarg{type}{Input/output image type. Only \texttt{CV\_8UC1} and \texttt{CV\_8UC4} are supported.}
|
||||
\cvarg{kernel}{2D 8-bit structuring element for the morphological operation.}
|
||||
\cvarg{size}{Horizontal or vertical structuring element size for separable morphological operations.}
|
||||
\cvarg{anchor}{Anchor position within the structuring element; negative values mean that the anchor is at the center.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
See also: \cvCppCross{createMorphologyFilter}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::erode}
|
||||
Erodes an image by using a specific structuring element.
|
||||
|
||||
\cvdefCpp{
|
||||
void erode(const GpuMat\& src, GpuMat\& dst, const Mat\& kernel, \par Point anchor = Point(-1, -1), \par int iterations = 1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Only \texttt{CV\_8UC1} and \texttt{CV\_8UC4} types are supported.}
|
||||
\cvarg{dst}{Destination image. It will have the same size and the same type as \texttt{src}.}
|
||||
\cvarg{kernel}{Structuring element used for dilation. If \texttt{kernel=Mat()}, a $3 \times 3$ rectangular structuring element is used.}
|
||||
\cvarg{anchor}{Position of the anchor within the element. The default value $(-1, -1)$ means that the anchor is at the element center.}
|
||||
\cvarg{iterations}{Number of times erosion to be applied.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
See also: \cvCppCross{erode}, \hyperref[cppfunc.gpu.createMorphologyFilter]{cv::gpu::createMorphologyFilter\_GPU}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::dilate}
|
||||
Dilates an image by using a specific structuring element.
|
||||
|
||||
\cvdefCpp{
|
||||
void dilate(const GpuMat\& src, GpuMat\& dst, const Mat\& kernel, \par Point anchor = Point(-1, -1), \par int iterations = 1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8UC1} and \texttt{CV\_8UC4} source types.}
|
||||
\cvarg{dst}{Destination image. It will have the same size and the same type as \texttt{src}.}
|
||||
\cvarg{kernel}{Structuring element used for dilation. If \texttt{kernel=Mat()}, a $3 \times 3$ rectangular structuring element is used.}
|
||||
\cvarg{anchor}{Position of the anchor within the element. The default value $(-1, -1)$ means that the anchor is at the element center.}
|
||||
\cvarg{iterations}{Number of times dilation to be applied.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
See also: \cvCppCross{dilate}, \hyperref[cppfunc.gpu.createMorphologyFilter]{cv::gpu::createMorphologyFilter\_GPU}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::morphologyEx}
|
||||
Applies an advanced morphological operation to image.
|
||||
|
||||
\cvdefCpp{
|
||||
void morphologyEx(const GpuMat\& src, GpuMat\& dst, int op, \par const Mat\& kernel, \par Point anchor = Point(-1, -1), \par int iterations = 1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8UC1} and \texttt{CV\_8UC4} source type.}
|
||||
\cvarg{dst}{Destination image. It will have the same size and the same type as \texttt{src}}
|
||||
\cvarg{op}{Type of morphological operation, one of the following:
|
||||
\begin{description}
|
||||
\cvarg{MORPH\_OPEN}{opening}
|
||||
\cvarg{MORPH\_CLOSE}{closing}
|
||||
\cvarg{MORPH\_GRADIENT}{morphological gradient}
|
||||
\cvarg{MORPH\_TOPHAT}{"top hat"}
|
||||
\cvarg{MORPH\_BLACKHAT}{"black hat"}
|
||||
\end{description}}
|
||||
\cvarg{kernel}{Structuring element.}
|
||||
\cvarg{anchor}{Position of the anchor within the element. The default value Point(-1, -1) means that the anchor is at the element center.}
|
||||
\cvarg{iterations}{Number of times erosion and dilation to be applied.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
See also: \cvCppCross{morphologyEx}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::createLinearFilter\_GPU}\label{cppfunc.gpu.createLinearFilter}
|
||||
Creates the non-separable linear filter.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<FilterEngine\_GPU> createLinearFilter\_GPU(int srcType, int dstType, \par const Mat\& kernel, \par const Point\& anchor = Point(-1,-1));
|
||||
}
|
||||
\cvdefCpp{
|
||||
Ptr<BaseFilter\_GPU> getLinearFilter\_GPU(int srcType, int dstType, \par const Mat\& kernel, const Size\& ksize, \par Point anchor = Point(-1, -1));
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{srcType}{Input image type. Supports \texttt{CV\_8UC1} and \texttt{CV\_8UC4}.}
|
||||
\cvarg{dstType}{Output image type. Supports only the same as source type.}
|
||||
\cvarg{kernel}{2D array of filter coefficients. This filter works with integers kernels, if \texttt{kernel} has \texttt{float} or \texttt{double} type it will be used fixed point arithmetic.}
|
||||
\cvarg{ksize}{Kernel size.}
|
||||
\cvarg{anchor}{Anchor point. The default value Point(-1, -1) means that the anchor is at the kernel center.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
See also: \cvCppCross{createLinearFilter}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::filter2D}
|
||||
Applies non-separable 2D linear filter to image.
|
||||
|
||||
\cvdefCpp{
|
||||
void filter2D(const GpuMat\& src, GpuMat\& dst, int ddepth, \par const Mat\& kernel, \par Point anchor=Point(-1,-1));
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8UC1} and \texttt{CV\_8UC4} source types.}
|
||||
\cvarg{dst}{Destination image. It will have the same size and the same number of channels as \texttt{src}.}
|
||||
\cvarg{ddepth}{The desired depth of the destination image. If it is negative, it will be the same as \texttt{src.depth()}. Supports only the same depth as source image.}
|
||||
\cvarg{kernel}{2D array of filter coefficients. This filter works with integers kernels, if \texttt{kernel} has \texttt{float} or \texttt{double} type it will use fixed point arithmetic.}
|
||||
\cvarg{anchor}{Anchor of the kernel that indicates the relative position of a filtered point within the kernel. The anchor should lie within the kernel. The special default value (-1,-1) means that the anchor is at the kernel center.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
See also: \cvCppCross{filter2D}, \hyperref[cppfunc.gpu.createLinearFilter]{cv::gpu::createLinearFilter\_GPU}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::Laplacian}
|
||||
Applies Laplacian operator to image.
|
||||
|
||||
\cvdefCpp{
|
||||
void Laplacian(const GpuMat\& src, GpuMat\& dst, int ddepth, \par int ksize = 1, double scale = 1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8UC1} and \texttt{CV\_8UC4} source types.}
|
||||
\cvarg{dst}{Destination image; will have the same size and the same number of channels as \texttt{src}.}
|
||||
\cvarg{ddepth}{Desired depth of the destination image. Supports only tha same depth as source image depth.}
|
||||
\cvarg{ksize}{Aperture size used to compute the second-derivative filters, see \cvCppCross{getDerivKernels}. It must be positive and odd. Supports only \texttt{ksize} = 1 and \texttt{ksize} = 3.}
|
||||
\cvarg{scale}{Optional scale factor for the computed Laplacian values (by default, no scaling is applied, see \cvCppCross{getDerivKernels}).}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
See also: \cvCppCross{Laplacian}, \cvCppCross{gpu::filter2D}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::getLinearRowFilter\_GPU}\label{cppfunc.gpu.getLinearRowFilter}
|
||||
Creates primitive row filter with the specified kernel.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<BaseRowFilter\_GPU> getLinearRowFilter\_GPU(int srcType, \par int bufType, const Mat\& rowKernel, int anchor = -1, \par int borderType = BORDER\_CONSTANT);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{srcType}{Source array type. Supports only \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_16SC1}, \texttt{CV\_16SC2}, \texttt{CV\_32SC1}, \texttt{CV\_32FC1} source types.}
|
||||
\cvarg{bufType}{Inermediate buffer type; must have as many channels as \texttt{srcType}.}
|
||||
\cvarg{rowKernel}{Filter coefficients.}
|
||||
\cvarg{anchor}{Anchor position within the kernel; negative values mean that anchor is positioned at the aperture center.}
|
||||
\cvarg{borderType}{Pixel extrapolation method; see \cvCppCross{borderInterpolate}. About limitation see below.}
|
||||
\end{description}
|
||||
|
||||
There are two version of algorithm: NPP and OpenCV. NPP calls when \texttt{srcType == CV\_8UC1} or \texttt{srcType == CV\_8UC4} and \texttt{bufType == srcType}, otherwise calls OpenCV version. NPP supports only \texttt{BORDER\_CONSTANT} border type and doesn't check indices outside image. OpenCV version supports only \texttt{CV\_32F} buffer depth and \texttt{BORDER\_REFLECT101}, \texttt{BORDER\_REPLICATE} and \texttt{BORDER\_CONSTANT} border types and checks indices outside image.
|
||||
|
||||
See also: \hyperref[cppfunc.gpu.getLinearColumnFilter]{cv::gpu::getLinearColumnFilter\_GPU}, \cvCppCross{createSeparableLinearFilter}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::getLinearColumnFilter\_GPU}\label{cppfunc.gpu.getLinearColumnFilter}
|
||||
Creates the primitive column filter with the specified kernel.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<BaseColumnFilter\_GPU> getLinearColumnFilter\_GPU(int bufType, \par int dstType, const Mat\& columnKernel, int anchor = -1, \par int borderType = BORDER\_CONSTANT);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{bufType}{Inermediate buffer type; must have as many channels as \texttt{dstType}.}
|
||||
\cvarg{dstType}{Destination array type. Supports \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_16SC1}, \texttt{CV\_16SC2}, \texttt{CV\_32SC1}, \texttt{CV\_32FC1} destination types.}
|
||||
\cvarg{columnKernel}{Filter coefficients.}
|
||||
\cvarg{anchor}{Anchor position within the kernel; negative values mean that anchor is positioned at the aperture center.}
|
||||
\cvarg{borderType}{Pixel extrapolation method; see \cvCppCross{borderInterpolate}. About limitation see below.}
|
||||
\end{description}
|
||||
|
||||
There are two version of algorithm: NPP and OpenCV. NPP calls when \texttt{dstType == CV\_8UC1} or \texttt{dstType == CV\_8UC4} and \texttt{bufType == dstType}, otherwise calls OpenCV version. NPP supports only \texttt{BORDER\_CONSTANT} border type and doesn't check indices outside image. OpenCV version supports only \texttt{CV\_32F} buffer depth and \texttt{BORDER\_REFLECT101}, \texttt{BORDER\_REPLICATE} and \texttt{BORDER\_CONSTANT} border types and checks indices outside image.\newline
|
||||
|
||||
See also: \hyperref[cppfunc.gpu.getLinearRowFilter]{cv::gpu::getLinearRowFilter\_GPU}, \cvCppCross{createSeparableLinearFilter}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::createSeparableLinearFilter\_GPU}\label{cppfunc.gpu.createSeparableLinearFilter}
|
||||
Creates the separable linear filter engine.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<FilterEngine\_GPU> createSeparableLinearFilter\_GPU(int srcType, \par int dstType, const Mat\& rowKernel, const Mat\& columnKernel, \par const Point\& anchor = Point(-1,-1), \par int rowBorderType = BORDER\_DEFAULT, \par int columnBorderType = -1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{srcType}{Source array type. Supports \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_16SC1}, \texttt{CV\_16SC2}, \texttt{CV\_32SC1}, \texttt{CV\_32FC1} source types.}
|
||||
\cvarg{dstType}{Destination array type. Supports \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_16SC1}, \texttt{CV\_16SC2}, \texttt{CV\_32SC1}, \texttt{CV\_32FC1} destination types.}
|
||||
\cvarg{rowKernel, columnKernel}{Filter coefficients.}
|
||||
\cvarg{anchor}{Anchor position within the kernel; negative values mean that anchor is positioned at the aperture center.}
|
||||
\cvarg{rowBorderType, columnBorderType}{Pixel extrapolation method in the horizontal and the vertical directions; see \cvCppCross{borderInterpolate}. About limitation see \hyperref[cppfunc.gpu.getLinearRowFilter]{cv::gpu::getLinearRowFilter\_GPU}, \hyperref[cppfunc.gpu.getLinearColumnFilter]{cv::gpu::getLinearColumnFilter\_GPU}.}
|
||||
\end{description}
|
||||
|
||||
See also: \hyperref[cppfunc.gpu.getLinearRowFilter]{cv::gpu::getLinearRowFilter\_GPU}, \hyperref[cppfunc.gpu.getLinearColumnFilter]{cv::gpu::getLinearColumnFilter\_GPU}, \cvCppCross{createSeparableLinearFilter}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::sepFilter2D}
|
||||
Applies separable 2D linear filter to the image.
|
||||
|
||||
\cvdefCpp{
|
||||
void sepFilter2D(const GpuMat\& src, GpuMat\& dst, int ddepth, \par const Mat\& kernelX, const Mat\& kernelY, \par Point anchor = Point(-1,-1), \par int rowBorderType = BORDER\_DEFAULT, \par int columnBorderType = -1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_16SC1}, \texttt{CV\_16SC2}, \texttt{CV\_32SC1}, \texttt{CV\_32FC1} source types.}
|
||||
\cvarg{dst}{Destination image; will have the same size and the same number of channels as \texttt{src}.}
|
||||
\cvarg{ddepth}{Destination image depth. Supports \texttt{CV\_8U}, \texttt{CV\_16S}, \texttt{CV\_32S} and \texttt{CV\_32F}.}
|
||||
\cvarg{kernelX, kernelY}{Filter coefficients.}
|
||||
\cvarg{anchor}{Anchor position within the kernel; The default value $(-1, 1)$ means that the anchor is at the kernel center.}
|
||||
\cvarg{rowBorderType, columnBorderType}{Pixel extrapolation method; see \cvCppCross{borderInterpolate}.}
|
||||
\end{description}
|
||||
|
||||
See also: \hyperref[cppfunc.gpu.createSeparableLinearFilter]{cv::gpu::createSeparableLinearFilter\_GPU}, \cvCppCross{sepFilter2D}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::createDerivFilter\_GPU}\label{cppfunc.gpu.createDerivFilter}
|
||||
Creates filter engine for the generalized Sobel operator.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<FilterEngine\_GPU> createDerivFilter\_GPU(int srcType, int dstType, \par int dx, int dy, int ksize, \par int rowBorderType = BORDER\_DEFAULT, \par int columnBorderType = -1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{srcType}{Source image type. Supports \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_16SC1}, \texttt{CV\_16SC2}, \texttt{CV\_32SC1}, \texttt{CV\_32FC1} source types.}
|
||||
\cvarg{dstType}{Destination image type; must have as many channels as \texttt{srcType}. Supports \texttt{CV\_8U}, \texttt{CV\_16S}, \texttt{CV\_32S} and \texttt{CV\_32F} depths.}
|
||||
\cvarg{dx}{Derivative order in respect with x.}
|
||||
\cvarg{dy}{Derivative order in respect with y.}
|
||||
\cvarg{ksize}{Aperture size; see \cvCppCross{getDerivKernels}.}
|
||||
\cvarg{rowBorderType, columnBorderType}{Pixel extrapolation method; see \cvCppCross{borderInterpolate}.}
|
||||
\end{description}
|
||||
|
||||
See also: \hyperref[cppfunc.gpu.createSeparableLinearFilter]{cv::gpu::createSeparableLinearFilter\_GPU}, \cvCppCross{createDerivFilter}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::Sobel}
|
||||
Applies generalized Sobel operator to the image.
|
||||
|
||||
\cvdefCpp{
|
||||
void Sobel(const GpuMat\& src, GpuMat\& dst, int ddepth, int dx, int dy, \par int ksize = 3, double scale = 1, \par int rowBorderType = BORDER\_DEFAULT, \par int columnBorderType = -1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_16SC1}, \texttt{CV\_16SC2}, \texttt{CV\_32SC1}, \texttt{CV\_32FC1} source types.}
|
||||
\cvarg{dst}{Destination image. Will have the same size and number of channels as source image.}
|
||||
\cvarg{ddepth}{Destination image depth. Supports \texttt{CV\_8U}, \texttt{CV\_16S}, \texttt{CV\_32S} and \texttt{CV\_32F}.}
|
||||
\cvarg{dx}{Derivative order in respect with x.}
|
||||
\cvarg{dy}{Derivative order in respect with y.}
|
||||
\cvarg{ksize}{Size of the extended Sobel kernel, must be 1, 3, 5 or 7.}
|
||||
\cvarg{scale}{Optional scale factor for the computed derivative values (by default, no scaling is applied, see \cvCppCross{getDerivKernels}).}
|
||||
\cvarg{rowBorderType, columnBorderType}{Pixel extrapolation method; see \cvCppCross{borderInterpolate}.}
|
||||
\end{description}
|
||||
|
||||
See also: \hyperref[cppfunc.gpu.createSeparableLinearFilter]{cv::gpu::createSeparableLinearFilter\_GPU}, \cvCppCross{Sobel}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::Scharr}
|
||||
Calculates the first x- or y- image derivative using Scharr operator.
|
||||
|
||||
\cvdefCpp{
|
||||
void Scharr(const GpuMat\& src, GpuMat\& dst, int ddepth, \par int dx, int dy, double scale = 1, \par int rowBorderType = BORDER\_DEFAULT, \par int columnBorderType = -1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_16SC1}, \texttt{CV\_16SC2}, \texttt{CV\_32SC1}, \texttt{CV\_32FC1} source types.}
|
||||
\cvarg{dst}{Destination image; will have the same size and the same number of channels as \texttt{src}.}
|
||||
\cvarg{ddepth}{Destination image depth. Supports \texttt{CV\_8U}, \texttt{CV\_16S}, \texttt{CV\_32S} and \texttt{CV\_32F}.}
|
||||
\cvarg{xorder}{Order of the derivative x.}
|
||||
\cvarg{yorder}{Order of the derivative y.}
|
||||
\cvarg{scale}{Optional scale factor for the computed derivative values (by default, no scaling is applied, see \cvCppCross{getDerivKernels}).}
|
||||
\cvarg{rowBorderType, columnBorderType}{Pixel extrapolation method, see \cvCppCross{borderInterpolate}}
|
||||
\end{description}
|
||||
|
||||
See also: \hyperref[cppfunc.gpu.createSeparableLinearFilter]{cv::gpu::createSeparableLinearFilter\_GPU}, \cvCppCross{Scharr}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::createGaussianFilter\_GPU}\label{cppfunc.gpu.createGaussianFilter}
|
||||
Creates Gaussian filter engine.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<FilterEngine\_GPU> createGaussianFilter\_GPU(int type, Size ksize, \par double sigmaX, double sigmaY = 0, \par int rowBorderType = BORDER\_DEFAULT, \par int columnBorderType = -1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{type}{Source and the destination image type. Supports \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_16SC1}, \texttt{CV\_16SC2}, \texttt{CV\_32SC1}, \texttt{CV\_32FC1}.}
|
||||
\cvarg{ksize}{Aperture size; see \cvCppCross{getGaussianKernel}.}
|
||||
\cvarg{sigmaX}{Gaussian sigma in the horizontal direction; see \cvCppCross{getGaussianKernel}.}
|
||||
\cvarg{sigmaY}{Gaussian sigma in the vertical direction; if 0, then $\texttt{sigmaY}\leftarrow\texttt{sigmaX}$.}
|
||||
\cvarg{rowBorderType, columnBorderType}{Which border type to use; see \cvCppCross{borderInterpolate}.}
|
||||
\end{description}
|
||||
|
||||
See also: \hyperref[cppfunc.gpu.createSeparableLinearFilter]{cv::gpu::createSeparableLinearFilter\_GPU}, \cvCppCross{createGaussianFilter}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::GaussianBlur}
|
||||
Smooths the image using Gaussian filter.
|
||||
|
||||
\cvdefCpp{
|
||||
void GaussianBlur(const GpuMat\& src, GpuMat\& dst, Size ksize, \par double sigmaX, double sigmaY = 0, \par int rowBorderType = BORDER\_DEFAULT, \par int columnBorderType = -1);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_16SC1}, \texttt{CV\_16SC2}, \texttt{CV\_32SC1}, \texttt{CV\_32FC1} source types.}
|
||||
\cvarg{dst}{Destination image; will have the same size and the same type as \texttt{src}.}
|
||||
\cvarg{ksize}{Gaussian kernel size; \texttt{ksize.width} and \texttt{ksize.height} can differ, but they both must be positive and odd. Or, they can be zero's, then they are computed from \texttt{sigmaX} amd \texttt{sigmaY}.}
|
||||
\cvarg{sigmaX, sigmaY}{Gaussian kernel standard deviations in X and Y direction. If \texttt{sigmaY} is zero, it is set to be equal to \texttt{sigmaX}. If they are both zeros, they are computed from \texttt{ksize.width} and \texttt{ksize.height}, respectively, see \cvCppCross{getGaussianKernel}. To fully control the result regardless of possible future modification of all this semantics, it is recommended to specify all of \texttt{ksize}, \texttt{sigmaX} and \texttt{sigmaY}.}
|
||||
\cvarg{rowBorderType, columnBorderType}{Pixel extrapolation method; see \cvCppCross{borderInterpolate}.}
|
||||
\end{description}
|
||||
|
||||
See also: \hyperref[cppfunc.gpu.createGaussianFilter]{cv::gpu::createGaussianFilter\_GPU}, \cvCppCross{GaussianBlur}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::getMaxFilter\_GPU}\label{cppfunc.gpu.getMaxFilter}
|
||||
Creates maximum filter.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<BaseFilter\_GPU> getMaxFilter\_GPU(int srcType, int dstType, \par const Size\& ksize, Point anchor = Point(-1,-1));
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{srcType}{Input image type. Supports only \texttt{CV\_8UC1} and \texttt{CV\_8UC4}.}
|
||||
\cvarg{dstType}{Output image type. Supports only the same type as source.}
|
||||
\cvarg{ksize}{Kernel size.}
|
||||
\cvarg{anchor}{Anchor point. The default value (-1) means that the anchor is at the kernel center.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::getMinFilter\_GPU}\label{cppfunc.gpu.getMinFilter}
|
||||
Creates minimum filter.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<BaseFilter\_GPU> getMinFilter\_GPU(int srcType, int dstType, \par const Size\& ksize, Point anchor = Point(-1,-1));
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{srcType}{Input image type. Supports only \texttt{CV\_8UC1} and \texttt{CV\_8UC4}.}
|
||||
\cvarg{dstType}{Output image type. Supports only the same type as source.}
|
||||
\cvarg{ksize}{Kernel size.}
|
||||
\cvarg{anchor}{Anchor point. The default value (-1) means that the anchor is at the kernel center.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This filter doesn't check out of border accesses, so only proper submatrix of bigger matrix have to be passed to it.
|
@ -1,499 +0,0 @@
|
||||
\section{Image Processing}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::meanShiftFiltering}
|
||||
Performs mean-shift filtering for each point of the source image. It maps each point of the source image into another point, and as the result we have new color and new position of each point.
|
||||
|
||||
\cvdefCpp{void meanShiftFiltering(const GpuMat\& src, GpuMat\& dst,\par
|
||||
int sp, int sr,\par
|
||||
TermCriteria criteria = TermCriteria(TermCriteria::MAX\_ITER\par
|
||||
+ TermCriteria::EPS, 5, 1));}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Only \texttt{CV\_8UC4} images are supported for now.}
|
||||
\cvarg{dst}{Destination image, containing color of mapped points. Will have the same size and type as \texttt{src}.}
|
||||
\cvarg{sp}{Spatial window radius.}
|
||||
\cvarg{sr}{Color window radius.}
|
||||
\cvarg{criteria}{Termination criteria. See \hyperref[TermCriteria]{cv::TermCriteria}.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This function works only on devices with Compute Capability $>=$ 1.2.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::meanShiftProc}
|
||||
Performs mean-shift procedure and stores information about processed points (i.e. their colors and positions) into two images.
|
||||
|
||||
\cvdefCpp{void meanShiftProc(const GpuMat\& src, GpuMat\& dstr, GpuMat\& dstsp,\par
|
||||
int sp, int sr,\par
|
||||
TermCriteria criteria = TermCriteria(TermCriteria::MAX\_ITER\par
|
||||
+ TermCriteria::EPS, 5, 1));}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Only \texttt{CV\_8UC4} images are supported for now.}
|
||||
\cvarg{dstr}{Destination image, containing color of mapped points. Will have the same size and type as \texttt{src}.}
|
||||
\cvarg{dstsp}{Destination image, containing position of mapped points. Will have the same size as \texttt{src} and \texttt{CV\_16SC2} type.}
|
||||
\cvarg{sp}{Spatial window radius.}
|
||||
\cvarg{sr}{Color window radius.}
|
||||
\cvarg{criteria}{Termination criteria. See \hyperref[TermCriteria]{cv::TermCriteria}.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This function works only on devices with Compute Capability $>=$ 1.2.
|
||||
|
||||
See also: \cvCppCross{gpu::meanShiftFiltering}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::meanShiftSegmentation}
|
||||
Performs mean-shift segmentation of the source image and eleminates small segments.
|
||||
|
||||
\cvdefCpp{void meanShiftSegmentation(const GpuMat\& src, Mat\& dst,\par
|
||||
int sp, int sr, int minsize,\par
|
||||
TermCriteria criteria = TermCriteria(TermCriteria::MAX\_ITER\par
|
||||
+ TermCriteria::EPS, 5, 1));}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Only \texttt{CV\_8UC4} images are supported for now.}
|
||||
\cvarg{dst}{Segmented image. Will have the same size and type as \texttt{src}.}
|
||||
\cvarg{sp}{Spatial window radius.}
|
||||
\cvarg{sr}{Color window radius.}
|
||||
\cvarg{minsize}{Minimum segment size. Smaller segements will be merged.}
|
||||
\cvarg{criteria}{Termination criteria. See \hyperref[TermCriteria]{cv::TermCriteria}.}
|
||||
\end{description}
|
||||
|
||||
\textbf{Please note:} This function works only on devices with Compute Capability $>=$ 1.2.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::integral}
|
||||
Computes integral image and squared integral image.
|
||||
|
||||
\cvdefCpp{void integral(const GpuMat\& src, GpuMat\& sum);\newline
|
||||
void integral(const GpuMat\& src, GpuMat\& sum, GpuMat\& sqsum);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Only \texttt{CV\_8UC1} images are supported for now.}
|
||||
\cvarg{sum}{Integral image. Will contain 32-bit unsigned integer values packed into \texttt{CV\_32SC1}.}
|
||||
\cvarg{sqsum}{Squared integral image. Will have \texttt{CV\_32FC1} type.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{integral}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::sqrIntegral}
|
||||
Computes squared integral image.
|
||||
|
||||
\cvdefCpp{void sqrIntegral(const GpuMat\& src, GpuMat\& sqsum);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Only \texttt{CV\_8UC1} images are supported for now.}
|
||||
\cvarg{sqsum}{Squared integral image. Will contain 64-bit unsigned integer values packed into \texttt{CV\_64FC1}.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::columnSum}
|
||||
Computes vertical (column) sum.
|
||||
|
||||
\cvdefCpp{void columnSum(const GpuMat\& src, GpuMat\& sum);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Only \texttt{CV\_32FC1} images are supported for now.}
|
||||
\cvarg{sum}{Destination image. Will have \texttt{CV\_32FC1} type.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::cornerHarris}
|
||||
Computes Harris cornerness criteria at each image pixel.
|
||||
|
||||
\cvdefCpp{void cornerHarris(const GpuMat\& src, GpuMat\& dst,\par
|
||||
int blockSize, int ksize, double k,\par
|
||||
int borderType=BORDER\_REFLECT101);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Only \texttt{CV\_8UC1} and \texttt{CV\_32FC1} images are supported for now.}
|
||||
\cvarg{dst}{Destination image. Will have the same size and \texttt{CV\_32FC1} type and contain cornerness values.}
|
||||
\cvarg{blockSize}{Neighborhood size.}
|
||||
\cvarg{ksize}{Aperture parameter for the Sobel operator.}
|
||||
\cvarg{k}{Harris detector free parameter.}
|
||||
\cvarg{borderType}{Pixel extrapolation method. Only \texttt{BORDER\_REFLECT101} and \texttt{BORDER\_REPLICATE} are supported for now.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{cornerHarris}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::cornerMinEigenVal}
|
||||
Computes minimum eigen value of 2x2 derivative covariation matrix at each pixel - the cornerness criteria.
|
||||
|
||||
\cvdefCpp{void cornerMinEigenVal(const GpuMat\& src, GpuMat\& dst,\par
|
||||
int blockSize, int ksize,\par
|
||||
int borderType=BORDER\_REFLECT101);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Only \texttt{CV\_8UC1} and \texttt{CV\_32FC1} images are supported for now.}
|
||||
\cvarg{dst}{Destination image. Will have the same size and \texttt{CV\_32FC1} type and contain cornerness values.}
|
||||
\cvarg{blockSize}{Neighborhood size.}
|
||||
\cvarg{ksize}{Aperture parameter for the Sobel operator.}
|
||||
\cvarg{k}{Harris detector free parameter.}
|
||||
\cvarg{borderType}{Pixel extrapolation method. Only \texttt{BORDER\_REFLECT101} and \texttt{BORDER\_REPLICATE} are supported for now.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{cornerMinEigenValue}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::mulSpectrums}
|
||||
Performs per-element multiplication of two Fourier spectrums.
|
||||
|
||||
\cvdefCpp{void mulSpectrums(const GpuMat\& a, const GpuMat\& b,\par
|
||||
GpuMat\& c, int flags, bool conjB=false);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{a}{First spectrum.}
|
||||
\cvarg{b}{Second spectrum. Must have the same size and type as \texttt{a}.}
|
||||
\cvarg{c}{Destination spectrum.}
|
||||
\cvarg{flags}{Mock paramter is kept for CPU/GPU interfaces similarity.}
|
||||
\cvarg{conjB}{Optional flag which indicates the second spectrum must be conjugated before the multiplication.}
|
||||
\end{description}
|
||||
|
||||
Only full (i.e. not packed) \texttt{CV\_32FC2} complex spectrums in the interleaved format are supported for now.
|
||||
|
||||
See also: \cvCppCross{mulSpectrums}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::mulAndScaleSpectrums}
|
||||
Performs per-element multiplication of two Fourier spectrums and scales the result.
|
||||
|
||||
\cvdefCpp{void mulAndScaleSpectrums(const GpuMat\& a, const GpuMat\& b,\par
|
||||
GpuMat\& c, int flags, float scale, bool conjB=false);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{a}{First spectrum.}
|
||||
\cvarg{b}{Second spectrum. Must have the same size and type as \texttt{a}.}
|
||||
\cvarg{c}{Destination spectrum.}
|
||||
\cvarg{flags}{Mock paramter is kept for CPU/GPU interfaces similarity.}
|
||||
\cvarg{scale}{Scale constant.}
|
||||
\cvarg{conjB}{Optional flag which indicates the second spectrum must be conjugated before the multiplication.}
|
||||
\end{description}
|
||||
|
||||
Only full (i.e. not packed) \texttt{CV\_32FC2} complex spectrums in the interleaved format are supported for now.
|
||||
|
||||
See also: \cvCppCross{mulSpectrums}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::dft}
|
||||
Performs a forward or inverse discrete Fourier transform (1D or 2D) of floating point matrix. Can handle real matrices (\texttt{CV\_32FC1}) and complex matrices in the interleaved format (\texttt{CV\_32FC2}).
|
||||
|
||||
\cvdefCpp{void dft(const GpuMat\& src, GpuMat\& dst, Size dft\_size, int flags=0);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source matrix (real or complex).}
|
||||
\cvarg{dst}{Destination matrix (real or complex).}
|
||||
\cvarg{dft\_size}{Size of discrete Fourier transform.}
|
||||
\cvarg{flags}{Optional flags:
|
||||
\begin{description}
|
||||
\cvarg{DFT\_ROWS}{Transform each individual row of the source matrix.}
|
||||
\cvarg{DFT\_SCALE}{Scale the result: divide it by the number of elements in the transform (it's obtained from \texttt{dft\_size}).
|
||||
\cvarg{DFT\_INVERSE}{Inverse DFT must be perfromed for complex-complex case (real-complex and complex-real cases are respectively forward and inverse always).}}
|
||||
\cvarg{DFT\_REAL\_OUTPUT}{The source matrix is the result of real-complex transform, so the destination matrix must be real.}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
The source matrix should be continuous, otherwise reallocation and data copying will be performed. Function chooses the operation mode depending on the flags, size and channel count of the source matrix:
|
||||
\begin{itemize}
|
||||
\item If the source matrix is complex and the output isn't specified as real then the destination matrix will be complex, will have \texttt{dft\_size} size and \texttt{CV\_32FC2} type. It will contain full result of the DFT (forward or inverse).
|
||||
\item If the source matrix is complex and the output is specified as real then function assumes that its input is the result of the forward transform (see next item). The destionation matrix will have \texttt{dft\_size} size and \texttt{CV\_32FC1} type. It will contain result of the inverse DFT.
|
||||
\item If the source matrix is real (i.e. its type is \texttt{CV\_32FC1}) then forward DFT will be performed. The result of the DFT will be packed into complex (\texttt{CV\_32FC2}) matrix so its width will be \texttt{dft\_size.width / 2 + 1}, but if the source is a single column then height will be reduced instead of width.
|
||||
\end{itemize}
|
||||
|
||||
See also: \cvCppCross{dft}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::convolve}
|
||||
Computes convolution (or cross-correlation) of two images.
|
||||
|
||||
\cvdefCpp{void convolve(const GpuMat\& image, const GpuMat\& templ, GpuMat\& result,\par
|
||||
bool ccorr=false);\newline
|
||||
void convolve(const GpuMat\& image, const GpuMat\& templ, GpuMat\& result,\par
|
||||
bool ccorr, ConvolveBuf\& buf);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Source image. Only \texttt{CV\_32FC1} images are supported for now.}
|
||||
\cvarg{templ}{Template image. Must have size not greater then \texttt{image} size and be the same type as \texttt{image}.}
|
||||
\cvarg{result}{Result image. Will have the same size and type as \texttt{image}.}
|
||||
\cvarg{ccorr}{Flags which indicates cross-correlation must be evaluated instead of convolution.}
|
||||
\cvarg{buf}{Optional buffer to avoid extra memory allocations (for many calls with the same sizes).}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvclass{gpu::ConvolveBuf}
|
||||
Memory buffer for the \cvCppCross{gpu::convolve} function.
|
||||
|
||||
\begin{lstlisting}
|
||||
struct CV_EXPORTS ConvolveBuf
|
||||
{
|
||||
ConvolveBuf() {}
|
||||
ConvolveBuf(Size image_size, Size templ_size)
|
||||
{ create(image_size, templ_size); }
|
||||
void create(Size image_size, Size templ_size);
|
||||
|
||||
private:
|
||||
// Hidden
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::ConvolveBuf::ConvolveBuf}
|
||||
|
||||
\cvdefCpp{ConvolveBuf::ConvolveBuf();}
|
||||
Constructs an empty buffer which will be properly resized after first call of the convolve function.
|
||||
|
||||
\cvdefCpp{ConvolveBuf::ConvolveBuf(Size image\_size, Size templ\_size);}
|
||||
Constructs a buffer for the convolve function with respectively arguments.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::matchTemplate}
|
||||
Computes a proximity map for a raster template and an image where the template is searched for.
|
||||
|
||||
\cvdefCpp{void matchTemplate(const GpuMat\& image, const GpuMat\& templ,\par
|
||||
GpuMat\& result, int method);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Source image. \texttt{CV\_32F} and \texttt{CV\_8U} depth images (1..4 channels) are supported for now.}
|
||||
\cvarg{templ}{Template image. Must have the same size and type as \texttt{image}.}
|
||||
\cvarg{result}{Map containing comparison results (\texttt{CV\_32FC1}). If \texttt{image} is $W \times H$ and
|
||||
\texttt{templ} is $w \times h$ then \texttt{result} must be $(W-w+1) \times (H-h+1)$.}
|
||||
\cvarg{method}{Specifies the way which the template must be compared with the image.}
|
||||
\end{description}
|
||||
|
||||
Following methods are supported for the \texttt{CV\_8U} depth images for now:
|
||||
\begin{itemize}
|
||||
\item CV\_TM\_SQDIFF \item CV\_TM\_SQDIFF\_NORMED \item CV\_TM\_CCORR \item CV\_TM\_CCORR\_NORMED \item CV\_TM\_CCOEFF \item CV\_TM\_CCOEFF\_NORMED
|
||||
\end{itemize}
|
||||
Following methods are supported for the \texttt{CV\_32F} images for now:
|
||||
\begin{itemize}
|
||||
\item CV\_TM\_SQDIFF \item CV\_TM\_CCORR
|
||||
\end{itemize}
|
||||
|
||||
See also: \cvCppCross{matchTemplate}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::remap}
|
||||
Applies a generic geometrical transformation to an image.
|
||||
|
||||
\cvdefCpp{
|
||||
void remap(const GpuMat\& src, GpuMat\& dst, \par const GpuMat\& xmap, const GpuMat\& ymap);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Only \texttt{CV\_8UC1} and \texttt{CV\_8UC3} source types are supported.}
|
||||
\cvarg{dst}{Destination image. It will have the same size as \texttt{xmap} and the same type as \texttt{src}.}
|
||||
\cvarg{xmap}{X values. Only \texttt{CV\_32FC1} type is supported.}
|
||||
\cvarg{ymap}{Y values. Only \texttt{CV\_32FC1} type is supported.}
|
||||
\end{description}
|
||||
|
||||
The function transforms the source image using the specified map:
|
||||
\[
|
||||
\texttt{dst}(x,y) = \texttt{src}(xmap(x,y), ymap(x,y))
|
||||
\]
|
||||
|
||||
Values of pixels with non-integer coordinates are computed using bilinear interpolation.
|
||||
|
||||
See also: \cvCppCross{remap}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::cvtColor}
|
||||
Converts image from one color space to another.
|
||||
|
||||
\cvdefCpp{
|
||||
void cvtColor(const GpuMat\& src, GpuMat\& dst, int code, int dcn = 0);\newline
|
||||
void cvtColor(const GpuMat\& src, GpuMat\& dst, int code, int dcn, \par const Stream\& stream);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image with \texttt{CV\_8U}, \texttt{CV\_16U} or \texttt{CV\_32F} depth and 1, 3 or 4 channels.}
|
||||
\cvarg{dst}{Destination image; will have the same size and the same depth as \texttt{src}.}
|
||||
\cvarg{code}{Color space conversion code. For details see \cvCppCross{cvtColor}. Conversion to/from Luv and Bayer color spaces doesn't supported.}
|
||||
\cvarg{dcn}{Number of channels in the destination image; if the parameter is 0, the number of the channels will be derived automatically from \texttt{src} and the \texttt{code}.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
3-channel color spaces (like \texttt{HSV}, \texttt{XYZ}, etc) can be stored to 4-channel image for better perfomance.
|
||||
|
||||
See also: \cvCppCross{cvtColor}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::threshold}
|
||||
Applies a fixed-level threshold to each array element.
|
||||
|
||||
\cvdefCpp{
|
||||
double threshold(const GpuMat\& src, GpuMat\& dst, double thresh, \par double maxval, int type);\newline
|
||||
double threshold(const GpuMat\& src, GpuMat\& dst, double thresh, \par double maxval, int type, const Stream\& stream);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source array (single-channel).}
|
||||
\cvarg{dst}{Destination array; will have the same size and the same type as \texttt{src}.}
|
||||
\cvarg{thresh}{Threshold value.}
|
||||
\cvarg{maxVal}{Maximum value to use with \texttt{THRESH\_BINARY} and \texttt{THRESH\_BINARY\_INV} thresholding types.}
|
||||
\cvarg{thresholdType}{Thresholding type. For details see \cvCppCross{threshold}. \texttt{THRESH\_OTSU} thresholding type doesn't supported.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{threshold}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::resize}
|
||||
Resizes an image.
|
||||
|
||||
\cvdefCpp{
|
||||
void resize(const GpuMat\& src, GpuMat\& dst, Size dsize, \par double fx=0, double fy=0, \par int interpolation = INTER\_LINEAR);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8UC1} and \texttt{CV\_8UC4} types.}
|
||||
\cvarg{dst}{Destination image. It will have size \texttt{dsize} (when it is non-zero) or the size computed from \texttt{src.size()} and \texttt{fx} and \texttt{fy}. The type of \texttt{dst} will be the same as of \texttt{src}.}
|
||||
\cvarg{dsize}{Destination image size. If it is zero, then it is computed as:
|
||||
\[
|
||||
\texttt{dsize = Size(round(fx*src.cols), round(fy*src.rows))}
|
||||
\]
|
||||
Either \texttt{dsize} or both \texttt{fx} or \texttt{fy} must be non-zero.}
|
||||
\cvarg{fx}{Scale factor along the horizontal axis. When 0, it is computed as
|
||||
\[
|
||||
\texttt{(double)dsize.width/src.cols}
|
||||
\]}
|
||||
\cvarg{fy}{Scale factor along the vertical axis. When 0, it is computed as
|
||||
\[
|
||||
\texttt{(double)dsize.height/src.rows}
|
||||
\]}
|
||||
\cvarg{interpolation}{Interpolation method. Supports only \texttt{INTER\_NEAREST} and \texttt{INTER\_LINEAR}.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{resize}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::warpAffine}
|
||||
Applies an affine transformation to an image.
|
||||
|
||||
\cvdefCpp{
|
||||
void warpAffine(const GpuMat\& src, GpuMat\& dst, const Mat\& M, \par Size dsize, int flags = INTER\_LINEAR);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8U}, \texttt{CV\_16U}, \texttt{CV\_32S} or \texttt{CV\_32F} depth and 1, 3 or 4 channels.}
|
||||
\cvarg{dst}{Destination image; will have size \texttt{dsize} and the same type as \texttt{src}.}
|
||||
\cvarg{M}{$2\times 3$ transformation matrix.}
|
||||
\cvarg{dsize}{Size of the destination image.}
|
||||
\cvarg{flags}{Combination of interpolation methods, see \cvCppCross{resize}, and the optional flag \texttt{WARP\_INVERSE\_MAP} that means that \texttt{M} is the inverse transformation ($\texttt{dst}\rightarrow\texttt{src}$). Supports only \texttt{INTER\_NEAREST}, \texttt{INTER\_LINEAR} and \texttt{INTER\_CUBIC} interpolation methods.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{warpAffine}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::warpPerspective}
|
||||
Applies a perspective transformation to an image.
|
||||
|
||||
\cvdefCpp{
|
||||
void warpPerspective(const GpuMat\& src, GpuMat\& dst, const Mat\& M, \par Size dsize, int flags = INTER\_LINEAR);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8U}, \texttt{CV\_16U}, \texttt{CV\_32S} or \texttt{CV\_32F} depth and 1, 3 or 4 channels.}
|
||||
\cvarg{dst}{Destination image; will have size \texttt{dsize} and the same type as \texttt{src}.}
|
||||
\cvarg{M}{$2
|
||||
3$ transformation matrix.}
|
||||
\cvarg{dsize}{Size of the destination image.}
|
||||
\cvarg{flags}{Combination of interpolation methods, see \cvCppCross{resize}, and the optional flag \texttt{WARP\_INVERSE\_MAP} that means that \texttt{M} is the inverse transformation ($\texttt{dst}\rightarrow\texttt{src}$). Supports only \texttt{INTER\_NEAREST}, \texttt{INTER\_LINEAR} and \texttt{INTER\_CUBIC} interpolation methods.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{warpPerspective}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::rotate}
|
||||
Rotates an image around the origin (0,0) and then shifts it.
|
||||
|
||||
\cvdefCpp{
|
||||
void rotate(const GpuMat\& src, GpuMat\& dst, Size dsize, \par double angle, double xShift = 0, double yShift = 0, \par int interpolation = INTER\_LINEAR);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8UC1} and \texttt{CV\_8UC4} types.}
|
||||
\cvarg{dst}{Destination image; will have size \texttt{dsize} and the same type as \texttt{src}.}
|
||||
\cvarg{dsize}{Size of the destination image.}
|
||||
\cvarg{angle}{Angle of rotation in degrees.}
|
||||
\cvarg{xShift}{Shift along horizontal axis.}
|
||||
\cvarg{yShift}{Shift along vertical axis.}
|
||||
\cvarg{interpolation}{Interpolation method. Supports only \texttt{INTER\_NEAREST}, \texttt{INTER\_LINEAR} and \texttt{INTER\_CUBIC}.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{gpu::warpAffine}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::copyMakeBorder}
|
||||
Copies 2D array to a larger destination array and pads borders with the given constant.
|
||||
|
||||
\cvdefCpp{
|
||||
void copyMakeBorder(const GpuMat\& src, GpuMat\& dst, \par int top, int bottom, int left, int right, \par const Scalar\& value = Scalar());
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_32SC1} and \texttt{CV\_32FC1} types.}
|
||||
\cvarg{dst}{The destination image; will have the same type as \texttt{src} and the size \texttt{Size(src.cols+left+right, src.rows+top+bottom)}.}
|
||||
\cvarg{top, bottom, left, right}{Specify how much pixels in each direction from the source image rectangle one needs to extrapolate, e.g. \texttt{top=1, bottom=1, left=1, right=1} mean that 1 pixel-wide border needs to be built.}
|
||||
\cvarg{value}{Border value.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{copyMakeBorder}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::rectStdDev}
|
||||
Computes standard deviation of integral images.
|
||||
|
||||
\cvdefCpp{
|
||||
void rectStdDev(const GpuMat\& src, const GpuMat\& sqr, GpuMat\& dst, \par const Rect\& rect);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports only \texttt{CV\_32SC1} type.}
|
||||
\cvarg{sqr}{Squared source image. Supports only \texttt{CV\_32FC1} type.}
|
||||
\cvarg{dst}{Destination image; will have the same type and the same size as \texttt{src}.}
|
||||
\cvarg{rect}{Rectangular window.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::evenLevels}
|
||||
Computes levels with even distribution.
|
||||
|
||||
\cvdefCpp{
|
||||
void evenLevels(GpuMat\& levels, int nLevels, \par int lowerLevel, int upperLevel);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{levels}{Destination array. \texttt{levels} will have 1 row and \texttt{nLevels} cols and \texttt{CV\_32SC1} type.}
|
||||
\cvarg{nLevels}{Number of levels being computed. \texttt{nLevels} must be at least 2.}
|
||||
\cvarg{lowerLevel}{Lower boundary value of the lowest level.}
|
||||
\cvarg{upperLevel}{Upper boundary value of the greatest level.}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{gpu::histEven}
|
||||
Calculates histogram with evenly distributed bins.
|
||||
|
||||
\cvdefCpp{
|
||||
void histEven(const GpuMat\& src, GpuMat\& hist, \par int histSize, int lowerLevel, int upperLevel);\newline
|
||||
void histEven(const GpuMat\& src, GpuMat hist[4], \par int histSize[4], int lowerLevel[4], int upperLevel[4]);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8U}, \texttt{CV\_16U} or \texttt{CV\_16S} depth and 1 or 4 channels. For four-channel image all channels are processed separately.}
|
||||
\cvarg{hist}{Destination histogram. Will have one row, \texttt{histSize} cols and \texttt{CV\_32S} type.}
|
||||
\cvarg{histSize}{Size of histogram.}
|
||||
\cvarg{lowerLevel}{Lower boundary of lowest level bin.}
|
||||
\cvarg{upperLevel}{Upper boundary of highest level bin.}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{gpu::histRange}
|
||||
Calculates histogram with bins determined by levels array.
|
||||
|
||||
\cvdefCpp{
|
||||
void histRange(const GpuMat\& src, GpuMat\& hist, const GpuMat\& levels);\newline
|
||||
void histRange(const GpuMat\& src, GpuMat hist[4], \par const GpuMat levels[4]);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image. Supports \texttt{CV\_8U}, \texttt{CV\_16U} or \texttt{CV\_16S} depth and 1 or 4 channels. For four-channel image all channels are processed separately.}
|
||||
\cvarg{hist}{Destination histogram. Will have one row, \texttt{(levels.cols-1)} cols and \texttt{CV\_32SC1} type.}
|
||||
\cvarg{levels}{Number of levels in histogram.}
|
||||
\end{description}
|
@ -1,206 +0,0 @@
|
||||
\section{Initalization and Information}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::getCudaEnabledDeviceCount}
|
||||
Returns number of CUDA-enabled devices installed. It is to be used before any other GPU functions calls. If OpenCV is compiled without GPU support this function returns 0.
|
||||
|
||||
\cvdefCpp{int getCudaEnabledDeviceCount();}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::setDevice}
|
||||
Sets device and initializes it for the current thread. Call of this function can be omitted, but in this case a default device will be initialized on fist GPU usage.
|
||||
|
||||
\cvdefCpp{void setDevice(int device);}
|
||||
\begin{description}
|
||||
\cvarg{device}{index of GPU device in system starting with 0.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::getDevice}
|
||||
Returns the current device index, which was set by {gpu::getDevice} or initialized by default.
|
||||
|
||||
\cvdefCpp{int getDevice();}
|
||||
|
||||
|
||||
\cvclass{gpu::FeatureSet}\label{cpp.gpu.FeatureSet}
|
||||
GPU compute features.
|
||||
|
||||
\begin{lstlisting}
|
||||
enum FeatureSet
|
||||
{
|
||||
FEATURE_SET_COMPUTE_10, FEATURE_SET_COMPUTE_11,
|
||||
FEATURE_SET_COMPUTE_12, FEATURE_SET_COMPUTE_13,
|
||||
FEATURE_SET_COMPUTE_20, FEATURE_SET_COMPUTE_21,
|
||||
GLOBAL_ATOMICS, NATIVE_DOUBLE
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvclass{gpu::DeviceInfo}
|
||||
This class provides functionality for querying the specified GPU properties.
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS DeviceInfo
|
||||
{
|
||||
public:
|
||||
DeviceInfo();
|
||||
DeviceInfo(int device_id);
|
||||
|
||||
string name() const;
|
||||
|
||||
int majorVersion() const;
|
||||
int minorVersion() const;
|
||||
|
||||
int multiProcessorCount() const;
|
||||
|
||||
size_t freeMemory() const;
|
||||
size_t totalMemory() const;
|
||||
|
||||
bool supports(FeatureSet feature_set) const;
|
||||
bool isCompatible() const;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::DeviceInfo::DeviceInfo}
|
||||
Constructs DeviceInfo object for the specified device. If \texttt{device\_id} parameter is missed it constructs object for the current device.
|
||||
|
||||
\cvdefCpp{DeviceInfo::DeviceInfo();\newline
|
||||
DeviceInfo::DeviceInfo(int device\_id);}
|
||||
\begin{description}
|
||||
\cvarg{device\_id}{Index of the GPU device in system starting with 0.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::DeviceInfo::name}
|
||||
Returns the device name.
|
||||
|
||||
\cvdefCpp{string DeviceInfo::name();}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::DeviceInfo::majorVersion}
|
||||
Returns the major compute capability version.
|
||||
|
||||
\cvdefCpp{int DeviceInfo::majorVersion();}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::DeviceInfo::minorVersion}
|
||||
Returns the minor compute capability version.
|
||||
|
||||
\cvdefCpp{int DeviceInfo::minorVersion();}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::DeviceInfo::multiProcessorCount}
|
||||
Returns the number of streaming multiprocessors.
|
||||
|
||||
\cvdefCpp{int DeviceInfo::multiProcessorCount();}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::DeviceInfo::freeMemory}
|
||||
Returns the amount of free memory in bytes.
|
||||
|
||||
\cvdefCpp{size\_t DeviceInfo::freeMemory();}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::DeviceInfo::totalMemory}
|
||||
Returns the amount of total memory in bytes.
|
||||
|
||||
\cvdefCpp{size\_t DeviceInfo::totalMemory();}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::DeviceInfo::supports}
|
||||
Returns true if the device has the given GPU feature, otherwise false.
|
||||
|
||||
\cvdefCpp{bool DeviceInfo::supports(FeatureSet feature\_set);}
|
||||
\begin{description}
|
||||
\cvarg{feature}{Feature to be checked. See \hyperref[cpp.gpu.FeatureSet]{cv::gpu::FeatureSet}.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::DeviceInfo::isCompatible}
|
||||
Returns true if the GPU module can be run on the specified device, otherwise false.
|
||||
|
||||
\cvdefCpp{bool DeviceInfo::isCompatible();}
|
||||
|
||||
|
||||
\cvclass{gpu::TargetArchs}
|
||||
This class provides functionality (as set of static methods) for checking which NVIDIA card architectures the GPU module was built for.
|
||||
|
||||
\bigskip
|
||||
|
||||
The following method checks whether the module was built with the support of the given feature:
|
||||
\cvdefCpp{static bool builtWith(FeatureSet feature\_set);}
|
||||
\begin{description}
|
||||
\cvarg{feature}{Feature to be checked. See \hyperref[cpp.gpu.FeatureSet]{cv::gpu::FeatureSet}.}
|
||||
\end{description}
|
||||
|
||||
There are a set of methods for checking whether the module contains intermediate (PTX) or binary GPU code for the given architecture(s):
|
||||
\cvdefCpp{
|
||||
static bool has(int major, int minor);\newline
|
||||
static bool hasPtx(int major, int minor);\newline
|
||||
static bool hasBin(int major, int minor);\newline
|
||||
static bool hasEqualOrLessPtx(int major, int minor);\newline
|
||||
static bool hasEqualOrGreater(int major, int minor);\newline
|
||||
static bool hasEqualOrGreaterPtx(int major, int minor);\newline
|
||||
static bool hasEqualOrGreaterBin(int major, int minor);}
|
||||
\begin{description}
|
||||
\cvarg{major}{Major compute capability version.}
|
||||
\cvarg{minor}{Minor compute capability version.}
|
||||
\end{description}
|
||||
|
||||
% By default GPU module is no compiled for devices with compute capability equal to 1.0. So if you run
|
||||
|
||||
According to the CUDA C Programming Guide Version 3.2: "PTX code produced for some specific compute capability can always be compiled to binary code of greater or equal compute capability".
|
||||
|
||||
|
||||
\cvclass{gpu::MultiGpuManager}
|
||||
Provides functionality for working with many GPUs.
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS MultiGpuManager
|
||||
{
|
||||
public:
|
||||
MultiGpuManager();
|
||||
~MultiGpuManager();
|
||||
|
||||
// Must be called before any other GPU calls
|
||||
void init();
|
||||
|
||||
// Makes the given GPU active
|
||||
void gpuOn(int gpu_id);
|
||||
|
||||
// Finishes the piece of work on the current GPU
|
||||
void gpuOff();
|
||||
|
||||
static const int BAD_GPU_ID;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::MultiGpuManager::MultiGpuManager}
|
||||
Creates multi GPU manager, but doesn't initialize it.
|
||||
\cvdefCpp{MultiGpuManager::MultiGpuManager}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::MultiGpuManager::\~{}MultiGpuManager}
|
||||
Releases multi GPU manager.
|
||||
\cvdefCpp{MultuGpuManager::\~{}multiGpuManager}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::MultiGpuManager::init}
|
||||
Initializes multi GPU manager.
|
||||
\cvdefCpp{void MultiGpuManager::init();}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::MultiGpuManager:gpuOn}
|
||||
Makes the given GPU active.
|
||||
\cvdefCpp{void MultiGpuManager::gpuOn(int gpu\_id);}
|
||||
\begin{description}
|
||||
\cvarg{gpu\_id}{Index of the GPU device in system starting with 0.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::MultiGpuManager::gpuOff}
|
||||
Finishes the piece of work on the current GPU.
|
||||
\cvdefCpp{void MultiGpuManager::gpuOff();}
|
||||
|
@ -1,59 +0,0 @@
|
||||
\section{GPU module introduction}
|
||||
|
||||
\subsection{General information}
|
||||
|
||||
The OpenCV GPU module is a set of classes and functions to utilize GPU computational capabilities. It is implemented using NVidia CUDA Runtime API, so only the NVidia GPUs are supported. It includes utility functions, low-level vision primitives as well as high-level algorithms. The utility functions and low-level primitives provide a powerful infrastructure for developing fast vision algorithms taking advantage of GPU. Whereas the high-level functionality includes some state-of-the-art algorithms (such as stereo correspondence, face and people detectors etc.), ready to be used by the application developers.
|
||||
|
||||
The GPU module is designed as host-level API, i.e. if a user has pre-compiled OpenCV GPU binaries, it is not necessary to have Cuda Toolkit installed or write any extra code to make use of the GPU.
|
||||
|
||||
The GPU module depends on the Cuda Toolkit and NVidia Performance Primitives library (NPP). Make sure you have the latest versions of those. The two libraries can be downloaded from NVidia site for all supported platforms. To compile OpenCV GPU module you will need a compiler compatible with Cuda Runtime Toolkit.
|
||||
|
||||
OpenCV GPU module is designed for ease of use and does not require any knowledge of Cuda. Though, such a knowledge will certainly be useful in non-trivial cases, or when you want to get the highest performance. It is helpful to have understanding of the costs of various operations, what the GPU does, what are the preferred data formats etc. The GPU module is an effective instrument for quick implementation of GPU-accelerated computer vision algorithms. However, if you algorithm involves many simple operations, then for the best possible performance you may still need to write your own kernels, to avoid extra write and read operations on the intermediate results.
|
||||
|
||||
To enable CUDA support, configure OpenCV using CMake with \texttt{WITH\_CUDA=ON}. When the flag is set and if CUDA is installed, the full-featured OpenCV GPU module will be built. Otherwise, the module will still be built, but at runtime all functions from the module will throw \cvCppCross{Exception} with \texttt{CV\_GpuNotSupported} error code, except for \cvCppCross{gpu::getCudaEnabledDeviceCount()}. The latter function will return zero GPU count in this case. Building OpenCV without CUDA support does not perform device code compilation, so it does not require Cuda Toolkit installed. Therefore, using \cvCppCross{gpu::getCudaEnabledDeviceCount()} function it is possible to implement a high-level algorithm that will detect GPU presence at runtime and choose the appropriate implementation (CPU or GPU) accordingly.
|
||||
|
||||
\subsection{Compilation for different NVidia platforms.}
|
||||
|
||||
NVidia compiler allows generating binary code (cubin and fatbin) and intermediate code (PTX). Binary code often implies a specific GPU architecture and generation, so the compatibility with other GPUs is not guaranteed. PTX is targeted for a virtual platform, which is defined entirely by the set of capabilities, or features. Depending on the virtual platform chosen, some of the instructions will be emulated or disabled, even if the real hardware supports all the features.
|
||||
|
||||
On first call, the PTX code is compiled to binary code for the particular GPU using JIT compiler. When the target GPU has lower "compute capability" (CC) than the PTX code, JIT fails.
|
||||
|
||||
By default, the OpenCV GPU module includes:
|
||||
\begin{itemize}
|
||||
\item Binaries for compute capabilities 1.3 and 2.0 (controlled by \texttt{CUDA\_ARCH\_BIN} in CMake)
|
||||
\item PTX code for compute capabilities 1.1 and 1.3 (controlled by \texttt{CUDA\_ARCH\_PTX} in CMake)
|
||||
\end{itemize}
|
||||
|
||||
That means for devices with CC 1.3 and 2.0 binary images are ready to run. For all newer platforms the PTX code for 1.3 is JIT'ed to a binary image. For devices with 1.1 and 1.2 the PTX for 1.1 is JIT'ed. For devices with CC 1.0 no code is available and the functions will throw \cvCppCross{Exception}. For platforms where JIT compilation is performed first run will be slow.
|
||||
|
||||
If you happen to have GPU with CC 1.0, the GPU module can still be compiled on it and most of the functions will run just fine on such card. Simply add "1.0" to the list of binaries, for example, \texttt{CUDA\_ARCH\_BIN="1.0 1.3 2.0"}. The functions that can not be run on CC 1.0 GPUs will throw an exception.
|
||||
|
||||
You can always determine at runtime whether OpenCV GPU built binaries (or PTX code) are compatible with your GPU. The function \cvCppCross{gpu::DeviceInfo::isCompatible} return the compatibility status (true/false).
|
||||
|
||||
|
||||
\subsection{Threading and multi-threading.}
|
||||
|
||||
OpenCV GPU module follows Cuda Runtime API conventions regarding the multi-threaded programming. That is, on first the API call a Cuda context is created implicitly, attached to the current CPU thread and then is used as the thread's "current" context. All further operations, such as memory allocation, GPU code compilation, will be associated with the context and the thread. Because any other thread is not attached to the context, memory (and other resources) allocated in the first thread can not be accessed by the other thread. Instead, for this other thread Cuda will create another context associated with it. In short, by default different threads do not share resources.
|
||||
|
||||
But such limitation can be removed using Cuda Driver API (version 3.1 or later). User can retrieve context reference for one thread, attach it to another thread and make it "current" for that thread. Then the threads can share memory and other resources. It is also possible to create a context explicitly before calling any GPU code and attach it to all the threads that you want to share the resources.
|
||||
|
||||
Also it is possible to create context explicitly using Cuda Driver API, attach and make "current" for all necessary threads. Cuda Runtime API (and OpenCV functions respectively) will pick up it.
|
||||
|
||||
\subsection{Multi-GPU}
|
||||
|
||||
In the current version each of the OpenCV GPU algorithms can use only a single GPU. So, to utilize multiple GPUs, user has to manually distribute the work between the GPUs. Here are the two ways of utilizing multiple GPUs:
|
||||
\begin{itemize}
|
||||
\item If you only use synchronous functions, first, create several CPU threads (one per each GPU) and from within each thread create CUDA context for the corresponding GPU using \cvCppCross{gpu::setDevice()} or Driver API. That's it. Now each of the threads will use the associated GPU.
|
||||
\item In case of asynchronous functions, it is possible to create several Cuda contexts associated with different GPUs but attached to one CPU thread. This can be done only by Driver API. Within the thread you can switch from one GPU to another by making the corresponding context "current". With non-blocking GPU calls managing algorithm is clear.
|
||||
\end{itemize}
|
||||
While developing algorithms for multiple GPUs a data passing overhead have to be taken into consideration. For primitive functions and for small images it can be significant and eliminate all the advantages of having multiple GPUs. But for high level algorithms Multi-GPU acceleration may be suitable. For example, Stereo Block Matching algorithm has been successfully parallelized using the following algorithm:
|
||||
\begin{itemize}
|
||||
\item
|
||||
Each image of the stereo pair is split into two horizontal overlapping stripes.
|
||||
\item
|
||||
Each pair of stripes (from the left and the right images) has been processed on a separate Fermi GPU
|
||||
\item
|
||||
The results are merged into the single disparity map.
|
||||
\end{itemize}
|
||||
With this scheme dual GPU gave 180\% performance increase comparing to the single Fermi GPU. The source code of the example is available at
|
||||
\url{https://code.ros.org/svn/opencv/trunk/opencv/examples/gpu/}
|
@ -1,192 +0,0 @@
|
||||
\section{Operations on Matrices}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::transpose}
|
||||
Transposes a matrix.
|
||||
|
||||
\cvdefCpp{void transpose(const GpuMat\& src, GpuMat\& dst);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source matrix. 1, 4, 8 bytes element sizes are supported for now.}
|
||||
\cvarg{dst}{Destination matrix.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{transpose}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::flip}
|
||||
Flips a 2D matrix around vertical, horizontal or both axes.
|
||||
|
||||
\cvdefCpp{void flip(const GpuMat\& a, GpuMat\& b, int flipCode);}
|
||||
\begin{description}
|
||||
\cvarg{a}{Source matrix. Only \texttt{CV\_8UC1} and \texttt{CV\_8UC4} matrices are supported for now.}
|
||||
\cvarg{b}{Destination matrix.}
|
||||
\cvarg{flipCode}{Specifies how to flip the source:
|
||||
\begin{description}
|
||||
\cvarg{0}{Flip around x-axis.}
|
||||
\cvarg{$>$0}{Flip around y-axis.}
|
||||
\cvarg{$<$0}{Flip around both axes.}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{flip}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::LUT}
|
||||
Transforms the source matrix into the destination matrix using given look-up table:
|
||||
\[dst(I) = lut(src(I))\]
|
||||
|
||||
\cvdefCpp{void LUT(const GpuMat\& src, const Mat\& lut, GpuMat\& dst);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source matrix. \texttt{CV\_8UC1} and \texttt{CV\_8UC3} matrixes are supported for now.}
|
||||
\cvarg{lut}{Look-up table. Must be continuous, \texttt{CV\_8U} depth matrix. Its area must satisfy to \texttt{lut.rows} $\times$ \texttt{lut.cols} = 256 condition.}
|
||||
\cvarg{dst}{Destination matrix. Will have the same depth as \texttt{lut} and the same number of channels as \texttt{src}.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{LUT}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::merge}
|
||||
Makes a multi-channel matrix out of several single-channel matrices.
|
||||
|
||||
\cvdefCpp{void merge(const GpuMat* src, size\_t n, GpuMat\& dst);\newline
|
||||
void merge(const GpuMat* src, size\_t n, GpuMat\& dst,\par
|
||||
const Stream\& stream);\newline}
|
||||
\begin{description}
|
||||
\cvarg{src}{Pointer to array of the source matrices.}
|
||||
\cvarg{n}{Number of source matrices.}
|
||||
\cvarg{dst}{Destination matrix.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{void merge(const vector$<$GpuMat$>$\& src, GpuMat\& dst);\newline
|
||||
void merge(const vector$<$GpuMat$>$\& src, GpuMat\& dst,\par
|
||||
const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Vector of the source matrices.}
|
||||
\cvarg{dst}{Destination matrix.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{merge}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::split}
|
||||
Copies each plane of a multi-channel matrix into an array.
|
||||
|
||||
\cvdefCpp{void split(const GpuMat\& src, GpuMat* dst);\newline
|
||||
void split(const GpuMat\& src, GpuMat* dst, const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source matrix.}
|
||||
\cvarg{dst}{Pointer to array of single-channel matrices.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{void split(const GpuMat\& src, vector$<$GpuMat$>$\& dst);\newline
|
||||
void split(const GpuMat\& src, vector$<$GpuMat$>$\& dst,\par
|
||||
const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source matrix.}
|
||||
\cvarg{dst}{Destination vector of single-channel matrices.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{split}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::magnitude}
|
||||
Computes magnitudes of complex matrix elements.
|
||||
|
||||
\cvdefCpp{void magnitude(const GpuMat\& x, GpuMat\& magnitude);}
|
||||
\begin{description}
|
||||
\cvarg{x}{Source complex matrix in the interleaved format (\texttt{CV\_32FC2}). }
|
||||
\cvarg{magnitude}{Destination matrix of float magnitudes (\texttt{CV\_32FC1}).}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{void magnitude(const GpuMat\& x, const GpuMat\& y, GpuMat\& magnitude);\newline
|
||||
void magnitude(const GpuMat\& x, const GpuMat\& y, GpuMat\& magnitude,\par
|
||||
const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{x}{Source matrix, containing real components (\texttt{CV\_32FC1}).}
|
||||
\cvarg{y}{Source matrix, containing imaginary components (\texttt{CV\_32FC1}).}
|
||||
\cvarg{magnitude}{Destination matrix of float magnitudes (\texttt{CV\_32FC1}).}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{magnitude}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::magnitudeSqr}
|
||||
Computes squared magnitudes of complex matrix elements.
|
||||
|
||||
\cvdefCpp{void magnitudeSqr(const GpuMat\& x, GpuMat\& magnitude);}
|
||||
\begin{description}
|
||||
\cvarg{x}{Source complex matrix in the interleaved format (\texttt{CV\_32FC2}). }
|
||||
\cvarg{magnitude}{Destination matrix of float magnitude squares (\texttt{CV\_32FC1}).}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{void magnitudeSqr(const GpuMat\& x, const GpuMat\& y, GpuMat\& magnitude);\newline
|
||||
void magnitudeSqr(const GpuMat\& x, const GpuMat\& y, GpuMat\& magnitude,\par
|
||||
const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{x}{Source matrix, containing real components (\texttt{CV\_32FC1}).}
|
||||
\cvarg{y}{Source matrix, containing imaginary components (\texttt{CV\_32FC1}).}
|
||||
\cvarg{magnitude}{Destination matrix of float magnitude squares (\texttt{CV\_32FC1}).}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::phase}
|
||||
Computes polar angles of complex matrix elements.
|
||||
|
||||
\cvdefCpp{void phase(const GpuMat\& x, const GpuMat\& y, GpuMat\& angle,\par
|
||||
bool angleInDegrees=false);\newline
|
||||
void phase(const GpuMat\& x, const GpuMat\& y, GpuMat\& angle,\par
|
||||
bool angleInDegrees, const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{x}{Source matrix, containing real components (\texttt{CV\_32FC1}).}
|
||||
\cvarg{y}{Source matrix, containing imaginary components (\texttt{CV\_32FC1}).}
|
||||
\cvarg{angle}{Destionation matrix of angles (\texttt{CV\_32FC1}).}
|
||||
\cvarg{angleInDegress}{Flag which indicates angles must be evaluated in degress.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{phase}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::cartToPolar}
|
||||
Converts Cartesian coordinates into polar.
|
||||
|
||||
\cvdefCpp{void cartToPolar(const GpuMat\& x, const GpuMat\& y, GpuMat\& magnitude,\par
|
||||
GpuMat\& angle, bool angleInDegrees=false);\newline
|
||||
void cartToPolar(const GpuMat\& x, const GpuMat\& y, GpuMat\& magnitude,\par
|
||||
GpuMat\& angle, bool angleInDegrees, const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{x}{Source matrix, containing real components (\texttt{CV\_32FC1}).}
|
||||
\cvarg{y}{Source matrix, containing imaginary components (\texttt{CV\_32FC1}).}
|
||||
\cvarg{magnitude}{Destination matrix of float magnituds (\texttt{CV\_32FC1}).}
|
||||
\cvarg{angle}{Destionation matrix of angles (\texttt{CV\_32FC1}).}
|
||||
\cvarg{angleInDegress}{Flag which indicates angles must be evaluated in degress.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{cartToPolar}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::polarToCart}
|
||||
Converts polar coordinates into Cartesian.
|
||||
|
||||
\cvdefCpp{void polarToCart(const GpuMat\& magnitude, const GpuMat\& angle,\par
|
||||
GpuMat\& x, GpuMat\& y, bool angleInDegrees=false);\newline
|
||||
void polarToCart(const GpuMat\& magnitude, const GpuMat\& angle,\par
|
||||
GpuMat\& x, GpuMat\& y, bool angleInDegrees,\par
|
||||
const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{magnitude}{Source matrix, containing magnitudes (\texttt{CV\_32FC1}).}
|
||||
\cvarg{angle}{Source matrix, containing angles (\texttt{CV\_32FC1}).}
|
||||
\cvarg{x}{Destination matrix of real components (\texttt{CV\_32FC1}).}
|
||||
\cvarg{y}{Destination matrix of imaginary components (\texttt{CV\_32FC1}).}
|
||||
\cvarg{angleInDegress}{Flag which indicates angles are in degress.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{polarToCart}.
|
@ -1,135 +0,0 @@
|
||||
\section{Matrix Reductions}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::meanStdDev}
|
||||
Computes mean value and standard deviation of matrix elements.
|
||||
|
||||
\cvdefCpp{void meanStdDev(const GpuMat\& mtx, Scalar\& mean, Scalar\& stddev);}
|
||||
\begin{description}
|
||||
\cvarg{mtx}{Source matrix. \texttt{CV\_8UC1} matrices are supported for now.}
|
||||
\cvarg{mean}{Mean value.}
|
||||
\cvarg{stddev}{Standard deviation value.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{meanStdDev}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::norm}
|
||||
Returns norm of matrix (or of two matrices difference).
|
||||
|
||||
\cvdefCpp{double norm(const GpuMat\& src, int normType=NORM\_L2);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source matrix. Any matrices except 64F are supported.}
|
||||
\cvarg{normType}{Norm type. \texttt{NORM\_L1}, \texttt{NORM\_L2} and \texttt{NORM\_INF} are supported for now.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{double norm(const GpuMat\& src, int normType, GpuMat\& buf);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source matrix. Any matrices except 64F are supported.}
|
||||
\cvarg{normType}{Norm type. \texttt{NORM\_L1}, \texttt{NORM\_L2} and \texttt{NORM\_INF} are supported for now.}
|
||||
\cvarg{buf}{Optional buffer to avoid extra memory allocations. It's resized automatically.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{double norm(const GpuMat\& src1, const GpuMat\& src2,\par
|
||||
int normType=NORM\_L2);}
|
||||
\begin{description}
|
||||
\cvarg{src1}{First source matrix. \texttt{CV\_8UC1} matrices are supported for now.}
|
||||
\cvarg{src2}{Second source matrix. Must have the same size and type as \texttt{src1}}.
|
||||
\cvarg{normType}{Norm type. \texttt{NORM\_L1}, \texttt{NORM\_L2} and \texttt{NORM\_INF} are supported for now.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{norm}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::sum}
|
||||
Returns sum of matrix elements.
|
||||
|
||||
\cvdefCpp{Scalar sum(const GpuMat\& src);\newline
|
||||
Scalar sum(const GpuMat\& src, GpuMat\& buf);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image of any depth except \texttt{CV\_64F}.}
|
||||
\cvarg{buf}{Optional buffer to avoid extra memory allocations. It's resized automatically.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{sum}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::absSum}
|
||||
Returns sum of matrix elements absolute values.
|
||||
|
||||
\cvdefCpp{Scalar absSum(const GpuMat\& src);\newline
|
||||
Scalar absSum(const GpuMat\& src, GpuMat\& buf);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image of any depth except \texttt{CV\_64F}.}
|
||||
\cvarg{buf}{Optional buffer to avoid extra memory allocations. It's resized automatically.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::sqrSum}
|
||||
Returns squared sum of matrix elements.
|
||||
|
||||
\cvdefCpp{Scalar sqrSum(const GpuMat\& src);\newline
|
||||
Scalar sqrSum(const GpuMat\& src, GpuMat\& buf);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image of any depth except \texttt{CV\_64F}.}
|
||||
\cvarg{buf}{Optional buffer to avoid extra memory allocations. It's resized automatically.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::minMax}
|
||||
Finds global minimum and maximum matrix elements and returns their values.
|
||||
|
||||
\cvdefCpp{void minMax(const GpuMat\& src, double* minVal,\par
|
||||
double* maxVal=0, const GpuMat\& mask=GpuMat());\newline
|
||||
void minMax(const GpuMat\& src, double* minVal, double* maxVal,\par
|
||||
const GpuMat\& mask, GpuMat\& buf);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Single-channel source image.}
|
||||
\cvarg{minVal}{Pointer to returned minimum value. \texttt{NULL} if not required.}
|
||||
\cvarg{maxVal}{Pointer to returned maximum value. \texttt{NULL} if not required.}
|
||||
\cvarg{mask}{Optional mask to select a sub-matrix. Please note the result is undefined in the case of empty mask.}
|
||||
\cvarg{buf}{Optional buffer to avoid extra memory allocations. It's resized automatically.}
|
||||
\end{description}
|
||||
|
||||
Function doesn't work with \texttt{CV\_64F} images on GPU with compute capability $<$ 1.3.\newline
|
||||
See also: \cvCppCross{minMaxLoc}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::minMaxLoc}
|
||||
Finds global minimum and maximum matrix elements and returns their values with locations.
|
||||
|
||||
\cvdefCpp{void minMaxLoc(const GpuMat\& src, double\* minVal, double* maxVal=0,\par
|
||||
Point* minLoc=0, Point* maxLoc=0,\par
|
||||
const GpuMat\& mask=GpuMat());\newline
|
||||
void minMaxLoc(const GpuMat\& src, double* minVal, double* maxVal,\par
|
||||
Point* minLoc, Point* maxLoc, const GpuMat\& mask,\par
|
||||
GpuMat\& valbuf, GpuMat\& locbuf);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Single-channel source image.}
|
||||
\cvarg{minVal}{Pointer to returned minimum value. \texttt{NULL} if not required.}
|
||||
\cvarg{maxVal}{Pointer to returned maximum value. \texttt{NULL} if not required.}
|
||||
\cvarg{minValLoc}{Pointer to returned minimum location. \texttt{NULL} if not required.}
|
||||
\cvarg{maxValLoc}{Pointer to returned maximum location. \texttt{NULL} if not required.}
|
||||
\cvarg{mask}{Optional mask to select a sub-matrix. Please note the result is undefined in the case of empty mask.}
|
||||
\cvarg{valbuf}{Optional values buffer to avoid extra memory allocations. It's resized automatically.}
|
||||
\cvarg{locbuf}{Optional locations buffer to avoid extra memory allocations. It's resized automatically.}
|
||||
\end{description}
|
||||
|
||||
Function doesn't work with \texttt{CV\_64F} images on GPU with compute capability $<$ 1.3.\newline
|
||||
See also: \cvCppCross{minMaxLoc}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::countNonZero}
|
||||
Counts non-zero matrix elements.
|
||||
|
||||
\cvdefCpp{int countNonZero(const GpuMat\& src);\newline
|
||||
int countNonZero(const GpuMat\& src, GpuMat\& buf);}
|
||||
\begin{description}
|
||||
\cvarg{src}{Single-channel source image.}
|
||||
\cvarg{buf}{Optional buffer to avoid extra memory allocations. It's resized automatically.}
|
||||
\end{description}
|
||||
|
||||
Function doesn't work with \texttt{CV\_64F} images on GPU with compute capability $<$ 1.3.\newline
|
||||
See also: \cvCppCross{countNonZero}.
|
@ -1,266 +0,0 @@
|
||||
\section{Object Detection}
|
||||
|
||||
\cvclass{gpu::HOGDescriptor}
|
||||
Histogram of Oriented Gradients \cite{dalal_hog} descriptor and detector.
|
||||
|
||||
\begin{lstlisting}
|
||||
struct CV_EXPORTS HOGDescriptor
|
||||
{
|
||||
enum { DEFAULT_WIN_SIGMA = -1 };
|
||||
enum { DEFAULT_NLEVELS = 64 };
|
||||
enum { DESCR_FORMAT_ROW_BY_ROW, DESCR_FORMAT_COL_BY_COL };
|
||||
|
||||
HOGDescriptor(Size win_size=Size(64, 128), Size block_size=Size(16, 16),
|
||||
Size block_stride=Size(8, 8), Size cell_size=Size(8, 8),
|
||||
int nbins=9, double win_sigma=DEFAULT_WIN_SIGMA,
|
||||
double threshold_L2hys=0.2, bool gamma_correction=true,
|
||||
int nlevels=DEFAULT_NLEVELS);
|
||||
|
||||
size_t getDescriptorSize() const;
|
||||
size_t getBlockHistogramSize() const;
|
||||
|
||||
void setSVMDetector(const vector<float>& detector);
|
||||
|
||||
static vector<float> getDefaultPeopleDetector();
|
||||
static vector<float> getPeopleDetector48x96();
|
||||
static vector<float> getPeopleDetector64x128();
|
||||
|
||||
void detect(const GpuMat& img, vector<Point>& found_locations,
|
||||
double hit_threshold=0, Size win_stride=Size(),
|
||||
Size padding=Size());
|
||||
|
||||
void detectMultiScale(const GpuMat& img, vector<Rect>& found_locations,
|
||||
double hit_threshold=0, Size win_stride=Size(),
|
||||
Size padding=Size(), double scale0=1.05,
|
||||
int group_threshold=2);
|
||||
|
||||
void getDescriptors(const GpuMat& img, Size win_stride,
|
||||
GpuMat& descriptors,
|
||||
int descr_format=DESCR_FORMAT_COL_BY_COL);
|
||||
|
||||
Size win_size;
|
||||
Size block_size;
|
||||
Size block_stride;
|
||||
Size cell_size;
|
||||
int nbins;
|
||||
double win_sigma;
|
||||
double threshold_L2hys;
|
||||
bool gamma_correction;
|
||||
int nlevels;
|
||||
|
||||
private:
|
||||
// Hidden
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Interfaces of all methods are kept similar to CPU HOG descriptor and detector analogues as much as possible.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::HOGDescriptor::HOGDescriptor}
|
||||
Creates HOG descriptor and detector.
|
||||
|
||||
\cvdefCpp{HOGDescriptor::HOGDescriptor(Size win\_size=Size(64, 128),\par
|
||||
Size block\_size=Size(16, 16), Size block\_stride=Size(8, 8),\par
|
||||
Size cell\_size=Size(8, 8), int nbins=9,\par
|
||||
double win\_sigma=DEFAULT\_WIN\_SIGMA,\par
|
||||
double threshold\_L2hys=0.2, bool gamma\_correction=true,\par
|
||||
int nlevels=DEFAULT\_NLEVELS);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{win\_size}{Detection window size. Must be aligned to block size and block stride.}
|
||||
\cvarg{block\_size}{Block size in pixels. Must be aligned to cell size. Only (16,16) is supported for now.}
|
||||
\cvarg{block\_stride}{Block stride. Must be a multiple of cell size.}
|
||||
\cvarg{cell\_size}{Cell size. Only (8, 8) is supported for now.}
|
||||
\cvarg{nbins}{Number of bins. Only 9 bins per cell is supported for now.}
|
||||
\cvarg{win\_sigma}{Gaussian smoothing window parameter.}
|
||||
\cvarg{threshold\_L2Hys}{L2-Hys normalization method shrinkage.}
|
||||
\cvarg{gamma\_correction}{Do gamma correction preprocessing or not.}
|
||||
\cvarg{nlevels}{Maximum number of detection window increases.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::HOGDescriptor::getDescriptorSize}
|
||||
Returns number of coefficients required for the classification.
|
||||
|
||||
\cvdefCpp{size\_t HOGDescriptor::getDescriptorSize() const;}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::HOGDescriptor::getBlockHistogramSize}
|
||||
Returns block histogram size.
|
||||
|
||||
\cvdefCpp{size\_t HOGDescriptor::getBlockHistogramSize() const;}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::HOGDescriptor::setSVMDetector}
|
||||
Sets coefficients for the linear SVM classifier.
|
||||
|
||||
\cvdefCpp{void HOGDescriptor::setSVMDetector(const vector<float>\& detector);}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::HOGDescriptor::getDefaultPeopleDetector}
|
||||
Returns coefficients of the classifier trained for people detection (for default window size).
|
||||
|
||||
\cvdefCpp{static vector<float> HOGDescriptor::getDefaultPeopleDetector();}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::HOGDescriptor::getPeopleDetector48x96}
|
||||
Returns coefficients of the classifier trained for people detection (for 48x96 windows).
|
||||
|
||||
\cvdefCpp{static vector<float> HOGDescriptor::getPeopleDetector48x96();}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::HOGDescriptor::getPeopleDetector64x128}
|
||||
Returns coefficients of the classifier trained for people detection (for 64x128 windows).
|
||||
|
||||
\cvdefCpp{static vector<float> HOGDescriptor::getPeopleDetector64x128();}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::HOGDescriptor::detect}
|
||||
Perfroms object detection without multiscale window.
|
||||
|
||||
\cvdefCpp{void HOGDescriptor::detect(const GpuMat\& img,\par
|
||||
vector<Point>\& found\_locations, double hit\_threshold=0,\par
|
||||
Size win\_stride=Size(), Size padding=Size());}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Source image. \texttt{CV\_8UC1} and \texttt{CV\_8UC4}types are supported for now.}
|
||||
\cvarg{found\_locations}{Will contain left-top corner points of detected objects boundaries.}
|
||||
\cvarg{hit\_threshold}{Threshold for the distance between features and SVM classifying plane. Usually it's 0 and should be specfied in the detector coefficients (as the last free coefficient), but if the free coefficient is omitted (it's allowed) you can specify it manually here.}
|
||||
\cvarg{win\_stride}{Window stride. Must be a multiple of block stride.}
|
||||
\cvarg{padding}{Mock parameter to keep CPU interface compatibility. Must be (0,0).}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::HOGDescriptor::detectMultiScale}
|
||||
Perfroms object detection with multiscale window.
|
||||
|
||||
\cvdefCpp{void HOGDescriptor::detectMultiScale(const GpuMat\& img,\par
|
||||
vector<Rect>\& found\_locations, double hit\_threshold=0,\par
|
||||
Size win\_stride=Size(), Size padding=Size(),\par
|
||||
double scale0=1.05, int group\_threshold=2);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Source image. See \cvCppCross{gpu::HOGDescriptor::detect} for type limitations.}
|
||||
\cvarg{found\_locations}{Will contain detected objects boundaries.}
|
||||
\cvarg{hit\_threshold}{The threshold for the distance between features and SVM classifying plane. See \cvCppCross{gpu::HOGDescriptor::detect} for details.}
|
||||
\cvarg{win\_stride}{Window stride. Must be a multiple of block stride.}
|
||||
\cvarg{padding}{Mock parameter to keep CPU interface compatibility. Must be (0,0).}
|
||||
\cvarg{scale0}{Coefficient of the detection window increase.}
|
||||
\cvarg{group\_threshold}{After detection some objects could be covered by many rectangles. This coefficient regulates similarity threshold. 0 means don't perform grouping.\newline
|
||||
See \cvCppCross{groupRectangles}.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::HOGDescriptor::getDescriptors}
|
||||
Returns block descriptors computed for the whole image. It's mainly used for classifier learning purposes.
|
||||
|
||||
\cvdefCpp{void HOGDescriptor::getDescriptors(const GpuMat\& img,\par
|
||||
Size win\_stride, GpuMat\& descriptors,\par
|
||||
int descr\_format=DESCR\_FORMAT\_COL\_BY\_COL);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Source image. See \cvCppCross{gpu::HOGDescriptor::detect} for type limitations.}
|
||||
\cvarg{win\_stride}{Window stride. Must be a multiple of block stride.}
|
||||
\cvarg{descriptors}{2D array of descriptors.}
|
||||
\cvarg{descr\_format}{Descriptor storage format:
|
||||
\begin{description}
|
||||
\cvarg{DESCR\_FORMAT\_ROW\_BY\_ROW}{Row-major order.}
|
||||
\cvarg{DESCR\_FORMAT\_COL\_BY\_COL}{Column-major order.}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvclass{gpu::CascadeClassifier\_GPU}
|
||||
The cascade classifier class for object detection.
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS CascadeClassifier_GPU
|
||||
{
|
||||
public:
|
||||
CascadeClassifier_GPU();
|
||||
CascadeClassifier_GPU(const string& filename);
|
||||
~CascadeClassifier_GPU();
|
||||
|
||||
bool empty() const;
|
||||
bool load(const string& filename);
|
||||
void release();
|
||||
|
||||
/* returns number of detected objects */
|
||||
int detectMultiScale( const GpuMat& image, GpuMat& objectsBuf, double scaleFactor=1.2, int minNeighbors=4, Size minSize=Size());
|
||||
|
||||
/* Finds only the largest object. Special mode for need to training*/
|
||||
bool findLargestObject;
|
||||
|
||||
/* Draws rectangles in input image */
|
||||
bool visualizeInPlace;
|
||||
|
||||
Size getClassifierSize() const;
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvfunc{cv::gpu::CascadeClassifier\_GPU::CascadeClassifier\_GPU}\par
|
||||
Loads the classifier from file.
|
||||
\cvdefCpp{cv::CascadeClassifier\_GPU(const string\& filename);}
|
||||
\begin{description}
|
||||
\cvarg{filename}{Name of file from which classifier will be load. Only old haar classifier (trained by haartraining application) and NVidia's nvbin are supported.}
|
||||
\end{description}
|
||||
|
||||
\cvfunc{cv::gpu::CascadeClassifier\_GPU::empty}
|
||||
Checks if the classifier has been loaded or not.
|
||||
\cvdefCpp{bool CascadeClassifier\_GPU::empty() const;}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::CascadeClassifier\_GPU::load}
|
||||
Loads the classifier from file. The previous content is destroyed.
|
||||
\cvdefCpp{bool CascadeClassifier\_GPU::load(const string\& filename);}
|
||||
\begin{description}
|
||||
\cvarg{filename}{Name of file from which classifier will be load. Only old haar classifier (trained by haartraining application) and NVidia's nvbin are supported.}
|
||||
\end{description}
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::CascadeClassifier\_GPU::release}
|
||||
Destroys loaded classifier.
|
||||
\cvdefCpp{void CascadeClassifier\_GPU::release()}
|
||||
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::CascadeClassifier\_GPU::detectMultiScale}
|
||||
Detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles.
|
||||
|
||||
\cvdefCpp{int CascadeClassifier\_GPU::detectMultiScale(const GpuMat\& image, GpuMat\& objectsBuf, double scaleFactor=1.2, int minNeighbors=4, Size minSize=Size());}
|
||||
\begin{description}
|
||||
\cvarg{image}{Matrix of type \texttt{CV\_8U} containing the image in which to detect objects.}
|
||||
\cvarg{objects}{Buffer to store detected objects (rectangles). If it is empty, it will be allocated with default size. If not empty, function will search not more than N objects, where N = sizeof(objectsBufer's data)/sizeof(cv::Rect).}
|
||||
\cvarg{scaleFactor}{Specifies how much the image size is reduced at each image scale.}
|
||||
\cvarg{minNeighbors}{Specifies how many neighbors should each candidate rectangle have to retain it.}
|
||||
\cvarg{minSize}{The minimum possible object size. Objects smaller than that are ignored.}
|
||||
\end{description}
|
||||
|
||||
The function returns number of detected objects, so you can retrieve them as in following example:
|
||||
|
||||
\begin{lstlisting}
|
||||
|
||||
cv::gpu::CascadeClassifier_GPU cascade_gpu(...);
|
||||
|
||||
Mat image_cpu = imread(...)
|
||||
GpuMat image_gpu(image_cpu);
|
||||
|
||||
GpuMat objbuf;
|
||||
int detections_number = cascade_gpu.detectMultiScale( image_gpu,
|
||||
objbuf, 1.2, minNeighbors);
|
||||
|
||||
Mat obj_host;
|
||||
// download only detected number of rectangles
|
||||
objbuf.colRange(0, detections_number).download(obj_host);
|
||||
|
||||
Rect* faces = obj_host.ptr<Rect>();
|
||||
for(int i = 0; i < detections_num; ++i)
|
||||
cv::rectangle(image_cpu, faces[i], Scalar(255));
|
||||
|
||||
imshow("Faces", image_cpu);
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
See also: \cvCppCross{CascadeClassifier::detectMultiScale}.
|
||||
|
@ -1,277 +0,0 @@
|
||||
\section{Per-element Operations.}
|
||||
|
||||
|
||||
\cvCppFunc{gpu::add}
|
||||
Computes matrix-matrix or matrix-scalar sum.
|
||||
|
||||
\cvdefCpp{void add(const GpuMat\& a, const GpuMat\& b, GpuMat\& c);}
|
||||
\begin{description}
|
||||
\cvarg{a}{First source matrix. \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_32SC1} and \texttt{CV\_32FC1} matrices are supported for now.}
|
||||
\cvarg{b}{Second source matrix. Must have the same size and type as \texttt{a}.}
|
||||
\cvarg{c}{Destination matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{void add(const GpuMat\& a, const Scalar\& sc, GpuMat\& c);}
|
||||
\begin{description}
|
||||
\cvarg{a}{Source matrix. \texttt{CV\_32FC1} and \texttt{CV\_32FC2} matrixes are supported for now.}
|
||||
\cvarg{b}{Source scalar to be added to the source matrix.}
|
||||
\cvarg{c}{Destination matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{add}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::subtract}
|
||||
Subtracts matrix from another matrix (or scalar from matrix).
|
||||
|
||||
\cvdefCpp{void subtract(const GpuMat\& a, const GpuMat\& b, GpuMat\& c);}
|
||||
\begin{description}
|
||||
\cvarg{a}{First source matrix. \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_32SC1} and \texttt{CV\_32FC1} matrices are supported for now.}
|
||||
\cvarg{b}{Second source matrix. Must have the same size and type as \texttt{a}.}
|
||||
\cvarg{c}{Destination matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{void subtract(const GpuMat\& a, const Scalar\& sc, GpuMat\& c);}
|
||||
\begin{description}
|
||||
\cvarg{a}{Source matrix. \texttt{CV\_32FC1} and \texttt{CV\_32FC2} matrixes are supported for now.}
|
||||
\cvarg{b}{Scalar to be subtracted from the source matrix elements.}
|
||||
\cvarg{c}{Destination matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{subtract}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::multiply}
|
||||
Computes per-element product of two matrices (or of matrix and scalar).
|
||||
|
||||
\cvdefCpp{void multiply(const GpuMat\& a, const GpuMat\& b, GpuMat\& c);}
|
||||
\begin{description}
|
||||
\cvarg{a}{First source matrix. \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_32SC1} and \texttt{CV\_32FC1} matrices are supported for now.}
|
||||
\cvarg{b}{Second source matrix. Must have the same size and type as \texttt{a}.}
|
||||
\cvarg{c}{Destionation matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{void multiply(const GpuMat\& a, const Scalar\& sc, GpuMat\& c);}
|
||||
\begin{description}
|
||||
\cvarg{a}{Source matrix. \texttt{CV\_32FC1} and \texttt{CV\_32FC2} matrixes are supported for now.}
|
||||
\cvarg{b}{Scalar to be multiplied by.}
|
||||
\cvarg{c}{Destination matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{multiply}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::divide}
|
||||
Performs per-element division of two matrices (or division of matrix by scalar).
|
||||
|
||||
\cvdefCpp{void divide(const GpuMat\& a, const GpuMat\& b, GpuMat\& c);}
|
||||
\begin{description}
|
||||
\cvarg{a}{First source matrix. \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_32SC1} and \texttt{CV\_32FC1} matrices are supported for now.}
|
||||
\cvarg{b}{Second source matrix. Must have the same size and type as \texttt{a}.}
|
||||
\cvarg{c}{Destionation matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{void divide(const GpuMat\& a, const Scalar\& sc, GpuMat\& c);}
|
||||
\begin{description}
|
||||
\cvarg{a}{Source matrix. \texttt{CV\_32FC1} and \texttt{CV\_32FC2} matrixes are supported for now.}
|
||||
\cvarg{b}{Scalar to be divided by.}
|
||||
\cvarg{c}{Destination matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
This function in contrast to \cvCppCross{divide} uses round-down rounding mode.
|
||||
|
||||
See also: \cvCppCross{divide}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::exp}
|
||||
Computes exponent of each matrix element.
|
||||
|
||||
\cvdefCpp{void exp(const GpuMat\& a, GpuMat\& b);}
|
||||
\begin{description}
|
||||
\cvarg{a}{Source matrix. \texttt{CV\_32FC1} matrixes are supported for now.}
|
||||
\cvarg{b}{Destination matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{exp}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::log}
|
||||
Computes natural logarithm of absolute value of each matrix element.
|
||||
|
||||
\cvdefCpp{void log(const GpuMat\& a, GpuMat\& b);}
|
||||
\begin{description}
|
||||
\cvarg{a}{Source matrix. \texttt{CV\_32FC1} matrixes are supported for now.}
|
||||
\cvarg{b}{Destination matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{log}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::absdiff}
|
||||
Computes per-element absolute difference of two matrices (or of matrix and scalar).
|
||||
|
||||
\cvdefCpp{void absdiff(const GpuMat\& a, const GpuMat\& b, GpuMat\& c);}
|
||||
\begin{description}
|
||||
\cvarg{a}{First source matrix. \texttt{CV\_8UC1}, \texttt{CV\_8UC4}, \texttt{CV\_32SC1} and \texttt{CV\_32FC1} matrices are supported for now.}
|
||||
\cvarg{b}{Second source matrix. Must have the same size and type as \texttt{a}.}
|
||||
\cvarg{c}{Destionation matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{void absdiff(const GpuMat\& a, const Scalar\& s, GpuMat\& c);}
|
||||
\begin{description}
|
||||
\cvarg{a}{Source matrix. \texttt{CV\_32FC1} matrixes are supported for now.}
|
||||
\cvarg{b}{Scalar to be subtracted from the source matrix elements.}
|
||||
\cvarg{c}{Destination matrix. Will have the same size and type as \texttt{a}.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{absdiff}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::compare}
|
||||
Compares elements of two matrices.
|
||||
|
||||
\cvdefCpp{void compare(const GpuMat\& a, const GpuMat\& b, GpuMat\& c, int cmpop);}
|
||||
\begin{description}
|
||||
\cvarg{a}{First source matrix. \texttt{CV\_8UC4} and \texttt{CV\_32FC1} matrices are supported for now.}
|
||||
\cvarg{b}{Second source matrix. Must have the same size and type as \texttt{a}.}
|
||||
\cvarg{c}{Destination matrix. Will have the same size as \texttt{a} and be \texttt{CV\_8UC1} type.}
|
||||
\cvarg{cmpop}{Flag specifying the relation between the elements to be checked:
|
||||
\begin{description}
|
||||
\cvarg{CMP\_EQ}{$=$}
|
||||
\cvarg{CMP\_GT}{$>$}
|
||||
\cvarg{CMP\_GE}{$\ge$}
|
||||
\cvarg{CMP\_LT}{$<$}
|
||||
\cvarg{CMP\_LE}{$\le$}
|
||||
\cvarg{CMP\_NE}{$\ne$}
|
||||
\end{description}
|
||||
}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{compare}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::bitwise\_not}\label{cppfunc.gpu.bitwise.not}
|
||||
Performs per-element bitwise inversion.
|
||||
|
||||
\cvdefCpp{void bitwise\_not(const GpuMat\& src, GpuMat\& dst,\par
|
||||
const GpuMat\& mask=GpuMat());\newline
|
||||
void bitwise\_not(const GpuMat\& src, GpuMat\& dst,\par
|
||||
const GpuMat\& mask, const Stream\& stream);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source matrix.}
|
||||
\cvarg{dst}{Destination matrix. Will have the same size and type as \texttt{src}.}
|
||||
\cvarg{mask}{Optional operation mask. 8-bit single channel image.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \hyperref[cppfunc.bitwise.not]{cv::bitwise\_not}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::bitwise\_or}\label{cppfunc.gpu.bitwise.or}
|
||||
Performs per-element bitwise disjunction of two matrices.
|
||||
|
||||
\cvdefCpp{void bitwise\_or(const GpuMat\& src1, const GpuMat\& src2, GpuMat\& dst,\par
|
||||
const GpuMat\& mask=GpuMat());\newline
|
||||
void bitwise\_or(const GpuMat\& src1, const GpuMat\& src2, GpuMat\& dst,\par
|
||||
const GpuMat\& mask, const Stream\& stream);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src1}{First source matrix.}
|
||||
\cvarg{src2}{Second source matrix. It must have the same size and type as \texttt{src1}.}
|
||||
\cvarg{dst}{Destination matrix. Will have the same size and type as \texttt{src1}.}
|
||||
\cvarg{mask}{Optional operation mask. 8-bit single channel image.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \hyperref[cppfunc.bitwise.or]{cv::bitwise\_or}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::bitwise\_and}\label{cppfunc.gpu.bitwise.and}
|
||||
Performs per-element bitwise conjunction of two matrices.
|
||||
|
||||
\cvdefCpp{void bitwise\_and(const GpuMat\& src1, const GpuMat\& src2, GpuMat\& dst,\par
|
||||
const GpuMat\& mask=GpuMat());\newline
|
||||
void bitwise\_and(const GpuMat\& src1, const GpuMat\& src2, GpuMat\& dst,\par
|
||||
const GpuMat\& mask, const Stream\& stream);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src1}{First source matrix.}
|
||||
\cvarg{src2}{Second source matrix. It must have the same size and type as \texttt{src1}.}
|
||||
\cvarg{dst}{Destination matrix. Will have the same size and type as \texttt{src1}.}
|
||||
\cvarg{mask}{Optional operation mask. 8-bit single channel image.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \hyperref[cppfunc.bitwise.and]{cv::bitwise\_and}.
|
||||
|
||||
|
||||
\cvfunc{cv::gpu::bitwise\_xor}\label{cppfunc.gpu.bitwise.xor}
|
||||
Performs per-element bitwise "exclusive or" of two matrices.
|
||||
|
||||
\cvdefCpp{void bitwise\_xor(const GpuMat\& src1, const GpuMat\& src2, GpuMat\& dst,\par
|
||||
const GpuMat\& mask=GpuMat());\newline
|
||||
void bitwise\_xor(const GpuMat\& src1, const GpuMat\& src2, GpuMat\& dst,\par
|
||||
const GpuMat\& mask, const Stream\& stream);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src1}{First source matrix.}
|
||||
\cvarg{src2}{Second source matrix. It must have the same size and type as \texttt{src1}.}
|
||||
\cvarg{dst}{Destination matrix. Will have the same size and type as \texttt{src1}.}
|
||||
\cvarg{mask}{Optional operation mask. 8-bit single channel image.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \hyperref[cppfunc.bitwise.xor]{cv::bitwise\_xor}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::min}
|
||||
Computes per-element minimum of two matrices (or of matrix and scalar).
|
||||
|
||||
\cvdefCpp{void min(const GpuMat\& src1, const GpuMat\& src2, GpuMat\& dst);\newline
|
||||
void min(const GpuMat\& src1, const GpuMat\& src2, GpuMat\& dst,\par
|
||||
const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{src1}{First source matrix.}
|
||||
\cvarg{src2}{Second source matrix.}
|
||||
\cvarg{dst}{Destination matrix. Will have the same size and type as \texttt{src1}.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{void min(const GpuMat\& src1, double src2, GpuMat\& dst);\newline
|
||||
void min(const GpuMat\& src1, double src2, GpuMat\& dst,\par
|
||||
const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{src1}{Source matrix.}
|
||||
\cvarg{src2}{Scalar to be compared with.}
|
||||
\cvarg{dst}{Destination matrix. Will have the same size and type as \texttt{src1}.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{min}.
|
||||
|
||||
|
||||
\cvCppFunc{gpu::max}
|
||||
Computes per-element maximum of two matrices (or of matrix and scalar).
|
||||
|
||||
\cvdefCpp{void max(const GpuMat\& src1, const GpuMat\& src2, GpuMat\& dst);\newline
|
||||
void max(const GpuMat\& src1, const GpuMat\& src2, GpuMat\& dst,\par
|
||||
const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{src1}{First source matrix.}
|
||||
\cvarg{src2}{Second source matrix.}
|
||||
\cvarg{dst}{Destination matrix. Will have the same size and type as \texttt{src1}.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
\cvdefCpp{void max(const GpuMat\& src1, double src2, GpuMat\& dst);\newline
|
||||
void max(const GpuMat\& src1, double src2, GpuMat\& dst,\par
|
||||
const Stream\& stream);}
|
||||
\begin{description}
|
||||
\cvarg{src1}{Source matrix.}
|
||||
\cvarg{src2}{Scalar to be compared with.}
|
||||
\cvarg{dst}{Destination matrix. Will have the same size and type as \texttt{src1}.}
|
||||
\cvarg{stream}{Stream for the asynchronous version.}
|
||||
\end{description}
|
||||
|
||||
See also: \cvCppCross{max}.
|
1046
doc/highgui.tex
1046
doc/highgui.tex
File diff suppressed because it is too large
Load Diff
@ -1,929 +0,0 @@
|
||||
|
||||
% ----- This section is now integrated in HighGui.tex
|
||||
|
||||
%\section{Qt updated functions}
|
||||
%\ifC
|
||||
%\section{C Language}
|
||||
%\cvCPyFunc{ConvertImage} % XXX:TBD
|
||||
%Converts one image to another with an optional vertical flip.
|
||||
%
|
||||
%\cvdefC{void cvConvertImage( const CvArr* src, CvArr* dst, int flags=0 );}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{src}{Source image.}
|
||||
%\cvarg{dst}{Destination image. Must be single-channel or 3-channel 8-bit image.}
|
||||
%\cvarg{flags}{The operation flags:
|
||||
%\begin{description}
|
||||
%\cvarg{CV\_CVTIMG\_FLIP}{Flips the image vertically}
|
||||
%\cvarg{CV\_CVTIMG\_SWAP\_RB}{Swaps the red and blue channels. In OpenCV color images have \texttt{BGR} channel order, however on some systems the order needs to be reversed before displaying the image (\cross{ShowImage} does this automatically).}
|
||||
%\end{description}}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvConvertImage} converts one image to another and flips the result vertically if desired. The function is used by \cross{ShowImage}.
|
||||
|
||||
|
||||
%\cvCPyFunc{CreateTrackbar}
|
||||
%Creates a trackbar and attaches it to the specified window
|
||||
%
|
||||
%\cvdefC{
|
||||
%int cvCreateTrackbar( \par const char* trackbarName, \par const char* windowName,
|
||||
% \par int* value, \par int count, \par CvTrackbarCallback onChange );
|
||||
%}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{trackbarName}{Name of the created trackbar.}
|
||||
%\cvarg{windowName}{Name of the window which will be used as a parent for created trackbar. Can be NULL if the trackbar should be attached to the control panel.}
|
||||
%\cvarg{value}{Pointer to an integer variable, whose value will reflect the position of the slider. Upon creation, the slider position is defined by this variable.}
|
||||
%
|
||||
%\cvarg{count}{Maximal position of the slider. Minimal position is always 0.}
|
||||
%
|
||||
%\cvarg{onChange}{
|
||||
%Pointer to the function to be called every time the slider changes position.
|
||||
%This function should be prototyped as \texttt{void Foo(int);} Can be NULL if callback is not required.}
|
||||
%
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvCreateTrackbar} creates a trackbar (a.k.a. slider or range control) with the specified name and range, assigns a variable to be syncronized with trackbar position and specifies a callback function to be called on trackbar position change. The created trackbar is displayed at the bottom of the given window if \emph{windowName} is correctly provided, or displayed on the control panel if \emph{windowName} is NULL.
|
||||
%\begin{lstlisting}
|
||||
%CV_EXTERN_C_FUNCPTR( void (*CvTrackbarCallback)(int pos) );
|
||||
%\end{lstlisting}
|
||||
|
||||
%By clicking on the label of each trackbar, it is possible to edit the trackbar's value manually for a more accurate control of it.
|
||||
|
||||
%\cvCPyFunc{DestroyAllWindows}
|
||||
%Destroys all of the HighGUI windows.
|
||||
%
|
||||
%\cvdefC{void cvDestroyAllWindows(void);}
|
||||
%
|
||||
%The function \texttt{cvDestroyAllWindows} destroys all of the opened HighGUI windows.
|
||||
%
|
||||
%\cvCPyFunc{DestroyWindow}
|
||||
%Destroys a window.
|
||||
%
|
||||
%\cvdefC{void cvDestroyWindow( const char* name );}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{name}{Name of the window to be destroyed.}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvDestroyWindow} destroys the window with the given name.
|
||||
|
||||
%\cvCPyFunc{GetTrackbarPos}
|
||||
%Returns the trackbar position.
|
||||
%
|
||||
%\cvdefC{int cvGetTrackbarPos( \par const char* trackbarName, \par const char* windowName );}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{trackbarName}{Name of the trackbar.}
|
||||
%\cvarg{windowName}{Name of the window which is the parent of the trackbar. Can be NULL if the trackbar is attached to the control panel.}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvGetTrackbarPos} returns the current position of the specified trackbar.
|
||||
|
||||
%\cvCPyFunc{GetWindowHandle}
|
||||
%Gets the window's handle by its name.
|
||||
%
|
||||
%\cvdefC{void* cvGetWindowHandle( const char* name );}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{name}{Name of the window}.
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvGetWindowHandle} returns the native window handle. (QWidget)
|
||||
|
||||
%\cvCPyFunc{GetWindowName}
|
||||
%Gets the window's name by its handle.
|
||||
%
|
||||
%\cvdefC{const char* cvGetWindowName( void* windowHandle );}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{windowHandle}{Handle of the window.}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvGetWindowName} returns the name of the window given its native handle (QWidget).
|
||||
%
|
||||
%\cvCPyFunc{InitSystem}
|
||||
%Initializes HighGUI.
|
||||
%
|
||||
%\cvdefC{int cvInitSystem( int argc, char** argv );}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{argc}{Number of command line arguments}
|
||||
%\cvarg{argv}{Array of command line arguments}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvInitSystem} initializes HighGUI. If it wasn't
|
||||
%called explicitly by the user before the first window was created, it is
|
||||
%called implicitly then with \texttt{argc=0}, \texttt{argv=NULL}. Under
|
||||
%Win32 there is no need to call it explicitly. Under X Window the arguments
|
||||
%may be used to customize a look of HighGUI windows and controls.
|
||||
|
||||
|
||||
%\cvCPyFunc{MoveWindow}
|
||||
%Sets the position of the window.
|
||||
%
|
||||
%\cvdefC{void cvMoveWindow( const char* name, int x, int y );}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{name}{Name of the window to be moved.}
|
||||
%\cvarg{x}{New x coordinate of the top-left corner}
|
||||
%\cvarg{y}{New y coordinate of the top-left corner}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvMoveWindow} changes the position of the window.
|
||||
|
||||
%\cvCPyFunc{NamedWindow}
|
||||
%Creates a window.
|
||||
%
|
||||
%\cvdefC{int cvNamedWindow( const char* name, int flags = 0 );}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{name}{Name of the window in the window caption that may be used as a window identifier.}
|
||||
%\cvarg{flags}{Flags of the window. Currently the supported flags are:
|
||||
%\begin{description}
|
||||
% \cvarg{CV\_WINDOW\_NORMAL or CV\_WINDOW\_AUTOSIZE:}
|
||||
%{ \texttt{CV\_WINDOW\_NORMAL} let the user resize the window, whereas \texttt{CV\_WINDOW\_AUTOSIZE} adjusts automatically the window's size to fit the displayed image (see \cross{ShowImage}), and the user can not change the window size manually.}
|
||||
% \cvarg{CV\_WINDOW\_FREERATIO or CV\_WINDOW\_KEEPRATIO:}
|
||||
%{\texttt{CV\_WINDOW\_FREERATIO} adjust the image without respect the its ration, whereas \texttt{CV\_WINDOW\_KEEPRATIO} keep the image's ratio.}
|
||||
% \cvarg{CV\_GUI\_NORMAL or CV\_GUI\_EXPANDED:}
|
||||
%{ \texttt{CV\_GUI\_NORMAL} is the old way to draw the window without statusbar and toolbar, whereas \texttt{CV\_GUI\_EXPANDED} is the new enhance GUI.}
|
||||
%\end{description}
|
||||
%
|
||||
%This parameter is optional. The default flags set for a new window are \texttt{CV\_WINDOW\_AUTOSIZE}, \texttt{CV\_WINDOW\_KEEPRATIO}, and \texttt{CV\_GUI\_EXPANDED}.
|
||||
%
|
||||
%However, if you want to modify the flags, you can combine them using OR operator, ie:
|
||||
%cvNamedWindow( ``myWindow'', \texttt{CV\_WINDOW\_NORMAL} \textbar \texttt{CV\_GUI\_NORMAL});}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvNamedWindow} creates a window which can be used as a placeholder for images and trackbars. Created windows are referred to by their names.
|
||||
%
|
||||
%
|
||||
%If a window with the same name already exists, the function does nothing.
|
||||
|
||||
%\cvCPyFunc{ResizeWindow}
|
||||
%Sets the window size.
|
||||
%
|
||||
%\cvdefC{void cvResizeWindow( const char* name, int width, int height );}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{name}{Name of the window to be resized.}
|
||||
%\cvarg{width}{New width}
|
||||
%\cvarg{height}{New height}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvResizeWindow} changes the size of the window.
|
||||
|
||||
%\cvCPyFunc{SetMouseCallback}
|
||||
%Assigns callback for mouse events.
|
||||
%
|
||||
%\cvdefC{void cvSetMouseCallback( const char* windowName, CvMouseCallback onMouse, void* param=NULL );}
|
||||
%
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{windowName}{Name of the window.}
|
||||
%
|
||||
%\cvarg{onMouse}{Pointer to the function to be called every time a mouse event occurs in the specified window. This function should be prototyped as
|
||||
%\texttt{void Foo(int event, int x, int y, int flags, void* param);}
|
||||
%where \texttt{event} is one of \texttt{CV\_EVENT\_*}, \texttt{x} and \texttt{y} are the coordinates of the mouse pointer in image coordinates (not window coordinates), \texttt{flags} is a combination of \texttt{CV\_EVENT\_FLAG\_*}, and \texttt{param} is a user-defined parameter passed to the \texttt{cvSetMouseCallback} function call.}
|
||||
%
|
||||
%\cvarg{param}{User-defined parameter to be passed to the callback function.}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvSetMouseCallback} sets the callback function for mouse events occuring within the specified window.
|
||||
%
|
||||
%The \texttt{event} parameter is one of:
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{CV\_EVENT\_MOUSEMOVE}{Mouse movement}
|
||||
%\cvarg{CV\_EVENT\_LBUTTONDOWN}{Left button down}
|
||||
%\cvarg{CV\_EVENT\_RBUTTONDOWN}{Right button down}
|
||||
%\cvarg{CV\_EVENT\_MBUTTONDOWN}{Middle button down}
|
||||
%\cvarg{CV\_EVENT\_LBUTTONUP}{Left button up}
|
||||
%\cvarg{CV\_EVENT\_RBUTTONUP}{Right button up}
|
||||
%\cvarg{CV\_EVENT\_MBUTTONUP}{Middle button up}
|
||||
%\cvarg{CV\_EVENT\_LBUTTONDBLCLK}{Left button double click}
|
||||
%\cvarg{CV\_EVENT\_RBUTTONDBLCLK}{Right button double click}
|
||||
%\cvarg{CV\_EVENT\_MBUTTONDBLCLK}{Middle button double click}
|
||||
%\end{description}
|
||||
%
|
||||
%The \texttt{flags} parameter is a combination of :
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{CV\_EVENT\_FLAG\_LBUTTON}{Left button pressed}
|
||||
%\cvarg{CV\_EVENT\_FLAG\_RBUTTON}{Right button pressed}
|
||||
%\cvarg{CV\_EVENT\_FLAG\_MBUTTON}{Middle button pressed}
|
||||
%\cvarg{CV\_EVENT\_FLAG\_CTRLKEY}{Control key pressed}
|
||||
%\cvarg{CV\_EVENT\_FLAG\_SHIFTKEY}{Shift key pressed}
|
||||
%\cvarg{CV\_EVENT\_FLAG\_ALTKEY}{Alt key pressed}
|
||||
%\end{description}
|
||||
|
||||
%\cvCPyFunc{SetTrackbarPos}
|
||||
%Sets the trackbar position.
|
||||
%
|
||||
%\cvdefC{void cvSetTrackbarPos( \par const char* trackbarName, \par const char* windowName, \par int pos );}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{trackbarName}{Name of the trackbar.}
|
||||
%\cvarg{windowName}{Name of the window which is the parent of trackbar. Can be NULL if the trackbar is attached to the control panel.}
|
||||
%\cvarg{pos}{New position.}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvSetTrackbarPos} sets the position of the specified trackbar.
|
||||
%
|
||||
%\cvCPyFunc{ShowImage}
|
||||
%Displays the image in the specified window
|
||||
%
|
||||
%\cvdefC{void cvShowImage( const char* name, const CvArr* image );}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{name}{Name of the window.}
|
||||
%\cvarg{image}{Image to be shown.}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvShowImage} displays the image in the specified window. If the window was created with the \texttt{CV\_WINDOW\_AUTOSIZE} flag then the image is shown with its original size, otherwise the image is scaled to fit in the window. The function may scale the image, depending on its depth:
|
||||
%\begin{itemize}
|
||||
% \item If the image is 8-bit unsigned, it is displayed as is.
|
||||
% \item If the image is 16-bit unsigned or 32-bit integer, the pixels are divided by 256. That is, the value range [0,255*256] is mapped to [0,255].
|
||||
% \item If the image is 32-bit floating-point, the pixel values are multiplied by 255. That is, the value range [0,1] is mapped to [0,255].
|
||||
%\end{itemize}
|
||||
|
||||
%\cvCPyFunc{WaitKey}
|
||||
%Waits for a pressed key.
|
||||
%
|
||||
%\cvdefC{int cvWaitKey( int delay=0 );}
|
||||
%\cvdefPy{WaitKey(delay=0)-> int}
|
||||
%
|
||||
%\begin{description}
|
||||
%\cvarg{delay}{Delay in milliseconds.}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{cvWaitKey} waits for key event infinitely ($ \texttt{delay} <= 0$) or for \texttt{delay} milliseconds. Returns the code of the pressed key or -1 if no key was pressed before the specified time had elapsed.
|
||||
%
|
||||
%\textbf{Note:} This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing, unless HighGUI is used within some environment that takes care of event processing. With this current Qt implementation, this is the only way to process event such as repaint for the windows, and so on \ldots
|
||||
%
|
||||
%\fi
|
||||
|
||||
%\ifCpp
|
||||
|
||||
%%%%%%%%%%%%%%%%%%% HERE CPP
|
||||
%\section{C++ Language}
|
||||
|
||||
%\cvCppFunc{createTrackbar}
|
||||
%Creates a trackbar and attaches it to the specified window
|
||||
%
|
||||
%\cvdefCpp{int createTrackbar( const string\& trackbarname,\par
|
||||
% const string\& winname,\par
|
||||
% int* value, int count,\par
|
||||
% TrackbarCallback onChange CV\_DEFAULT(0),\par
|
||||
% void* userdata CV\_DEFAULT(0));}
|
||||
%\begin{description}
|
||||
%\cvarg{trackbarname}{Name of the created trackbar.}
|
||||
%\cvarg{winname}{Name of the window which will be used as a parent for created trackbar. Can be NULL if the trackbar should be attached to the control panel.}
|
||||
%\cvarg{value}{The optional pointer to an integer variable, whose value will reflect the position of the slider. Upon creation, the slider position is defined by this variable.}
|
||||
%\cvarg{count}{The maximal position of the slider. The minimal position is always 0.}
|
||||
%\cvarg{onChange}{Pointer to the function to be called every time the slider changes position. This function should be prototyped as \texttt{void Foo(int,void*);}, where the first parameter is the trackbar position and the second parameter is the user data (see the next parameter). If the callback is NULL pointer, then no callbacks is called, but only \texttt{value} is updated}
|
||||
%\cvarg{userdata}{The user data that is passed as-is to the callback; it can be used to handle trackbar events without using global variables}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{createTrackbar} creates a trackbar (a.k.a. slider or range control) with the specified name and range, assigns a variable \texttt{value} to be syncronized with trackbar position and specifies a callback function \texttt{onChange} to be called on the trackbar position change. The created trackbar is displayed at the bottom of the given window if \emph{winname} is correctly provided, or displayed on the control panel if \emph{winname} is NULL.
|
||||
%
|
||||
%By clicking on the label of each trackbar, it is possible to edit the trackbar's value manually for a more accurate control of it.
|
||||
|
||||
%\cvCppFunc{getTrackbarPos}
|
||||
%Returns the trackbar position.
|
||||
%
|
||||
%\cvdefCpp{int getTrackbarPos( const string\& trackbarname, \par const string\& winname );}
|
||||
%\begin{description}
|
||||
%\cvarg{trackbarname}{Name of the trackbar.}
|
||||
%\cvarg{winname}{Name of the window which is the parent of the trackbar. Can be NULL if the trackbar is attached to the control panel.}
|
||||
%\end{description}
|
||||
%
|
||||
%The function returns the current position of the specified trackbar.
|
||||
|
||||
%
|
||||
%\cvCppFunc{imshow}
|
||||
%Displays the image in the specified window
|
||||
%
|
||||
%\cvdefCpp{void imshow( const string\& winname, \par const Mat\& image );}
|
||||
%\begin{description}
|
||||
%\cvarg{winname}{Name of the window.}
|
||||
%\cvarg{image}{Image to be shown.}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{imshow} displays the image in the specified window. If the window was created with the \texttt{CV\_WINDOW\_AUTOSIZE} flag then the image is shown with its original size, otherwise the image is scaled to fit in the window. The function may scale the image, depending on its depth:
|
||||
%\begin{itemize}
|
||||
% \item If the image is 8-bit unsigned, it is displayed as is.
|
||||
% \item If the image is 16-bit unsigned or 32-bit integer, the pixels are divided by 256. That is, the value range [0,255*256] is mapped to [0,255].
|
||||
% \item If the image is 32-bit floating-point, the pixel values are multiplied by 255. That is, the value range [0,1] is mapped to [0,255].
|
||||
%\end{itemize}
|
||||
|
||||
|
||||
%\cvCppFunc{namedWindow}
|
||||
%Creates a window.
|
||||
%
|
||||
%\cvdefCpp{void namedWindow( const string\& winname, \par int flags = 0 );}
|
||||
%\begin{description}
|
||||
%\cvarg{name}{Name of the window in the window caption that may be used as a window identifier.}
|
||||
%\cvarg{flags}{Flags of the window. Currently the supported flags are:
|
||||
%\begin{description}
|
||||
% \cvarg{CV\_WINDOW\_NORMAL or CV\_WINDOW\_AUTOSIZE:}
|
||||
%{ \texttt{CV\_WINDOW\_NORMAL} let the user resize the window, whereas \texttt{CV\_WINDOW\_AUTOSIZE} adjusts automatically the window's size to fit the displayed image (see \cross{ShowImage}), and the user can not change the window size manually.}
|
||||
% \cvarg{CV\_WINDOW\_FREERATIO or CV\_WINDOW\_KEEPRATIO:}
|
||||
%{\texttt{CV\_WINDOW\_FREERATIO} adjust the image without respect the its ration, whereas \texttt{CV\_WINDOW\_KEEPRATIO} keep the image's ratio.}
|
||||
% \cvarg{CV\_GUI\_NORMAL or CV\_GUI\_EXPANDED:}
|
||||
%{ \texttt{CV\_GUI\_NORMAL} is the old way to draw the window without statusbar and toolbar, whereas \texttt{CV\_GUI\_EXPANDED} is the new enhance GUI.}
|
||||
%\end{description}
|
||||
%
|
||||
%This parameter is optional. The default flags set for a new window are \texttt{CV\_WINDOW\_AUTOSIZE}, \texttt{CV\_WINDOW\_KEEPRATIO}, and \texttt{CV\_GUI\_EXPANDED}.
|
||||
%
|
||||
%However, if you want to modify the flags, you can combine them using OR operator, ie:
|
||||
%namedWindow( ``myWindow'', \texttt{CV\_WINDOW\_NORMAL} \textbar \texttt{CV\_GUI\_NORMAL});}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{namedWindow} creates a window which can be used as a placeholder for images and trackbars. Created windows are referred to by their names.
|
||||
%
|
||||
%If a window with the same name already exists, the function does nothing.
|
||||
%
|
||||
%\cvCppFunc{setTrackbarPos}
|
||||
%Sets the trackbar position.
|
||||
%
|
||||
%\cvdefCpp{void setTrackbarPos( const string\& trackbarname, \par const string\& winname, int pos );}
|
||||
%\begin{description}
|
||||
%\cvarg{trackbarname}{Name of the trackbar.}
|
||||
%\cvarg{winname}{Name of the window which is the parent of trackbar. Can be NULL if the trackbar is attached to the control panel.}
|
||||
%\cvarg{pos}{The new position.}
|
||||
%\end{description}
|
||||
%
|
||||
%The function sets the position of the specified trackbar.
|
||||
|
||||
|
||||
%\cvCppFunc{waitKey}
|
||||
%Waits for a pressed key.
|
||||
%
|
||||
%\cvdefCpp{int waitKey(int delay=0);}
|
||||
%\begin{description}
|
||||
%\cvarg{delay}{Delay in milliseconds. 0 is the special value that means "forever"}
|
||||
%\end{description}
|
||||
%
|
||||
%The function \texttt{waitKey} waits for key event infinitely (when $\texttt{delay}\leq 0$) or for \texttt{delay} milliseconds, when it's positive. Returns the code of the pressed key or -1 if no key was pressed before the specified time had elapsed.
|
||||
%
|
||||
%\textbf{Note:} This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing, unless HighGUI is used within some environment that takes care of event processing. With this current Qt implementation, this is the only way to process event such as repaint for the windows, and so on \ldots
|
||||
%
|
||||
%\textbf{Note 2:} The function only works if there is at least one HighGUI window created and the window is active. If there are several HighGUI windows, any of them can be active.
|
||||
|
||||
%\fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\section{Qt new functions}
|
||||
|
||||
%here explain and picture
|
||||
\includegraphics[width=1.1\textwidth]{pics/Qt_GUI.png}
|
||||
|
||||
This figure explains the new functionalities implemented with Qt GUI. As we can see, the new GUI provides a statusbar, a toolbar, and a control panel. The control panel can have trackbars and buttonbars attached to it.
|
||||
\begin{itemize}
|
||||
\item To attach a trackbar, the window\_name parameter must be NULL.
|
||||
\item To attach a buttonbar, a button must be created.
|
||||
If the last bar attached to the control panel is a buttonbar, the new button is added on the right of the last button.
|
||||
If the last bar attached to the control panel is a trackbar, or the control panel is empty, a new buttonbar is created. Then a new button is attached to it.
|
||||
\end{itemize}
|
||||
|
||||
The following code is an example used to generate the figure.
|
||||
\begin{lstlisting}
|
||||
int main(int argc, char *argv[])
|
||||
int value = 50;
|
||||
int value2 = 0;
|
||||
|
||||
cvNamedWindow("main1",CV_WINDOW_NORMAL);
|
||||
cvNamedWindow("main2",CV_WINDOW_AUTOSIZE | CV_GUI_NORMAL);
|
||||
|
||||
cvCreateTrackbar( "track1", "main1", &value, 255, NULL);//OK tested
|
||||
char* nameb1 = "button1";
|
||||
char* nameb2 = "button2";
|
||||
cvCreateButton(nameb1,callbackButton,nameb1,CV_CHECKBOX,1);
|
||||
|
||||
cvCreateButton(nameb2,callbackButton,nameb2,CV_CHECKBOX,0);
|
||||
cvCreateTrackbar( "track2", NULL, &value2, 255, NULL);
|
||||
cvCreateButton("button5",callbackButton1,NULL,CV_RADIOBOX,0);
|
||||
cvCreateButton("button6",callbackButton2,NULL,CV_RADIOBOX,1);
|
||||
|
||||
cvSetMouseCallback( "main2",on_mouse,NULL );
|
||||
|
||||
IplImage* img1 = cvLoadImage("files/flower.jpg");
|
||||
IplImage* img2 = cvCreateImage(cvGetSize(img1),8,3);
|
||||
CvCapture* video = cvCaptureFromFile("files/hockey.avi");
|
||||
IplImage* img3 = cvCreateImage(cvGetSize(cvQueryFrame(video)),8,3);
|
||||
|
||||
while(cvWaitKey(33) != 27)
|
||||
{
|
||||
cvAddS(img1,cvScalarAll(value),img2);
|
||||
cvAddS(cvQueryFrame(video),cvScalarAll(value2),img3);
|
||||
cvShowImage("main1",img2);
|
||||
cvShowImage("main2",img3);
|
||||
}
|
||||
|
||||
cvDestroyAllWindows();
|
||||
cvReleaseImage(&img1);
|
||||
cvReleaseImage(&img2);
|
||||
cvReleaseImage(&img3);
|
||||
cvReleaseCapture(&video);
|
||||
return 0;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\ifC
|
||||
%CVAPI(void) cvSetWindowProperty(const char* name, int prop_id, double prop_value);
|
||||
\cvCPyFunc{SetWindowProperty}
|
||||
Change the parameters of the window dynamically.
|
||||
|
||||
\cvdefC{void cvSetWindowProperty(const char* name, int prop\_id, double prop\_value);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window.}
|
||||
\cvarg{prop\_id}{Window's property to edit. The operation flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_WND\_PROP\_FULLSCREEN}{Change if the window is fullscreen (\texttt{CV\_WINDOW\_NORMAL} or \texttt{CV\_WINDOW\_FULLSCREEN}).}
|
||||
\cvarg{CV\_WND\_PROP\_AUTOSIZE}{Change if the user can resize the window (texttt{CV\_WINDOW\_NORMAL} or \texttt{CV\_WINDOW\_AUTOSIZE}).}
|
||||
\cvarg{CV\_WND\_PROP\_ASPECTRATIO}{Change if the image's aspect ratio is preserved (texttt{CV\_WINDOW\_FREERATIO} or \texttt{CV\_WINDOW\_KEEPRATIO}).}
|
||||
\end{description}}
|
||||
\cvarg{prop\_value}{New value of the Window's property. The operation flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_WINDOW\_NORMAL}{Change the window in normal size, or allows the user to resize the window.}
|
||||
\cvarg{CV\_WINDOW\_AUTOSIZE}{The user cannot resize the window, the size is constrainted by the image displayed.}
|
||||
\cvarg{CV\_WINDOW\_FULLSCREEN}{Change the window to fullscreen.}
|
||||
\cvarg{CV\_WINDOW\_FREERATIO}{The image expends as much as it can (no ratio constraint)}
|
||||
\cvarg{CV\_WINDOW\_KEEPRATIO}{The ration image is respected.}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{ cvSetWindowProperty} allows to change the window's properties.
|
||||
|
||||
|
||||
|
||||
%CVAPI(double) cvGetWindowProperty(const char* name, int prop_id);
|
||||
\cvCPyFunc{GetWindowProperty}
|
||||
Get the parameters of the window.
|
||||
|
||||
\cvdefC{void cvGetWindowProperty(const char* name, int prop\_id);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window.}
|
||||
\cvarg{prop\_id}{Window's property to retrive. The operation flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_WND\_PROP\_FULLSCREEN}{Change if the window is fullscreen (\texttt{CV\_WINDOW\_NORMAL} or \texttt{CV\_WINDOW\_FULLSCREEN}).}
|
||||
\cvarg{CV\_WND\_PROP\_AUTOSIZE}{Change if the user can resize the window (texttt{CV\_WINDOW\_NORMAL} or \texttt{CV\_WINDOW\_AUTOSIZE}).}
|
||||
\cvarg{CV\_WND\_PROP\_ASPECTRATIO}{Change if the image's aspect ratio is preserved (texttt{CV\_WINDOW\_FREERATIO} or \texttt{CV\_WINDOW\_KEEPRATIO}).}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
See \cross{SetWindowProperty} to know the meaning of the returned values.
|
||||
|
||||
The function \texttt{ cvGetWindowProperty} return window's properties.
|
||||
|
||||
|
||||
\cvCPyFunc{FontQt}
|
||||
Create the font to be used to draw text on an image (with \cross{addText}).
|
||||
|
||||
\cvdefC{CvFont cvFontQt(const char* nameFont, int pointSize = -1, CvScalar color = cvScalarAll(0), int weight = CV\_FONT\_NORMAL, int style = CV\_STYLE\_NORMAL, int spacing = 0);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{nameFont}{Name of the font. The name should match the name of a system font (such as ``Times''). If the font is not found, a default one will be used.}
|
||||
\cvarg{pointSize}{Size of the font. If not specified, equal zero or negative, the point size of the font is set to a system-dependent default value. Generally, this is 12 points.}
|
||||
\cvarg{color}{Color of the font in BGRA -- A = 255 is fully transparent. Use the macro CV\_RGB for simplicity.}
|
||||
\cvarg{weight}{The operation flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_FONT\_LIGHT}{Weight of 25}
|
||||
\cvarg{CV\_FONT\_NORMAL}{Weight of 50}
|
||||
\cvarg{CV\_FONT\_DEMIBOLD}{Weight of 63}
|
||||
\cvarg{CV\_FONT\_BOLD}{Weight of 75}
|
||||
\cvarg{CV\_FONT\_BLACK}{Weight of 87}
|
||||
You can also specify a positive integer for more control.
|
||||
\end{description}}
|
||||
\cvarg{style}{The operation flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_STYLE\_NORMAL}{Font is normal}
|
||||
\cvarg{CV\_STYLE\_ITALIC}{Font is in italic}
|
||||
\cvarg{CV\_STYLE\_OBLIQUE}{Font is oblique}
|
||||
\end{description}}
|
||||
\cvarg{spacing}{Spacing between characters. Can be negative or positive}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvFontQt} creates a CvFont object to be used with \cross{addText}. This CvFont is not compatible with cvPutText.
|
||||
|
||||
A basic usage of this function is:
|
||||
\begin{lstlisting}
|
||||
CvFont font = cvFontQt(''Times'');
|
||||
cvAddText( img1, ``Hello World !'', cvPoint(50,50), font);
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvCPyFunc{AddText}
|
||||
Create the font to be used to draw text on an image
|
||||
\cvdefC{void cvAddText(const CvArr* img, const char* text, CvPoint location, CvFont *font);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Image where the text should be drawn}
|
||||
\cvarg{text}{Text to write on the image}
|
||||
\cvarg{location}{Point(x,y) where the text should start on the image}
|
||||
\cvarg{font}{Font to use to draw the text}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvAddText} draw \emph{text} on the image \emph{img} using a specific font \emph{font} (see example \cross{FontQt})
|
||||
|
||||
|
||||
%CVAPI(void) cvDisplayOverlay(const char* name, const char* text, int delay);
|
||||
\cvCPyFunc{DisplayOverlay}
|
||||
Display text on the window's image as an overlay for delay milliseconds. This is not editing the image's data. The text is display on the top of the image.
|
||||
\cvdefC{void cvDisplayOverlay(const char* name, const char* text, int delay);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window}
|
||||
\cvarg{text}{Overlay text to write on the window's image}
|
||||
\cvarg{delay}{Delay to display the overlay text. If this function is called before the previous overlay text time out, the timer is restarted and the text updated. . If this value is zero, the text never disapers.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvDisplayOverlay} aims at displaying useful information/tips on the window for a certain amount of time \emph{delay}. This information is display on the top of the window.
|
||||
|
||||
|
||||
%CVAPI(void) cvDisplayStatusBar(const char* name, const char* text, int delayms);
|
||||
\cvCPyFunc{DisplayStatusBar}
|
||||
Display text on the window's statusbar as for delay milliseconds.
|
||||
\cvdefC{void cvDisplayStatusBar(const char* name, const char* text, int delayms);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window}
|
||||
\cvarg{text}{Text to write on the window's statusbar}
|
||||
\cvarg{delay}{Delay to display the text. If this function is called before the previous text time out, the timer is restarted and the text updated. If this value is zero, the text never disapers.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvDisplayOverlay} aims at displaying useful information/tips on the window for a certain amount of time \emph{delay}. This information is displayed on the window's statubar (the window must be created with \texttt{CV\_GUI\_EXPANDED} flags).
|
||||
|
||||
|
||||
|
||||
%CVAPI(void) cvCreateOpenGLCallback( const char* window_name, CvOpenGLCallback callbackOpenGL, void* userdata CV_DEFAULT(NULL), double angle CV_DEFAULT(-1), double zmin CV_DEFAULT(-1), double zmax CV_DEFAULT(-1));
|
||||
\cvCPyFunc{CreateOpenGLCallback}
|
||||
Create a callback function called to draw OpenGL on top the the image display by \emph{window\_name}.
|
||||
\cvdefC{void cvCreateOpenGLCallback( const char* window\_name, CvOpenGLCallback callbackOpenGL, void* userdata CV\_DEFAULT(NULL), double angle CV\_DEFAULT(-1), double zmin CV\_DEFAULT(-1), double zmax CV\_DEFAULT(-1);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{window\_name}{Name of the window}
|
||||
\cvarg{callbackOpenGL}{
|
||||
Pointer to the function to be called every frame.
|
||||
This function should be prototyped as \texttt{void Foo(*void);}.}
|
||||
\cvarg{userdata}{pointer passed to the callback function. \emph{(Optional)}}
|
||||
\cvarg{angle}{Specifies the field of view angle, in degrees, in the y direction.. \emph{(Optional - Default 45 degree)}}
|
||||
\cvarg{zmin}{Specifies the distance from the viewer to the near clipping plane (always positive). \emph{(Optional - Default 0.01)}}
|
||||
\cvarg{zmax}{Specifies the distance from the viewer to the far clipping plane (always positive). \emph{(Optional - Default 1000)}}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvCreateOpenGLCallback} can be used to draw 3D data on the window. An example of callback could be:
|
||||
\begin{lstlisting}
|
||||
void on_opengl(void* param)
|
||||
{
|
||||
//draw scene here
|
||||
glLoadIdentity();
|
||||
|
||||
glTranslated(0.0, 0.0, -1.0);
|
||||
|
||||
glRotatef( 55, 1, 0, 0 );
|
||||
glRotatef( 45, 0, 1, 0 );
|
||||
glRotatef( 0, 0, 0, 1 );
|
||||
|
||||
static const int coords[6][4][3] = {
|
||||
{ { +1, -1, -1 }, { -1, -1, -1 }, { -1, +1, -1 }, { +1, +1, -1 } },
|
||||
{ { +1, +1, -1 }, { -1, +1, -1 }, { -1, +1, +1 }, { +1, +1, +1 } },
|
||||
{ { +1, -1, +1 }, { +1, -1, -1 }, { +1, +1, -1 }, { +1, +1, +1 } },
|
||||
{ { -1, -1, -1 }, { -1, -1, +1 }, { -1, +1, +1 }, { -1, +1, -1 } },
|
||||
{ { +1, -1, +1 }, { -1, -1, +1 }, { -1, -1, -1 }, { +1, -1, -1 } },
|
||||
{ { -1, -1, +1 }, { +1, -1, +1 }, { +1, +1, +1 }, { -1, +1, +1 } }
|
||||
};
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
glColor3ub( i*20, 100+i*10, i*42 );
|
||||
glBegin(GL_QUADS);
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
glVertex3d(0.2 * coords[i][j][0], 0.2 * coords[i][j][1], 0.2 * coords[i][j][2]);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{lstlisting}
|
||||
CV_EXTERN_C_FUNCPTR( *CvOpenGLCallback)(void* userdata));
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
%CVAPI(void) cvSaveWindowParameters(const char* name);
|
||||
\cvCPyFunc{SaveWindowParameters}
|
||||
Save parameters of the window \emph{window\_name}.
|
||||
\cvdefC{void cvSaveWindowParameters(const char* name);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvSaveWindowParameters} saves size, location, flags, trackbars' value, zoom and panning location of the window \emph{window\_name}
|
||||
|
||||
|
||||
%CVAPI(void) cvLoadWindowParameters(const char* name);
|
||||
\cvCPyFunc{LoadWindowParameters}
|
||||
Load parameters of the window \emph{window\_name}.
|
||||
\cvdefC{void cvLoadWindowParameters(const char* name);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvLoadWindowParameters} load size, location, flags, trackbars' value, zoom and panning location of the window \emph{window\_name}
|
||||
|
||||
|
||||
%CVAPI(int) cvCreateButton( const char* button_name CV_DEFAULT(NULL),CvButtonCallback on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(NULL) , int button_type CV_DEFAULT(CV_PUSH_BUTTON), int initial_button_state CV_DEFAULT(0));
|
||||
\cvCPyFunc{CreateButton}
|
||||
Create a callback function called to draw OpenGL on top the the image display by \emph{window\_name}.
|
||||
\cvdefC{cvCreateButton( const char* button\_name CV\_DEFAULT(NULL),CvButtonCallback on\_change CV\_DEFAULT(NULL), void* userdata CV\_DEFAULT(NULL) , int button\_type CV\_DEFAULT(CV\_PUSH\_BUTTON), int initial\_button\_state CV\_DEFAULT(0);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{ button\_name}{Name of the button \emph{( if NULL, the name will be "button <number of boutton>")}}
|
||||
\cvarg{on\_change}{
|
||||
Pointer to the function to be called every time the button changed its state.
|
||||
This function should be prototyped as \texttt{void Foo(int state,*void);}. \emph{state} is the current state of the button. It could be -1 for a push button, 0 or 1 for a check/radio box button.}
|
||||
\cvarg{userdata}{pointer passed to the callback function. \emph{(Optional)}}
|
||||
\end{description}
|
||||
|
||||
The \texttt{button\_type} parameter can be : \emph{(Optional -- Will be a push button by default.)
|
||||
\begin{description}
|
||||
\cvarg{CV\_PUSH\_BUTTON}{The button will be a push button.}
|
||||
\cvarg{CV\_CHECKBOX}{The button will be a checkbox button.}
|
||||
\cvarg{CV\_RADIOBOX}{The button will be a radiobox button. The radiobox on the same buttonbar (same line) are exclusive; one on can be select at the time.}
|
||||
\end{description}}
|
||||
\begin{description}
|
||||
\cvarg{initial\_button\_state}{Default state of the button. Use for checkbox and radiobox, its value could be 0 or 1. \emph{(Optional)}}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvCreateButton} attach button to the control panel. Each button is added to a buttonbar on the right of the last button.
|
||||
A new buttonbar is create if nothing was attached to the control panel before, or if the last element attached to the control panel was a trackbar.
|
||||
|
||||
Here are various example of \texttt{cvCreateButton} function call:
|
||||
\begin{lstlisting}
|
||||
cvCreateButton(NULL,callbackButton);//create a push button "button 0", that will call callbackButton.
|
||||
cvCreateButton("button2",callbackButton,NULL,CV\_CHECKBOX,0);
|
||||
cvCreateButton("button3",callbackButton,&value);
|
||||
cvCreateButton("button5",callbackButton1,NULL,CV\_RADIOBOX);
|
||||
cvCreateButton("button6",callbackButton2,NULL,CV\_PUSH\_BUTTON,1);
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{lstlisting}
|
||||
CV_EXTERN_C_FUNCPTR( *CvButtonCallback)(int state, void* userdata));
|
||||
\end{lstlisting}
|
||||
|
||||
\fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\ifCpp
|
||||
|
||||
|
||||
%CVAPI(void) cvSetWindowProperty(const char* name, int prop_id, double prop_value);
|
||||
\cvCppFunc{setWindowProperty}
|
||||
Change the parameters of the window dynamically.
|
||||
|
||||
\cvdefCpp{void setWindowProperty(const string\& name, int prop\_id, double prop\_value);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window.}
|
||||
\cvarg{prop\_id}{Window's property to edit. The operation flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_WND\_PROP\_FULLSCREEN}{Change if the window is fullscreen (\texttt{CV\_WINDOW\_NORMAL} or \texttt{CV\_WINDOW\_FULLSCREEN}).}
|
||||
\cvarg{CV\_WND\_PROP\_AUTOSIZE}{Change if the user can resize the window (texttt{CV\_WINDOW\_NORMAL} or \texttt{CV\_WINDOW\_AUTOSIZE}).}
|
||||
\cvarg{CV\_WND\_PROP\_ASPECTRATIO}{Change if the image's aspect ratio is preserved (texttt{CV\_WINDOW\_FREERATIO} or \texttt{CV\_WINDOW\_KEEPRATIO}).}
|
||||
\end{description}}
|
||||
\cvarg{prop\_value}{New value of the Window's property. The operation flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_WINDOW\_NORMAL}{Change the window in normal size, or allows the user to resize the window.}
|
||||
\cvarg{CV\_WINDOW\_AUTOSIZE}{The user cannot resize the window, the size is constrainted by the image displayed.}
|
||||
\cvarg{CV\_WINDOW\_FULLSCREEN}{Change the window to fullscreen.}
|
||||
\cvarg{CV\_WINDOW\_FREERATIO}{The image expends as much as it can (no ratio constraint)}
|
||||
\cvarg{CV\_WINDOW\_KEEPRATIO}{The ration image is respected.}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{ setWindowProperty} allows to change the window's properties.
|
||||
|
||||
|
||||
|
||||
%CVAPI(double) cvGetWindowProperty(const char* name, int prop_id);
|
||||
\cvCppFunc{getWindowProperty}
|
||||
Get the parameters of the window.
|
||||
|
||||
\cvdefCpp{void getWindowProperty(const char* name, int prop\_id);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window.}
|
||||
\cvarg{prop\_id}{Window's property to retrive. The operation flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_WND\_PROP\_FULLSCREEN}{Change if the window is fullscreen (\texttt{CV\_WINDOW\_NORMAL} or \texttt{CV\_WINDOW\_FULLSCREEN}).}
|
||||
\cvarg{CV\_WND\_PROP\_AUTOSIZE}{Change if the user can resize the window (texttt{CV\_WINDOW\_NORMAL} or \texttt{CV\_WINDOW\_AUTOSIZE}).}
|
||||
\cvarg{CV\_WND\_PROP\_ASPECTRATIO}{Change if the image's aspect ratio is preserved (texttt{CV\_WINDOW\_FREERATIO} or \texttt{CV\_WINDOW\_KEEPRATIO}).}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
See \cross{setWindowProperty} to know the meaning of the returned values.
|
||||
|
||||
The function \texttt{ getWindowProperty} return window's properties.
|
||||
|
||||
|
||||
\cvCppFunc{fontQt}
|
||||
Create the font to be used to draw text on an image.
|
||||
|
||||
\cvdefCpp{CvFont fontQt(const string\& nameFont, int pointSize = -1, Scalar color = Scalar::all(0), int weight = CV\_FONT\_NORMAL, int style = CV\_STYLE\_NORMAL, int spacing = 0);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{nameFont}{Name of the font. The name should match the name of a system font (such as ``Times''). If the font is not found, a default one will be used.}
|
||||
\cvarg{pointSize}{Size of the font. If not specified, equal zero or negative, the point size of the font is set to a system-dependent default value. Generally, this is 12 points.}
|
||||
\cvarg{color}{Color of the font in BGRA -- A = 255 is fully transparent. Use the macro CV\_RGB for simplicity.}
|
||||
\cvarg{weight}{The operation flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_FONT\_LIGHT}{Weight of 25}
|
||||
\cvarg{CV\_FONT\_NORMAL}{Weight of 50}
|
||||
\cvarg{CV\_FONT\_DEMIBOLD}{Weight of 63}
|
||||
\cvarg{CV\_FONT\_BOLD}{Weight of 75}
|
||||
\cvarg{CV\_FONT\_BLACK}{Weight of 87}
|
||||
You can also specify a positive integer for more control.
|
||||
\end{description}}
|
||||
\cvarg{style}{The operation flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_STYLE\_NORMAL}{Font is normal}
|
||||
\cvarg{CV\_STYLE\_ITALIC}{Font is in italic}
|
||||
\cvarg{CV\_STYLE\_OBLIQUE}{Font is oblique}
|
||||
\end{description}}
|
||||
\cvarg{spacing}{Spacing between characters. Can be negative or positive}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{fontQt} creates a CvFont object. This CvFont is not compatible with putText.
|
||||
|
||||
A basic usage of this function is:
|
||||
\begin{lstlisting}
|
||||
CvFont font = fontQt(''Times'');
|
||||
addText( img1, ``Hello World !'', Point(50,50), font);
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{addText}
|
||||
Create the font to be used to draw text on an image
|
||||
\cvdefCpp{void addText(const Mat\& img, const string\& text, Point location, CvFont *font);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Image where the text should be drawn}
|
||||
\cvarg{text}{Text to write on the image}
|
||||
\cvarg{location}{Point(x,y) where the text should start on the image}
|
||||
\cvarg{font}{Font to use to draw the text}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{addText} draw \emph{text} on the image \emph{img} using a specific font \emph{font} (see example \cross{fontQt})
|
||||
|
||||
|
||||
%CVAPI(void) cvDisplayOverlay(const char* name, const char* text, int delay);
|
||||
\cvCppFunc{displayOverlay}
|
||||
Display text on the window's image as an overlay for delay milliseconds. This is not editing the image's data. The text is display on the top of the image.
|
||||
\cvdefCpp{void displayOverlay(const string\& name, const string\& text, int delay);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window}
|
||||
\cvarg{text}{Overlay text to write on the window's image}
|
||||
\cvarg{delay}{Delay to display the overlay text. If this function is called before the previous overlay text time out, the timer is restarted and the text updated. . If this value is zero, the text never disapers.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{displayOverlay} aims at displaying useful information/tips on the window for a certain amount of time \emph{delay}. This information is display on the top of the window.
|
||||
|
||||
|
||||
%CVAPI(void) cvDisplayStatusBar(const char* name, const char* text, int delayms);
|
||||
\cvCppFunc{displayStatusBar}
|
||||
Display text on the window's statusbar as for delay milliseconds.
|
||||
\cvdefCpp{void displayStatusBar(const string\& name, const string\& text, int delayms);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window}
|
||||
\cvarg{text}{Text to write on the window's statusbar}
|
||||
\cvarg{delay}{Delay to display the text. If this function is called before the previous text time out, the timer is restarted and the text updated. If this value is zero, the text never disapers.}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{displayOverlay} aims at displaying useful information/tips on the window for a certain amount of time \emph{delay}. This information is displayed on the window's statubar (the window must be created with \texttt{CV\_GUI\_EXPANDED} flags).
|
||||
|
||||
|
||||
|
||||
%CVAPI(void) cvCreateOpenGLCallback( const char* window_name, CvOpenGLCallback callbackOpenGL, void* userdata CV_DEFAULT(NULL), double angle CV_DEFAULT(-1), double zmin CV_DEFAULT(-1), double zmax CV_DEFAULT(-1));
|
||||
\cvCppFunc{createOpenGLCallback}
|
||||
Create a callback function called to draw OpenGL on top the the image display by \emph{window\_name}.
|
||||
\cvdefCpp{void createOpenGLCallback( const string\& window\_name, OpenGLCallback callbackOpenGL, void* userdata CV\_DEFAULT(NULL), double angle CV\_DEFAULT(-1), double zmin CV\_DEFAULT(-1), double zmax CV\_DEFAULT(-1);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{window\_name}{Name of the window}
|
||||
\cvarg{callbackOpenGL}{
|
||||
Pointer to the function to be called every frame.
|
||||
This function should be prototyped as \texttt{void Foo(*void);}.}
|
||||
\cvarg{userdata}{pointer passed to the callback function. \emph{(Optional)}}
|
||||
\cvarg{angle}{Specifies the field of view angle, in degrees, in the y direction.. \emph{(Optional - Default 45 degree)}}
|
||||
\cvarg{zmin}{Specifies the distance from the viewer to the near clipping plane (always positive). \emph{(Optional - Default 0.01)}}
|
||||
\cvarg{zmax}{Specifies the distance from the viewer to the far clipping plane (always positive). \emph{(Optional - Default 1000)}}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{createOpenGLCallback} can be used to draw 3D data on the window. An example of callback could be:
|
||||
\begin{lstlisting}
|
||||
void on_opengl(void* param)
|
||||
{
|
||||
glLoadIdentity();
|
||||
|
||||
glTranslated(0.0, 0.0, -1.0);
|
||||
|
||||
glRotatef( 55, 1, 0, 0 );
|
||||
glRotatef( 45, 0, 1, 0 );
|
||||
glRotatef( 0, 0, 0, 1 );
|
||||
|
||||
static const int coords[6][4][3] = {
|
||||
{ { +1, -1, -1 }, { -1, -1, -1 }, { -1, +1, -1 }, { +1, +1, -1 } },
|
||||
{ { +1, +1, -1 }, { -1, +1, -1 }, { -1, +1, +1 }, { +1, +1, +1 } },
|
||||
{ { +1, -1, +1 }, { +1, -1, -1 }, { +1, +1, -1 }, { +1, +1, +1 } },
|
||||
{ { -1, -1, -1 }, { -1, -1, +1 }, { -1, +1, +1 }, { -1, +1, -1 } },
|
||||
{ { +1, -1, +1 }, { -1, -1, +1 }, { -1, -1, -1 }, { +1, -1, -1 } },
|
||||
{ { -1, -1, +1 }, { +1, -1, +1 }, { +1, +1, +1 }, { -1, +1, +1 } }
|
||||
};
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
glColor3ub( i*20, 100+i*10, i*42 );
|
||||
glBegin(GL_QUADS);
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
glVertex3d(0.2 * coords[i][j][0], 0.2 * coords[i][j][1], 0.2 * coords[i][j][2]);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
%CVAPI(void) cvSaveWindowParameters(const char* name);
|
||||
\cvCppFunc{saveWindowParameters}
|
||||
Save parameters of the window \emph{window\_name}.
|
||||
\cvdefCpp{void saveWindowParameters(const string\& name);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{saveWindowParameters} saves size, location, flags, trackbars' value, zoom and panning location of the window \emph{window\_name}
|
||||
|
||||
|
||||
%CVAPI(void) cvLoadWindowParameters(const char* name);
|
||||
\cvCppFunc{loadWindowParameters}
|
||||
Load parameters of the window \emph{window\_name}.
|
||||
\cvdefCpp{void loadWindowParameters(const string\& name);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{name}{Name of the window}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{loadWindowParameters} load size, location, flags, trackbars' value, zoom and panning location of the window \emph{window\_name}
|
||||
|
||||
|
||||
%CVAPI(int) cvCreateButton( const char* button_name CV_DEFAULT(NULL),CvButtonCallback on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(NULL) , int button_type CV_DEFAULT(CV_PUSH_BUTTON), int initial_button_state CV_DEFAULT(0));
|
||||
\cvCppFunc{createButton}
|
||||
Create a callback function called to draw OpenGL on top the the image display by \emph{window\_name}.
|
||||
\cvdefCpp{createButton( const string\& button\_name CV\_DEFAULT(NULL),ButtonCallback on\_change CV\_DEFAULT(NULL), void* userdata CV\_DEFAULT(NULL) , int button\_type CV\_DEFAULT(CV\_PUSH\_BUTTON), int initial\_button\_state CV\_DEFAULT(0);}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{ button\_name}{Name of the button \emph{( if NULL, the name will be "button <number of boutton>")}}
|
||||
\cvarg{on\_change}{
|
||||
Pointer to the function to be called every time the button changed its state.
|
||||
This function should be prototyped as \texttt{void Foo(int state,*void);}. \emph{state} is the current state of the button. It could be -1 for a push button, 0 or 1 for a check/radio box button.}
|
||||
\cvarg{userdata}{pointer passed to the callback function. \emph{(Optional)}}
|
||||
\end{description}
|
||||
|
||||
The \texttt{button\_type} parameter can be : \emph{(Optional -- Will be a push button by default.)
|
||||
\begin{description}
|
||||
\cvarg{CV\_PUSH\_BUTTON}{The button will be a push button.}
|
||||
\cvarg{CV\_CHECKBOX}{The button will be a checkbox button.}
|
||||
\cvarg{CV\_RADIOBOX}{The button will be a radiobox button. The radiobox on the same buttonbar (same line) are exclusive; one on can be select at the time.}
|
||||
\end{description}}
|
||||
\begin{description}
|
||||
\cvarg{initial\_button\_state}{Default state of the button. Use for checkbox and radiobox, its value could be 0 or 1. \emph{(Optional)}}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{createButton} attach a button to the control panel. Each button is added to a buttonbar on the right of the last button.
|
||||
A new buttonbar is create if nothing was attached to the control panel before, or if the last element attached to the control panel was a trackbar.
|
||||
|
||||
Here are various example of \texttt{createButton} function call:
|
||||
\begin{lstlisting}
|
||||
createButton(NULL,callbackButton);//create a push button "button 0", that will call callbackButton.
|
||||
createButton("button2",callbackButton,NULL,CV\_CHECKBOX,0);
|
||||
createButton("button3",callbackButton,&value);
|
||||
createButton("button5",callbackButton1,NULL,CV\_RADIOBOX);
|
||||
createButton("button6",callbackButton2,NULL,CV\_PUSH\_BUTTON,1);
|
||||
\end{lstlisting}
|
||||
|
||||
\fi
|
@ -1,773 +0,0 @@
|
||||
%[TODO: from Feature Detection]
|
||||
\section{Feature Detection}
|
||||
|
||||
\ifCPy
|
||||
|
||||
\cvCPyFunc{Canny}
|
||||
Implements the Canny algorithm for edge detection.
|
||||
|
||||
\cvdefC{
|
||||
void cvCanny(\par const CvArr* image,
|
||||
\par CvArr* edges,
|
||||
\par double threshold1,
|
||||
\par double threshold2,
|
||||
\par int aperture\_size=3 );
|
||||
}\cvdefPy{Canny(image,edges,threshold1,threshold2,aperture\_size=3)-> None}
|
||||
\begin{description}
|
||||
\cvarg{image}{Single-channel input image}
|
||||
\cvarg{edges}{Single-channel image to store the edges found by the function}
|
||||
\cvarg{threshold1}{The first threshold}
|
||||
\cvarg{threshold2}{The second threshold}
|
||||
\cvarg{aperture\_size}{Aperture parameter for the Sobel operator (see \cvCPyCross{Sobel})}
|
||||
\end{description}
|
||||
|
||||
The function finds the edges on the input image \texttt{image} and marks them in the output image \texttt{edges} using the Canny algorithm. The smallest value between \texttt{threshold1} and \texttt{threshold2} is used for edge linking, the largest value is used to find the initial segments of strong edges.
|
||||
|
||||
\cvCPyFunc{CornerEigenValsAndVecs}
|
||||
Calculates eigenvalues and eigenvectors of image blocks for corner detection.
|
||||
|
||||
\cvdefC{
|
||||
void cvCornerEigenValsAndVecs( \par const CvArr* image,\par CvArr* eigenvv,\par int blockSize,\par int aperture\_size=3 );
|
||||
|
||||
}\cvdefPy{CornerEigenValsAndVecs(image,eigenvv,blockSize,aperture\_size=3)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Input image}
|
||||
\cvarg{eigenvv}{Image to store the results. It must be 6 times wider than the input image}
|
||||
\cvarg{blockSize}{Neighborhood size (see discussion)}
|
||||
\cvarg{aperture\_size}{Aperture parameter for the Sobel operator (see \cvCPyCross{Sobel})}
|
||||
\end{description}
|
||||
|
||||
For every pixel, the function \texttt{cvCornerEigenValsAndVecs} considers a $\texttt{blockSize} \times \texttt{blockSize}$ neigborhood S(p). It calcualtes the covariation matrix of derivatives over the neigborhood as:
|
||||
|
||||
\[
|
||||
M = \begin{bmatrix}
|
||||
\sum_{S(p)}(dI/dx)^2 & \sum_{S(p)}(dI/dx \cdot dI/dy)^2 \\
|
||||
\sum_{S(p)}(dI/dx \cdot dI/dy)^2 & \sum_{S(p)}(dI/dy)^2
|
||||
\end{bmatrix}
|
||||
\]
|
||||
|
||||
After that it finds eigenvectors and eigenvalues of the matrix and stores them into destination image in form
|
||||
$(\lambda_1, \lambda_2, x_1, y_1, x_2, y_2)$ where
|
||||
\begin{description}
|
||||
\item[$\lambda_1, \lambda_2$]are the eigenvalues of $M$; not sorted
|
||||
\item[$x_1, y_1$]are the eigenvectors corresponding to $\lambda_1$
|
||||
\item[$x_2, y_2$]are the eigenvectors corresponding to $\lambda_2$
|
||||
\end{description}
|
||||
|
||||
\cvCPyFunc{CornerHarris}
|
||||
Harris edge detector.
|
||||
|
||||
\cvdefC{
|
||||
void cvCornerHarris(
|
||||
\par const CvArr* image,
|
||||
\par CvArr* harris\_dst,
|
||||
\par int blockSize,
|
||||
\par int aperture\_size=3,
|
||||
\par double k=0.04 );
|
||||
}
|
||||
\cvdefPy{CornerHarris(image,harris\_dst,blockSize,aperture\_size=3,k=0.04)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Input image}
|
||||
\cvarg{harris\_dst}{Image to store the Harris detector responses. Should have the same size as \texttt{image}}
|
||||
\cvarg{blockSize}{Neighborhood size (see the discussion of \cvCPyCross{CornerEigenValsAndVecs})}
|
||||
\cvarg{aperture\_size}{Aperture parameter for the Sobel operator (see \cvCPyCross{Sobel}).}
|
||||
% format. In the case of floating-point input format this parameter is the number of the fixed float filter used for differencing
|
||||
\cvarg{k}{Harris detector free parameter. See the formula below}
|
||||
\end{description}
|
||||
|
||||
The function runs the Harris edge detector on the image. Similarly to \cvCPyCross{CornerMinEigenVal} and \cvCPyCross{CornerEigenValsAndVecs}, for each pixel it calculates a $2\times2$ gradient covariation matrix $M$ over a $\texttt{blockSize} \times \texttt{blockSize}$ neighborhood. Then, it stores
|
||||
|
||||
\[
|
||||
det(M) - k \, trace(M)^2
|
||||
\]
|
||||
|
||||
to the destination image. Corners in the image can be found as the local maxima of the destination image.
|
||||
|
||||
\cvCPyFunc{CornerMinEigenVal}
|
||||
Calculates the minimal eigenvalue of gradient matrices for corner detection.
|
||||
|
||||
\cvdefC{
|
||||
void cvCornerMinEigenVal(
|
||||
\par const CvArr* image,
|
||||
\par CvArr* eigenval,
|
||||
\par int blockSize,
|
||||
\par int aperture\_size=3 );
|
||||
}\cvdefPy{CornerMinEigenVal(image,eigenval,blockSize,aperture\_size=3)-> None}
|
||||
\begin{description}
|
||||
\cvarg{image}{Input image}
|
||||
\cvarg{eigenval}{Image to store the minimal eigenvalues. Should have the same size as \texttt{image}}
|
||||
\cvarg{blockSize}{Neighborhood size (see the discussion of \cvCPyCross{CornerEigenValsAndVecs})}
|
||||
\cvarg{aperture\_size}{Aperture parameter for the Sobel operator (see \cvCPyCross{Sobel}).}
|
||||
% format. In the case of floating-point input format this parameter is the number of the fixed float filter used for differencing
|
||||
\end{description}
|
||||
|
||||
The function is similar to \cvCPyCross{CornerEigenValsAndVecs} but it calculates and stores only the minimal eigen value of derivative covariation matrix for every pixel, i.e. $min(\lambda_1, \lambda_2)$ in terms of the previous function.
|
||||
|
||||
\cvCPyFunc{FindCornerSubPix}
|
||||
Refines the corner locations.
|
||||
|
||||
\cvdefC{
|
||||
void cvFindCornerSubPix(
|
||||
\par const CvArr* image,
|
||||
\par CvPoint2D32f* corners,
|
||||
\par int count,
|
||||
\par CvSize win,
|
||||
\par CvSize zero\_zone,
|
||||
\par CvTermCriteria criteria );
|
||||
}\cvdefPy{FindCornerSubPix(image,corners,win,zero\_zone,criteria)-> corners}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Input image}
|
||||
\ifC
|
||||
\cvarg{corners}{Initial coordinates of the input corners; refined coordinates on output}
|
||||
\cvarg{count}{Number of corners}
|
||||
\fi
|
||||
\ifPy
|
||||
\cvarg{corners}{Initial coordinates of the input corners as a list of (x, y) pairs}
|
||||
\fi
|
||||
\cvarg{win}{Half of the side length of the search window. For example, if \texttt{win}=(5,5), then a $5*2+1 \times 5*2+1 = 11 \times 11$ search window would be used}
|
||||
\cvarg{zero\_zone}{Half of the size of the dead region in the middle of the search zone over which the summation in the formula below is not done. It is used sometimes to avoid possible singularities of the autocorrelation matrix. The value of (-1,-1) indicates that there is no such size}
|
||||
\cvarg{criteria}{Criteria for termination of the iterative process of corner refinement. That is, the process of corner position refinement stops either after a certain number of iterations or when a required accuracy is achieved. The \texttt{criteria} may specify either of or both the maximum number of iteration and the required accuracy}
|
||||
\end{description}
|
||||
|
||||
The function iterates to find the sub-pixel accurate location of corners, or radial saddle points, as shown in on the picture below.
|
||||
\ifPy
|
||||
It returns the refined coordinates as a list of (x, y) pairs.
|
||||
\fi
|
||||
|
||||
\includegraphics[width=1.0\textwidth]{pics/cornersubpix.png}
|
||||
|
||||
Sub-pixel accurate corner locator is based on the observation that every vector from the center $q$ to a point $p$ located within a neighborhood of $q$ is orthogonal to the image gradient at $p$ subject to image and measurement noise. Consider the expression:
|
||||
|
||||
\[
|
||||
\epsilon_i = {DI_{p_i}}^T \cdot (q - p_i)
|
||||
\]
|
||||
|
||||
where ${DI_{p_i}}$ is the image gradient at the one of the points $p_i$ in a neighborhood of $q$. The value of $q$ is to be found such that $\epsilon_i$ is minimized. A system of equations may be set up with $\epsilon_i$ set to zero:
|
||||
|
||||
\[
|
||||
\sum_i(DI_{p_i} \cdot {DI_{p_i}}^T) q = \sum_i(DI_{p_i} \cdot {DI_{p_i}}^T \cdot p_i)
|
||||
\]
|
||||
|
||||
where the gradients are summed within a neighborhood ("search window") of $q$. Calling the first gradient term $G$ and the second gradient term $b$ gives:
|
||||
|
||||
\[
|
||||
q = G^{-1} \cdot b
|
||||
\]
|
||||
|
||||
The algorithm sets the center of the neighborhood window at this new center $q$ and then iterates until the center keeps within a set threshold.
|
||||
|
||||
\cvCPyFunc{GoodFeaturesToTrack}
|
||||
Determines strong corners on an image.
|
||||
|
||||
\cvdefC{
|
||||
void cvGoodFeaturesToTrack(
|
||||
\par const CvArr* image
|
||||
\par CvArr* eigImage, CvArr* tempImage
|
||||
\par CvPoint2D32f* corners
|
||||
\par int* cornerCount
|
||||
\par double qualityLevel
|
||||
\par double minDistance
|
||||
\par const CvArr* mask=NULL
|
||||
\par int blockSize=3
|
||||
\par int useHarris=0
|
||||
\par double k=0.04 );
|
||||
}
|
||||
\cvdefPy{GoodFeaturesToTrack(image,eigImage,tempImage,cornerCount,qualityLevel,minDistance,mask=NULL,blockSize=3,useHarris=0,k=0.04)-> corners}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{The source 8-bit or floating-point 32-bit, single-channel image}
|
||||
\cvarg{eigImage}{Temporary floating-point 32-bit image, the same size as \texttt{image}}
|
||||
\cvarg{tempImage}{Another temporary image, the same size and format as \texttt{eigImage}}
|
||||
\ifC
|
||||
\cvarg{corners}{Output parameter; detected corners}
|
||||
\cvarg{cornerCount}{Output parameter; number of detected corners}
|
||||
\else
|
||||
\cvarg{cornerCount}{number of corners to detect}
|
||||
\fi
|
||||
\cvarg{qualityLevel}{Multiplier for the max/min eigenvalue; specifies the minimal accepted quality of image corners}
|
||||
\cvarg{minDistance}{Limit, specifying the minimum possible distance between the returned corners; Euclidian distance is used}
|
||||
\cvarg{mask}{Region of interest. The function selects points either in the specified region or in the whole image if the mask is NULL}
|
||||
\cvarg{blockSize}{Size of the averaging block, passed to the underlying \cvCPyCross{CornerMinEigenVal} or \cvCPyCross{CornerHarris} used by the function}
|
||||
\cvarg{useHarris}{If nonzero, Harris operator (\cvCPyCross{CornerHarris}) is used instead of default \cvCPyCross{CornerMinEigenVal}}
|
||||
\cvarg{k}{Free parameter of Harris detector; used only if ($\texttt{useHarris} != 0$)}
|
||||
\end{description}
|
||||
|
||||
The function finds the corners with big eigenvalues in the image. The function first calculates the minimal
|
||||
eigenvalue for every source image pixel using the \cvCPyCross{CornerMinEigenVal}
|
||||
function and stores them in \texttt{eigImage}. Then it performs
|
||||
non-maxima suppression (only the local maxima in $3\times 3$ neighborhood
|
||||
are retained). The next step rejects the corners with the minimal
|
||||
eigenvalue less than $\texttt{qualityLevel} \cdot max(\texttt{eigImage}(x,y))$.
|
||||
Finally, the function ensures that the distance between any two corners is not smaller than \texttt{minDistance}. The weaker corners (with a smaller min eigenvalue) that are too close to the stronger corners are rejected.
|
||||
|
||||
Note that the if the function is called with different values \texttt{A} and \texttt{B} of the parameter \texttt{qualityLevel}, and \texttt{A} > {B}, the array of returned corners with \texttt{qualityLevel=A} will be the prefix of the output corners array with \texttt{qualityLevel=B}.
|
||||
|
||||
\cvCPyFunc{HoughLines2}
|
||||
Finds lines in a binary image using a Hough transform.
|
||||
|
||||
\cvdefC{
|
||||
CvSeq* cvHoughLines2( \par CvArr* image,\par void* storage,\par int method,\par double rho,\par double theta,\par int threshold,\par double param1=0,\par double param2=0 );
|
||||
}
|
||||
\cvdefPy{HoughLines2(image,storage,method,rho,theta,threshold,param1=0,param2=0)-> lines}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{The 8-bit, single-channel, binary source image. In the case of a probabilistic method, the image is modified by the function}
|
||||
\cvarg{storage}{The storage for the lines that are detected. It can
|
||||
be a memory storage (in this case a sequence of lines is created in
|
||||
the storage and returned by the function) or single row/single column
|
||||
matrix (CvMat*) of a particular type (see below) to which the lines'
|
||||
parameters are written. The matrix header is modified by the function
|
||||
so its \texttt{cols} or \texttt{rows} will contain the number of lines
|
||||
detected. If \texttt{storage} is a matrix and the actual number
|
||||
of lines exceeds the matrix size, the maximum possible number of lines
|
||||
is returned (in the case of standard hough transform the lines are sorted
|
||||
by the accumulator value)}
|
||||
\cvarg{method}{The Hough transform variant, one of the following:
|
||||
\begin{description}
|
||||
\cvarg{CV\_HOUGH\_STANDARD}{classical or standard Hough transform. Every line is represented by two floating-point numbers $(\rho, \theta)$, where $\rho$ is a distance between (0,0) point and the line, and $\theta$ is the angle between x-axis and the normal to the line. Thus, the matrix must be (the created sequence will be) of \texttt{CV\_32FC2} type}
|
||||
\cvarg{CV\_HOUGH\_PROBABILISTIC}{probabilistic Hough transform (more efficient in case if picture contains a few long linear segments). It returns line segments rather than the whole line. Each segment is represented by starting and ending points, and the matrix must be (the created sequence will be) of \texttt{CV\_32SC4} type}
|
||||
\cvarg{CV\_HOUGH\_MULTI\_SCALE}{multi-scale variant of the classical Hough transform. The lines are encoded the same way as \texttt{CV\_HOUGH\_STANDARD}}
|
||||
\end{description}}
|
||||
\cvarg{rho}{Distance resolution in pixel-related units}
|
||||
\cvarg{theta}{Angle resolution measured in radians}
|
||||
\cvarg{threshold}{Threshold parameter. A line is returned by the function if the corresponding accumulator value is greater than \texttt{threshold}}
|
||||
\cvarg{param1}{The first method-dependent parameter:
|
||||
\begin{itemize}
|
||||
\item For the classical Hough transform it is not used (0).
|
||||
\item For the probabilistic Hough transform it is the minimum line length.
|
||||
\item For the multi-scale Hough transform it is the divisor for the distance resolution $\rho$. (The coarse distance resolution will be $\rho$ and the accurate resolution will be $(\rho / \texttt{param1})$).
|
||||
\end{itemize}}
|
||||
\cvarg{param2}{The second method-dependent parameter:
|
||||
\begin{itemize}
|
||||
\item For the classical Hough transform it is not used (0).
|
||||
\item For the probabilistic Hough transform it is the maximum gap between line segments lying on the same line to treat them as a single line segment (i.e. to join them).
|
||||
\item For the multi-scale Hough transform it is the divisor for the angle resolution $\theta$. (The coarse angle resolution will be $\theta$ and the accurate resolution will be $(\theta / \texttt{param2})$).
|
||||
\end{itemize}}
|
||||
\end{description}
|
||||
|
||||
The function implements a few variants of the Hough transform for line detection.
|
||||
|
||||
\ifC
|
||||
\textbf{Example. Detecting lines with Hough transform.}
|
||||
\begin{lstlisting}
|
||||
/* This is a standalone program. Pass an image name as a first parameter
|
||||
of the program. Switch between standard and probabilistic Hough transform
|
||||
by changing "#if 1" to "#if 0" and back */
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include <math.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
IplImage* src;
|
||||
if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0)
|
||||
{
|
||||
IplImage* dst = cvCreateImage( cvGetSize(src), 8, 1 );
|
||||
IplImage* color_dst = cvCreateImage( cvGetSize(src), 8, 3 );
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
CvSeq* lines = 0;
|
||||
int i;
|
||||
cvCanny( src, dst, 50, 200, 3 );
|
||||
cvCvtColor( dst, color_dst, CV_GRAY2BGR );
|
||||
#if 1
|
||||
lines = cvHoughLines2( dst,
|
||||
storage,
|
||||
CV_HOUGH_STANDARD,
|
||||
1,
|
||||
CV_PI/180,
|
||||
100,
|
||||
0,
|
||||
0 );
|
||||
|
||||
for( i = 0; i < MIN(lines->total,100); i++ )
|
||||
{
|
||||
float* line = (float*)cvGetSeqElem(lines,i);
|
||||
float rho = line[0];
|
||||
float theta = line[1];
|
||||
CvPoint pt1, pt2;
|
||||
double a = cos(theta), b = sin(theta);
|
||||
double x0 = a*rho, y0 = b*rho;
|
||||
pt1.x = cvRound(x0 + 1000*(-b));
|
||||
pt1.y = cvRound(y0 + 1000*(a));
|
||||
pt2.x = cvRound(x0 - 1000*(-b));
|
||||
pt2.y = cvRound(y0 - 1000*(a));
|
||||
cvLine( color_dst, pt1, pt2, CV_RGB(255,0,0), 3, 8 );
|
||||
}
|
||||
#else
|
||||
lines = cvHoughLines2( dst,
|
||||
storage,
|
||||
CV_HOUGH_PROBABILISTIC,
|
||||
1,
|
||||
CV_PI/180,
|
||||
80,
|
||||
30,
|
||||
10 );
|
||||
for( i = 0; i < lines->total; i++ )
|
||||
{
|
||||
CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
|
||||
cvLine( color_dst, line[0], line[1], CV_RGB(255,0,0), 3, 8 );
|
||||
}
|
||||
#endif
|
||||
cvNamedWindow( "Source", 1 );
|
||||
cvShowImage( "Source", src );
|
||||
|
||||
cvNamedWindow( "Hough", 1 );
|
||||
cvShowImage( "Hough", color_dst );
|
||||
|
||||
cvWaitKey(0);
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
This is the sample picture the function parameters have been tuned for:
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/building.jpg}
|
||||
|
||||
And this is the output of the above program in the case of probabilistic Hough transform (\texttt{\#if 0} case):
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/houghp.png}
|
||||
\fi
|
||||
|
||||
|
||||
\cvCPyFunc{PreCornerDetect}
|
||||
Calculates the feature map for corner detection.
|
||||
|
||||
\cvdefC{
|
||||
void cvPreCornerDetect(
|
||||
\par const CvArr* image,
|
||||
\par CvArr* corners,
|
||||
\par int apertureSize=3 );
|
||||
}
|
||||
\cvdefPy{PreCornerDetect(image,corners,apertureSize=3)-> None}
|
||||
\begin{description}
|
||||
\cvarg{image}{Input image}
|
||||
\cvarg{corners}{Image to store the corner candidates}
|
||||
\cvarg{apertureSize}{Aperture parameter for the Sobel operator (see \cvCPyCross{Sobel})}
|
||||
\end{description}
|
||||
|
||||
The function calculates the function
|
||||
|
||||
\[
|
||||
D_x^2 D_{yy} + D_y^2 D_{xx} - 2 D_x D_y D_{xy}
|
||||
\]
|
||||
|
||||
where $D_?$ denotes one of the first image derivatives and $D_{??}$ denotes a second image derivative.
|
||||
|
||||
The corners can be found as local maximums of the function below:
|
||||
|
||||
\ifC
|
||||
\begin{lstlisting}
|
||||
// assume that the image is floating-point
|
||||
IplImage* corners = cvCloneImage(image);
|
||||
IplImage* dilated_corners = cvCloneImage(image);
|
||||
IplImage* corner_mask = cvCreateImage( cvGetSize(image), 8, 1 );
|
||||
cvPreCornerDetect( image, corners, 3 );
|
||||
cvDilate( corners, dilated_corners, 0, 1 );
|
||||
cvSubS( corners, dilated_corners, corners );
|
||||
cvCmpS( corners, 0, corner_mask, CV_CMP_GE );
|
||||
cvReleaseImage( &corners );
|
||||
cvReleaseImage( &dilated_corners );
|
||||
\end{lstlisting}
|
||||
|
||||
\else
|
||||
\lstinputlisting{python_fragments/precornerdetect.py}
|
||||
\fi
|
||||
|
||||
\ifC
|
||||
\cvCPyFunc{SampleLine}
|
||||
Reads the raster line to the buffer.
|
||||
|
||||
\cvdefC{
|
||||
int cvSampleLine(
|
||||
\par const CvArr* image
|
||||
\par CvPoint pt1
|
||||
\par CvPoint pt2
|
||||
\par void* buffer
|
||||
\par int connectivity=8 );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Image to sample the line from}
|
||||
\cvarg{pt1}{Starting line point}
|
||||
\cvarg{pt2}{Ending line point}
|
||||
\cvarg{buffer}{Buffer to store the line points; must have enough size to store
|
||||
$max( |\texttt{pt2.x} - \texttt{pt1.x}|+1, |\texttt{pt2.y} - \texttt{pt1.y}|+1 )$
|
||||
points in the case of an 8-connected line and
|
||||
$ (|\texttt{pt2.x}-\texttt{pt1.x}|+|\texttt{pt2.y}-\texttt{pt1.y}|+1) $
|
||||
in the case of a 4-connected line}
|
||||
\cvarg{connectivity}{The line connectivity, 4 or 8}
|
||||
\end{description}
|
||||
|
||||
The function implements a particular application of line iterators. The function reads all of the image points lying on the line between \texttt{pt1} and \texttt{pt2}, including the end points, and stores them into the buffer.
|
||||
|
||||
\fi
|
||||
|
||||
\fi
|
||||
|
||||
|
||||
\ifCpp
|
||||
|
||||
\cvCppFunc{Canny}
|
||||
Finds edges in an image using Canny algorithm.
|
||||
|
||||
\cvdefCpp{void Canny( const Mat\& image, Mat\& edges,\par
|
||||
double threshold1, double threshold2,\par
|
||||
int apertureSize=3, bool L2gradient=false );}
|
||||
\begin{description}
|
||||
\cvarg{image}{Single-channel 8-bit input image}
|
||||
\cvarg{edges}{The output edge map. It will have the same size and the same type as \texttt{image}}
|
||||
\cvarg{threshold1}{The first threshold for the hysteresis procedure}
|
||||
\cvarg{threshold2}{The second threshold for the hysteresis procedure}
|
||||
\cvarg{apertureSize}{Aperture size for the \cvCppCross{Sobel} operator}
|
||||
\cvarg{L2gradient}{Indicates, whether the more accurate $L_2$ norm $=\sqrt{(dI/dx)^2 + (dI/dy)^2}$ should be used to compute the image gradient magnitude (\texttt{L2gradient=true}), or a faster default $L_1$ norm $=|dI/dx|+|dI/dy|$ is enough (\texttt{L2gradient=false})}
|
||||
\end{description}
|
||||
|
||||
The function finds edges in the input image \texttt{image} and marks them in the output map \texttt{edges} using the Canny algorithm. The smallest value between \texttt{threshold1} and \texttt{threshold2} is used for edge linking, the largest value is used to find the initial segments of strong edges, see
|
||||
\url{http://en.wikipedia.org/wiki/Canny_edge_detector}
|
||||
|
||||
\cvCppFunc{cornerEigenValsAndVecs}
|
||||
Calculates eigenvalues and eigenvectors of image blocks for corner detection.
|
||||
|
||||
\cvdefCpp{void cornerEigenValsAndVecs( const Mat\& src, Mat\& dst,\par
|
||||
int blockSize, int apertureSize,\par
|
||||
int borderType=BORDER\_DEFAULT );}
|
||||
\begin{description}
|
||||
\cvarg{src}{Input single-channel 8-bit or floating-point image}
|
||||
\cvarg{dst}{Image to store the results. It will have the same size as \texttt{src} and the type \texttt{CV\_32FC(6)}}
|
||||
\cvarg{blockSize}{Neighborhood size (see discussion)}
|
||||
\cvarg{apertureSize}{Aperture parameter for the \cvCppCross{Sobel} operator}
|
||||
\cvarg{boderType}{Pixel extrapolation method; see \cvCppCross{borderInterpolate}}
|
||||
\end{description}
|
||||
|
||||
For every pixel $p$, the function \texttt{cornerEigenValsAndVecs} considers a \texttt{blockSize} $\times$ \texttt{blockSize} neigborhood $S(p)$. It calculates the covariation matrix of derivatives over the neighborhood as:
|
||||
|
||||
\[
|
||||
M = \begin{bmatrix}
|
||||
\sum_{S(p)}(dI/dx)^2 & \sum_{S(p)}(dI/dx dI/dy)^2 \\
|
||||
\sum_{S(p)}(dI/dx dI/dy)^2 & \sum_{S(p)}(dI/dy)^2
|
||||
\end{bmatrix}
|
||||
\]
|
||||
|
||||
Where the derivatives are computed using \cvCppCross{Sobel} operator.
|
||||
|
||||
After that it finds eigenvectors and eigenvalues of $M$ and stores them into destination image in the form
|
||||
$(\lambda_1, \lambda_2, x_1, y_1, x_2, y_2)$ where
|
||||
\begin{description}
|
||||
\item[$\lambda_1, \lambda_2$]are the eigenvalues of $M$; not sorted
|
||||
\item[$x_1, y_1$]are the eigenvectors corresponding to $\lambda_1$
|
||||
\item[$x_2, y_2$]are the eigenvectors corresponding to $\lambda_2$
|
||||
\end{description}
|
||||
|
||||
The output of the function can be used for robust edge or corner detection.
|
||||
|
||||
See also: \cvCppCross{cornerMinEigenVal}, \cvCppCross{cornerHarris}, \cvCppCross{preCornerDetect}
|
||||
|
||||
\cvCppFunc{cornerHarris}
|
||||
Harris edge detector.
|
||||
|
||||
\cvdefCpp{void cornerHarris( const Mat\& src, Mat\& dst, int blockSize,\par
|
||||
int apertureSize, double k,\par
|
||||
int borderType=BORDER\_DEFAULT );}
|
||||
\begin{description}
|
||||
\cvarg{src}{Input single-channel 8-bit or floating-point image}
|
||||
\cvarg{dst}{Image to store the Harris detector responses; will have type \texttt{CV\_32FC1} and the same size as \texttt{src}}
|
||||
\cvarg{blockSize}{Neighborhood size (see the discussion of \cvCppCross{cornerEigenValsAndVecs})}
|
||||
\cvarg{apertureSize}{Aperture parameter for the \cvCppCross{Sobel} operator}
|
||||
\cvarg{k}{Harris detector free parameter. See the formula below}
|
||||
\cvarg{boderType}{Pixel extrapolation method; see \cvCppCross{borderInterpolate}}
|
||||
\end{description}
|
||||
|
||||
The function runs the Harris edge detector on the image. Similarly to \cvCppCross{cornerMinEigenVal} and \cvCppCross{cornerEigenValsAndVecs}, for each pixel $(x, y)$ it calculates a $2\times2$ gradient covariation matrix $M^{(x,y)}$ over a $\texttt{blockSize} \times \texttt{blockSize}$ neighborhood. Then, it computes the following characteristic:
|
||||
|
||||
\[
|
||||
\texttt{dst}(x,y) = \mathrm{det} M^{(x,y)} - k \cdot \left(\mathrm{tr} M^{(x,y)}\right)^2
|
||||
\]
|
||||
|
||||
Corners in the image can be found as the local maxima of this response map.
|
||||
|
||||
\cvCppFunc{cornerMinEigenVal}
|
||||
Calculates the minimal eigenvalue of gradient matrices for corner detection.
|
||||
|
||||
\cvdefCpp{void cornerMinEigenVal( const Mat\& src, Mat\& dst,\par
|
||||
int blockSize, int apertureSize=3,\par
|
||||
int borderType=BORDER\_DEFAULT );}
|
||||
\begin{description}
|
||||
\cvarg{src}{Input single-channel 8-bit or floating-point image}
|
||||
\cvarg{dst}{Image to store the minimal eigenvalues; will have type \texttt{CV\_32FC1} and the same size as \texttt{src}}
|
||||
\cvarg{blockSize}{Neighborhood size (see the discussion of \cvCppCross{cornerEigenValsAndVecs})}
|
||||
\cvarg{apertureSize}{Aperture parameter for the \cvCppCross{Sobel} operator}
|
||||
\cvarg{boderType}{Pixel extrapolation method; see \cvCppCross{borderInterpolate}}
|
||||
\end{description}
|
||||
|
||||
The function is similar to \cvCppCross{cornerEigenValsAndVecs} but it calculates and stores only the minimal eigenvalue of the covariation matrix of derivatives, i.e. $\min(\lambda_1, \lambda_2)$ in terms of the formulae in \cvCppCross{cornerEigenValsAndVecs} description.
|
||||
|
||||
\cvCppFunc{cornerSubPix}
|
||||
Refines the corner locations.
|
||||
|
||||
\cvdefCpp{void cornerSubPix( const Mat\& image, vector<Point2f>\& corners,\par
|
||||
Size winSize, Size zeroZone,\par
|
||||
TermCriteria criteria );}
|
||||
\begin{description}
|
||||
\cvarg{image}{Input image}
|
||||
\cvarg{corners}{Initial coordinates of the input corners; refined coordinates on output}
|
||||
\cvarg{winSize}{Half of the side length of the search window. For example, if \texttt{winSize=Size(5,5)}, then a $5*2+1 \times 5*2+1 = 11 \times 11$ search window would be used}
|
||||
\cvarg{zeroZone}{Half of the size of the dead region in the middle of the search zone over which the summation in the formula below is not done. It is used sometimes to avoid possible singularities of the autocorrelation matrix. The value of (-1,-1) indicates that there is no such size}
|
||||
\cvarg{criteria}{Criteria for termination of the iterative process of corner refinement. That is, the process of corner position refinement stops either after a certain number of iterations or when a required accuracy is achieved. The \texttt{criteria} may specify either of or both the maximum number of iteration and the required accuracy}
|
||||
\end{description}
|
||||
|
||||
The function iterates to find the sub-pixel accurate location of corners, or radial saddle points, as shown in on the picture below.
|
||||
|
||||
\includegraphics[width=1.0\textwidth]{pics/cornersubpix.png}
|
||||
|
||||
Sub-pixel accurate corner locator is based on the observation that every vector from the center $q$ to a point $p$ located within a neighborhood of $q$ is orthogonal to the image gradient at $p$ subject to image and measurement noise. Consider the expression:
|
||||
|
||||
\[
|
||||
\epsilon_i = {DI_{p_i}}^T \cdot (q - p_i)
|
||||
\]
|
||||
|
||||
where ${DI_{p_i}}$ is the image gradient at the one of the points $p_i$ in a neighborhood of $q$. The value of $q$ is to be found such that $\epsilon_i$ is minimized. A system of equations may be set up with $\epsilon_i$ set to zero:
|
||||
|
||||
\[
|
||||
\sum_i(DI_{p_i} \cdot {DI_{p_i}}^T) - \sum_i(DI_{p_i} \cdot {DI_{p_i}}^T \cdot p_i)
|
||||
\]
|
||||
|
||||
where the gradients are summed within a neighborhood ("search window") of $q$. Calling the first gradient term $G$ and the second gradient term $b$ gives:
|
||||
|
||||
\[
|
||||
q = G^{-1} \cdot b
|
||||
\]
|
||||
|
||||
The algorithm sets the center of the neighborhood window at this new center $q$ and then iterates until the center keeps within a set threshold.
|
||||
|
||||
|
||||
\cvCppFunc{goodFeaturesToTrack}
|
||||
Determines strong corners on an image.
|
||||
|
||||
\cvdefCpp{void goodFeaturesToTrack( const Mat\& image, vector<Point2f>\& corners,\par
|
||||
int maxCorners, double qualityLevel, double minDistance,\par
|
||||
const Mat\& mask=Mat(), int blockSize=3,\par
|
||||
bool useHarrisDetector=false, double k=0.04 );}
|
||||
\begin{description}
|
||||
\cvarg{image}{The input 8-bit or floating-point 32-bit, single-channel image}
|
||||
\cvarg{corners}{The output vector of detected corners}
|
||||
\cvarg{maxCorners}{The maximum number of corners to return. If there are more corners than that will be found, the strongest of them will be returned}
|
||||
\cvarg{qualityLevel}{Characterizes the minimal accepted quality of image corners; the value of the parameter is multiplied by the by the best corner quality measure (which is the min eigenvalue, see \cvCppCross{cornerMinEigenVal}, or the Harris function response, see \cvCppCross{cornerHarris}). The corners, which quality measure is less than the product, will be rejected. For example, if the best corner has the quality measure = 1500, and the \texttt{qualityLevel=0.01}, then all the corners which quality measure is less than 15 will be rejected.}
|
||||
\cvarg{minDistance}{The minimum possible Euclidean distance between the returned corners}
|
||||
\cvarg{mask}{The optional region of interest. If the image is not empty (then it needs to have the type \texttt{CV\_8UC1} and the same size as \texttt{image}), it will specify the region in which the corners are detected}
|
||||
\cvarg{blockSize}{Size of the averaging block for computing derivative covariation matrix over each pixel neighborhood, see \cvCppCross{cornerEigenValsAndVecs}}
|
||||
\cvarg{useHarrisDetector}{Indicates, whether to use \hyperref[cornerHarris]{Harris} operator or \cvCppCross{cornerMinEigenVal}}
|
||||
\cvarg{k}{Free parameter of Harris detector}
|
||||
\end{description}
|
||||
|
||||
The function finds the most prominent corners in the image or in the specified image region, as described
|
||||
in \cite{Shi94}:
|
||||
\begin{enumerate}
|
||||
\item the function first calculates the corner quality measure at every source image pixel using the \cvCppCross{cornerMinEigenVal} or \cvCppCross{cornerHarris}
|
||||
\item then it performs non-maxima suppression (the local maxima in $3\times 3$ neighborhood
|
||||
are retained).
|
||||
\item the next step rejects the corners with the minimal eigenvalue less than $\texttt{qualityLevel} \cdot \max_{x,y} qualityMeasureMap(x,y)$.
|
||||
\item the remaining corners are then sorted by the quality measure in the descending order.
|
||||
\item finally, the function throws away each corner $pt_j$ if there is a stronger corner $pt_i$ ($i < j$) such that the distance between them is less than \texttt{minDistance}
|
||||
\end{enumerate}
|
||||
|
||||
The function can be used to initialize a point-based tracker of an object.
|
||||
|
||||
Note that the if the function is called with different values \texttt{A} and \texttt{B} of the parameter \texttt{qualityLevel}, and \texttt{A} > {B}, the vector of returned corners with \texttt{qualityLevel=A} will be the prefix of the output vector with \texttt{qualityLevel=B}.
|
||||
|
||||
See also: \cvCppCross{cornerMinEigenVal}, \cvCppCross{cornerHarris}, \cvCppCross{calcOpticalFlowPyrLK}, \cvCppCross{estimateRigidMotion}, \cvCppCross{PlanarObjectDetector}, \cvCppCross{OneWayDescriptor}
|
||||
|
||||
\cvCppFunc{HoughCircles}
|
||||
Finds circles in a grayscale image using a Hough transform.
|
||||
|
||||
\cvdefCpp{void HoughCircles( Mat\& image, vector<Vec3f>\& circles,\par
|
||||
int method, double dp, double minDist,\par
|
||||
double param1=100, double param2=100,\par
|
||||
int minRadius=0, int maxRadius=0 );}
|
||||
\begin{description}
|
||||
\cvarg{image}{The 8-bit, single-channel, grayscale input image}
|
||||
\cvarg{circles}{The output vector of found circles. Each vector is encoded as 3-element floating-point vector $(x, y, radius)$}
|
||||
\cvarg{method}{Currently, the only implemented method is \texttt{CV\_HOUGH\_GRADIENT}, which is basically \emph{21HT}, described in \cite{Yuen90}.}
|
||||
\cvarg{dp}{The inverse ratio of the accumulator resolution to the image resolution. For example, if \texttt{dp=1}, the accumulator will have the same resolution as the input image, if \texttt{dp=2} - accumulator will have half as big width and height, etc}
|
||||
\cvarg{minDist}{Minimum distance between the centers of the detected circles. If the parameter is too small, multiple neighbor circles may be falsely detected in addition to a true one. If it is too large, some circles may be missed}
|
||||
\cvarg{param1}{The first method-specific parameter. in the case of \texttt{CV\_HOUGH\_GRADIENT} it is the higher threshold of the two passed to \cvCppCross{Canny} edge detector (the lower one will be twice smaller)}
|
||||
\cvarg{param2}{The second method-specific parameter. in the case of \texttt{CV\_HOUGH\_GRADIENT} it is the accumulator threshold at the center detection stage. The smaller it is, the more false circles may be detected. Circles, corresponding to the larger accumulator values, will be returned first}
|
||||
\cvarg{minRadius}{Minimum circle radius}
|
||||
\cvarg{maxRadius}{Maximum circle radius}
|
||||
\end{description}
|
||||
|
||||
The function finds circles in a grayscale image using some modification of Hough transform. Here is a short usage example:
|
||||
|
||||
\begin{lstlisting}
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include <math.h>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Mat img, gray;
|
||||
if( argc != 2 && !(img=imread(argv[1], 1)).data)
|
||||
return -1;
|
||||
cvtColor(img, gray, CV_BGR2GRAY);
|
||||
// smooth it, otherwise a lot of false circles may be detected
|
||||
GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
|
||||
vector<Vec3f> circles;
|
||||
HoughCircles(gray, circles, CV_HOUGH_GRADIENT,
|
||||
2, gray->rows/4, 200, 100 );
|
||||
for( size_t i = 0; i < circles.size(); i++ )
|
||||
{
|
||||
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
|
||||
int radius = cvRound(circles[i][2]);
|
||||
// draw the circle center
|
||||
circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
|
||||
// draw the circle outline
|
||||
circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
|
||||
}
|
||||
namedWindow( "circles", 1 );
|
||||
imshow( "circles", img );
|
||||
return 0;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
Note that usually the function detects the circles' centers well, however it may fail to find the correct radii. You can assist the function by specifying the radius range (\texttt{minRadius} and \texttt{maxRadius}) if you know it, or you may ignore the returned radius, use only the center and find the correct radius using some additional procedure.
|
||||
|
||||
See also: \cvCppCross{fitEllipse}, \cvCppCross{minEnclosingCircle}
|
||||
|
||||
\cvCppFunc{HoughLines}
|
||||
Finds lines in a binary image using standard Hough transform.
|
||||
|
||||
\cvdefCpp{void HoughLines( Mat\& image, vector<Vec2f>\& lines,\par
|
||||
double rho, double theta, int threshold,\par
|
||||
double srn=0, double stn=0 );}
|
||||
\begin{description}
|
||||
\cvarg{image}{The 8-bit, single-channel, binary source image. The image may be modified by the function}
|
||||
\cvarg{lines}{The output vector of lines. Each line is represented by a two-element vector $(\rho, \theta)$. $\rho$ is the distance from the coordinate origin $(0,0)$ (top-left corner of the image) and $\theta$ is the line rotation angle in radians ($0 \sim \textrm{vertical line}, \pi/2 \sim \textrm{horizontal line}$)}
|
||||
\cvarg{rho}{Distance resolution of the accumulator in pixels}
|
||||
\cvarg{theta}{Angle resolution of the accumulator in radians}
|
||||
\cvarg{threshold}{The accumulator threshold parameter. Only those lines are returned that get enough votes ($>\texttt{threshold}$)}
|
||||
\cvarg{srn}{For the multi-scale Hough transform it is the divisor for the distance resolution \texttt{rho}. The coarse accumulator distance resolution will be \texttt{rho} and the accurate accumulator resolution will be \texttt{rho/srn}. If both \texttt{srn=0} and \texttt{stn=0} then the classical Hough transform is used, otherwise both these parameters should be positive.}
|
||||
\cvarg{stn}{For the multi-scale Hough transform it is the divisor for the distance resolution \texttt{theta}}
|
||||
\end{description}
|
||||
|
||||
The function implements standard or standard multi-scale Hough transform algorithm for line detection. See \cvCppCross{HoughLinesP} for the code example.
|
||||
|
||||
|
||||
\cvCppFunc{HoughLinesP}
|
||||
Finds lines segments in a binary image using probabilistic Hough transform.
|
||||
|
||||
\cvdefCpp{void HoughLinesP( Mat\& image, vector<Vec4i>\& lines,\par
|
||||
double rho, double theta, int threshold,\par
|
||||
double minLineLength=0, double maxLineGap=0 );}
|
||||
\begin{description}
|
||||
\cvarg{image}{The 8-bit, single-channel, binary source image. The image may be modified by the function}
|
||||
\cvarg{lines}{The output vector of lines. Each line is represented by a 4-element vector $(x_1, y_1, x_2, y_2)$, where $(x_1,y_1)$ and $(x_2, y_2)$ are the ending points of each line segment detected.}
|
||||
\cvarg{rho}{Distance resolution of the accumulator in pixels}
|
||||
\cvarg{theta}{Angle resolution of the accumulator in radians}
|
||||
\cvarg{threshold}{The accumulator threshold parameter. Only those lines are returned that get enough votes ($>\texttt{threshold}$)}
|
||||
\cvarg{minLineLength}{The minimum line length. Line segments shorter than that will be rejected}
|
||||
\cvarg{maxLineGap}{The maximum allowed gap between points on the same line to link them.}
|
||||
\end{description}
|
||||
|
||||
The function implements probabilistic Hough transform algorithm for line detection, described in \cite{Matas00}. Below is line detection example:
|
||||
|
||||
\begin{lstlisting}
|
||||
/* This is a standalone program. Pass an image name as a first parameter
|
||||
of the program. Switch between standard and probabilistic Hough transform
|
||||
by changing "#if 1" to "#if 0" and back */
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
#include <math.h>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Mat src, dst, color_dst;
|
||||
if( argc != 2 || !(src=imread(argv[1], 0)).data)
|
||||
return -1;
|
||||
|
||||
Canny( src, dst, 50, 200, 3 );
|
||||
cvtColor( dst, color_dst, CV_GRAY2BGR );
|
||||
|
||||
#if 0
|
||||
vector<Vec2f> lines;
|
||||
HoughLines( dst, lines, 1, CV_PI/180, 100 );
|
||||
|
||||
for( size_t i = 0; i < lines.size(); i++ )
|
||||
{
|
||||
float rho = lines[i][0];
|
||||
float theta = lines[i][1];
|
||||
double a = cos(theta), b = sin(theta);
|
||||
double x0 = a*rho, y0 = b*rho;
|
||||
Point pt1(cvRound(x0 + 1000*(-b)),
|
||||
cvRound(y0 + 1000*(a)));
|
||||
Point pt2(cvRound(x0 - 1000*(-b)),
|
||||
cvRound(y0 - 1000*(a)));
|
||||
line( color_dst, pt1, pt2, Scalar(0,0,255), 3, 8 );
|
||||
}
|
||||
#else
|
||||
vector<Vec4i> lines;
|
||||
HoughLinesP( dst, lines, 1, CV_PI/180, 80, 30, 10 );
|
||||
for( size_t i = 0; i < lines.size(); i++ )
|
||||
{
|
||||
line( color_dst, Point(lines[i][0], lines[i][1]),
|
||||
Point(lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8 );
|
||||
}
|
||||
#endif
|
||||
namedWindow( "Source", 1 );
|
||||
imshow( "Source", src );
|
||||
|
||||
namedWindow( "Detected Lines", 1 );
|
||||
imshow( "Detected Lines", color_dst );
|
||||
|
||||
waitKey(0);
|
||||
return 0;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
This is the sample picture the function parameters have been tuned for:
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/building.jpg}
|
||||
|
||||
And this is the output of the above program in the case of probabilistic Hough transform
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/houghp.png}
|
||||
|
||||
\cvCppFunc{preCornerDetect}
|
||||
Calculates the feature map for corner detection
|
||||
|
||||
\cvdefCpp{void preCornerDetect( const Mat\& src, Mat\& dst, int apertureSize,\par
|
||||
int borderType=BORDER\_DEFAULT );}
|
||||
\begin{description}
|
||||
\cvarg{src}{The source single-channel 8-bit of floating-point image}
|
||||
\cvarg{dst}{The output image; will have type \texttt{CV\_32F} and the same size as \texttt{src}}
|
||||
\cvarg{apertureSize}{Aperture size of \cvCppCross{Sobel}}
|
||||
\cvarg{borderType}{The pixel extrapolation method; see \cvCppCross{borderInterpolate}}
|
||||
\end{description}
|
||||
|
||||
The function calculates the complex spatial derivative-based function of the source image
|
||||
|
||||
\[
|
||||
\texttt{dst} = (D_x \texttt{src})^2 \cdot D_{yy} \texttt{src} + (D_y \texttt{src})^2 \cdot D_{xx} \texttt{src} - 2 D_x \texttt{src} \cdot D_y \texttt{src} \cdot D_{xy} \texttt{src}
|
||||
\]
|
||||
|
||||
where $D_x$, $D_y$ are the first image derivatives, $D_{xx}$, $D_{yy}$ are the second image derivatives and $D_{xy}$ is the mixed derivative.
|
||||
|
||||
The corners can be found as local maximums of the functions, as shown below:
|
||||
|
||||
\begin{lstlisting}
|
||||
Mat corners, dilated_corners;
|
||||
preCornerDetect(image, corners, 3);
|
||||
// dilation with 3x3 rectangular structuring element
|
||||
dilate(corners, dilated_corners, Mat(), 1);
|
||||
Mat corner_mask = corners == dilated_corners;
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
|
||||
\fi
|
@ -1,731 +0,0 @@
|
||||
\section{Histograms}
|
||||
|
||||
\ifCPy
|
||||
|
||||
\cvclass{CvHistogram}\label{CvHistogram}
|
||||
Multi-dimensional histogram.
|
||||
|
||||
\ifC
|
||||
\begin{lstlisting}
|
||||
typedef struct CvHistogram
|
||||
{
|
||||
int type;
|
||||
CvArr* bins;
|
||||
float thresh[CV_MAX_DIM][2]; /* for uniform histograms */
|
||||
float** thresh2; /* for non-uniform histograms */
|
||||
CvMatND mat; /* embedded matrix header for array histograms */
|
||||
}
|
||||
CvHistogram;
|
||||
\end{lstlisting}
|
||||
\fi
|
||||
|
||||
\ifPy
|
||||
A CvHistogram is a multi-dimensional histogram, created by function \cross{CreateHist}. It has an attribute \texttt{bins} a \cross{CvMatND} containing the histogram counts.
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{CalcBackProject}
|
||||
Calculates the back projection.
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcBackProject( \par IplImage** image,\par CvArr* back\_project,\par const CvHistogram* hist );
|
||||
}\cvdefPy{CalcBackProject(image,back\_project,hist)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Source images (though you may pass CvMat** as well)}
|
||||
\cvarg{back\_project}{Destination back projection image of the same type as the source images}
|
||||
\cvarg{hist}{Histogram}
|
||||
\end{description}
|
||||
|
||||
The function calculates the back project of the histogram. For each
|
||||
tuple of pixels at the same position of all input single-channel images
|
||||
the function puts the value of the histogram bin, corresponding to the
|
||||
tuple in the destination image. In terms of statistics, the value of
|
||||
each output image pixel is the probability of the observed tuple given
|
||||
the distribution (histogram). For example, to find a red object in the
|
||||
picture, one may do the following:
|
||||
|
||||
\begin{enumerate}
|
||||
\item Calculate a hue histogram for the red object assuming the image contains only this object. The histogram is likely to have a strong maximum, corresponding to red color.
|
||||
\item Calculate back projection of a hue plane of input image where the object is searched, using the histogram. Threshold the image.
|
||||
\item Find connected components in the resulting picture and choose the right component using some additional criteria, for example, the largest connected component.
|
||||
\end{enumerate}
|
||||
|
||||
That is the approximate algorithm of Camshift color object tracker, except for the 3rd step, instead of which CAMSHIFT algorithm is used to locate the object on the back projection given the previous object position.
|
||||
|
||||
\cvCPyFunc{CalcBackProjectPatch}
|
||||
Locates a template within an image by using a histogram comparison.
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcBackProjectPatch( \par IplImage** images,\par CvArr* dst,\par CvSize patch\_size,\par CvHistogram* hist,\par int method,\par double factor );
|
||||
}
|
||||
\cvdefPy{CalcBackProjectPatch(images,dst,patch\_size,hist,method,factor)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{images}{Source images (though, you may pass CvMat** as well)}
|
||||
\cvarg{dst}{Destination image}
|
||||
\cvarg{patch\_size}{Size of the patch slid though the source image}
|
||||
\cvarg{hist}{Histogram}
|
||||
\cvarg{method}{Comparison method, passed to \cvCPyCross{CompareHist} (see description of that function)}
|
||||
\cvarg{factor}{Normalization factor for histograms, will affect the normalization scale of the destination image, pass 1 if unsure}
|
||||
\end{description}
|
||||
|
||||
The function calculates the back projection by comparing histograms of the source image patches with the given histogram. Taking measurement results from some image at each location over ROI creates an array \texttt{image}. These results might be one or more of hue, \texttt{x} derivative, \texttt{y} derivative, Laplacian filter, oriented Gabor filter, etc. Each measurement output is collected into its own separate image. The \texttt{image} image array is a collection of these measurement images. A multi-dimensional histogram \texttt{hist} is constructed by sampling from the \texttt{image} image array. The final histogram is normalized. The \texttt{hist} histogram has as many dimensions as the number of elements in \texttt{image} array.
|
||||
|
||||
Each new image is measured and then converted into an \texttt{image} image array over a chosen ROI. Histograms are taken from this \texttt{image} image in an area covered by a "patch" with an anchor at center as shown in the picture below. The histogram is normalized using the parameter \texttt{norm\_factor} so that it may be compared with \texttt{hist}. The calculated histogram is compared to the model histogram; \texttt{hist} uses The function \texttt{cvCompareHist} with the comparison method=\texttt{method}). The resulting output is placed at the location corresponding to the patch anchor in the probability image \texttt{dst}. This process is repeated as the patch is slid over the ROI. Iterative histogram update by subtracting trailing pixels covered by the patch and adding newly covered pixels to the histogram can save a lot of operations, though it is not implemented yet.
|
||||
|
||||
Back Project Calculation by Patches
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/backprojectpatch.png}
|
||||
|
||||
\cvCPyFunc{CalcHist}
|
||||
Calculates the histogram of image(s).
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcHist( \par IplImage** image,\par CvHistogram* hist,\par int accumulate=0,\par const CvArr* mask=NULL );
|
||||
}
|
||||
\cvdefPy{CalcHist(image,hist,accumulate=0,mask=NULL)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Source images (though you may pass CvMat** as well)}
|
||||
\cvarg{hist}{Pointer to the histogram}
|
||||
\cvarg{accumulate}{Accumulation flag. If it is set, the histogram is not cleared in the beginning. This feature allows user to compute a single histogram from several images, or to update the histogram online}
|
||||
\cvarg{mask}{The operation mask, determines what pixels of the source images are counted}
|
||||
\end{description}
|
||||
|
||||
The function calculates the histogram of one or more
|
||||
single-channel images. The elements of a tuple that is used to increment
|
||||
a histogram bin are taken at the same location from the corresponding
|
||||
input images.
|
||||
|
||||
\ifC % {
|
||||
% ===== Sample. Calculating and displaying 2D Hue-Saturation histogram of a color image =====
|
||||
\begin{lstlisting}
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
IplImage* src;
|
||||
if( argc == 2 && (src=cvLoadImage(argv[1], 1))!= 0)
|
||||
{
|
||||
IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 );
|
||||
IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 );
|
||||
IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 );
|
||||
IplImage* planes[] = { h_plane, s_plane };
|
||||
IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 );
|
||||
int h_bins = 30, s_bins = 32;
|
||||
int hist_size[] = {h_bins, s_bins};
|
||||
/* hue varies from 0 (~0 deg red) to 180 (~360 deg red again) */
|
||||
float h_ranges[] = { 0, 180 };
|
||||
/* saturation varies from 0 (black-gray-white) to
|
||||
255 (pure spectrum color) */
|
||||
float s_ranges[] = { 0, 255 };
|
||||
float* ranges[] = { h_ranges, s_ranges };
|
||||
int scale = 10;
|
||||
IplImage* hist_img =
|
||||
cvCreateImage( cvSize(h_bins*scale,s_bins*scale), 8, 3 );
|
||||
CvHistogram* hist;
|
||||
float max_value = 0;
|
||||
int h, s;
|
||||
|
||||
cvCvtColor( src, hsv, CV_BGR2HSV );
|
||||
cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );
|
||||
hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );
|
||||
cvCalcHist( planes, hist, 0, 0 );
|
||||
cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );
|
||||
cvZero( hist_img );
|
||||
|
||||
for( h = 0; h < h_bins; h++ )
|
||||
{
|
||||
for( s = 0; s < s_bins; s++ )
|
||||
{
|
||||
float bin_val = cvQueryHistValue\_2D( hist, h, s );
|
||||
int intensity = cvRound(bin_val*255/max_value);
|
||||
cvRectangle( hist_img, cvPoint( h*scale, s*scale ),
|
||||
cvPoint( (h+1)*scale - 1, (s+1)*scale - 1),
|
||||
CV_RGB(intensity,intensity,intensity),
|
||||
CV_FILLED );
|
||||
}
|
||||
}
|
||||
|
||||
cvNamedWindow( "Source", 1 );
|
||||
cvShowImage( "Source", src );
|
||||
|
||||
cvNamedWindow( "H-S Histogram", 1 );
|
||||
cvShowImage( "H-S Histogram", hist_img );
|
||||
|
||||
cvWaitKey(0);
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
\else % }{
|
||||
\lstinputlisting{python_fragments/calchist.py}
|
||||
\fi % }
|
||||
|
||||
\cvCPyFunc{CalcProbDensity}
|
||||
Divides one histogram by another.
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcProbDensity( \par const CvHistogram* hist1,\par const CvHistogram* hist2,\par CvHistogram* dst\_hist,\par double scale=255 );
|
||||
}
|
||||
\cvdefPy{CalcProbDensity(hist1,hist2,dst\_hist,scale=255)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist1}{first histogram (the divisor)}
|
||||
\cvarg{hist2}{second histogram}
|
||||
\cvarg{dst\_hist}{destination histogram}
|
||||
\cvarg{scale}{scale factor for the destination histogram}
|
||||
\end{description}
|
||||
|
||||
The function calculates the object probability density from the two histograms as:
|
||||
|
||||
\[
|
||||
\texttt{dist\_hist}(I)=
|
||||
\forkthree
|
||||
{0}{if $\texttt{hist1}(I)=0$}
|
||||
{\texttt{scale}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) > \texttt{hist1}(I)$}
|
||||
{\frac{\texttt{hist2}(I) \cdot \texttt{scale}}{\texttt{hist1}(I)}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) \le \texttt{hist1}(I)$}
|
||||
\]
|
||||
|
||||
So the destination histogram bins are within less than \texttt{scale}.
|
||||
|
||||
\cvCPyFunc{ClearHist}
|
||||
Clears the histogram.
|
||||
|
||||
\cvdefC{
|
||||
void cvClearHist( CvHistogram* hist );
|
||||
}\cvdefPy{ClearHist(hist)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Histogram}
|
||||
\end{description}
|
||||
|
||||
The function sets all of the histogram bins to 0 in the case of a dense histogram and removes all histogram bins in the case of a sparse array.
|
||||
|
||||
\cvCPyFunc{CompareHist}
|
||||
Compares two dense histograms.
|
||||
|
||||
\cvdefC{
|
||||
double cvCompareHist( \par const CvHistogram* hist1,\par const CvHistogram* hist2,\par int method );
|
||||
}\cvdefPy{CompareHist(hist1,hist2,method)->float}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist1}{The first dense histogram}
|
||||
\cvarg{hist2}{The second dense histogram}
|
||||
\cvarg{method}{Comparison method, one of the following:
|
||||
\begin{description}
|
||||
\cvarg{CV\_COMP\_CORREL}{Correlation}
|
||||
\cvarg{CV\_COMP\_CHISQR}{Chi-Square}
|
||||
\cvarg{CV\_COMP\_INTERSECT}{Intersection}
|
||||
\cvarg{CV\_COMP\_BHATTACHARYYA}{Bhattacharyya distance}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
The function compares two dense histograms using the specified method ($H_1$ denotes the first histogram, $H_2$ the second):
|
||||
|
||||
\begin{description}
|
||||
\item[Correlation (method=CV\_COMP\_CORREL)]
|
||||
\[
|
||||
d(H_1,H_2) = \frac
|
||||
{\sum_I (H'_1(I) \cdot H'_2(I))}
|
||||
{\sqrt{\sum_I(H'_1(I)^2) \cdot \sum_I(H'_2(I)^2)}}
|
||||
\]
|
||||
where
|
||||
\[
|
||||
H'_k(I) = \frac{H_k(I) - 1}{N \cdot \sum_J H_k(J)}
|
||||
\]
|
||||
where N is the number of histogram bins.
|
||||
|
||||
\item[Chi-Square (method=CV\_COMP\_CHISQR)]
|
||||
\[ d(H_1,H_2) = \sum_I \frac{(H_1(I)-H_2(I))^2}{H_1(I)+H_2(I)} \]
|
||||
|
||||
\item[Intersection (method=CV\_COMP\_INTERSECT)]
|
||||
\[ d(H_1,H_2) = \sum_I \min (H_1(I), H_2(I)) \]
|
||||
|
||||
\item[Bhattacharyya distance (method=CV\_COMP\_BHATTACHARYYA)]
|
||||
\[ d(H_1,H_2) = \sqrt{1 - \sum_I \frac{\sqrt{H_1(I) \cdot H_2(I)}}{ \sqrt{ \sum_I H_1(I) \cdot \sum_I H_2(I) }}} \]
|
||||
|
||||
\end{description}
|
||||
|
||||
The function returns $d(H_1, H_2)$.
|
||||
|
||||
Note: the method \texttt{CV\_COMP\_BHATTACHARYYA} only works with normalized histograms.
|
||||
|
||||
To compare a sparse histogram or more general sparse configurations of weighted points, consider using the \cvCPyCross{CalcEMD2} function.
|
||||
|
||||
\ifC
|
||||
\cvCPyFunc{CopyHist}
|
||||
Copies a histogram.
|
||||
|
||||
\cvdefC{
|
||||
void cvCopyHist( const CvHistogram* src, CvHistogram** dst );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source histogram}
|
||||
\cvarg{dst}{Pointer to destination histogram}
|
||||
\end{description}
|
||||
|
||||
The function makes a copy of the histogram. If the
|
||||
second histogram pointer \texttt{*dst} is NULL, a new histogram of the
|
||||
same size as \texttt{src} is created. Otherwise, both histograms must
|
||||
have equal types and sizes. Then the function copies the source histogram's
|
||||
bin values to the destination histogram and sets the same bin value ranges
|
||||
as in \texttt{src}.
|
||||
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{CreateHist}
|
||||
Creates a histogram.
|
||||
|
||||
\cvdefC{
|
||||
CvHistogram* cvCreateHist(\par int dims,\par int* sizes,\par int type,\par float** ranges=NULL,\par int uniform=1 );
|
||||
}\cvdefPy{CreateHist(dims, type, ranges, uniform = 1) -> hist}
|
||||
|
||||
\begin{description}
|
||||
\cvC{\cvarg{dims}{Number of histogram dimensions}
|
||||
\cvarg{sizes}{Array of the histogram dimension sizes}}
|
||||
\cvPy{\cvarg{dims}{for an N-dimensional histogram, list of length N giving the size of each dimension}}
|
||||
\cvarg{type}{Histogram representation format: \texttt{CV\_HIST\_ARRAY} means that the histogram data is represented as a multi-dimensional dense array CvMatND; \texttt{CV\_HIST\_SPARSE} means that histogram data is represented as a multi-dimensional sparse array CvSparseMat}
|
||||
\cvarg{ranges}{Array of ranges for the histogram bins. Its meaning depends on the \texttt{uniform} parameter value. The ranges are used for when the histogram is calculated or backprojected to determine which histogram bin corresponds to which value/tuple of values from the input image(s)}
|
||||
\cvarg{uniform}{Uniformity flag; if not 0, the histogram has evenly
|
||||
spaced bins and for every $0<=i<cDims$ \texttt{ranges[i]}
|
||||
is an array of two numbers: lower and upper boundaries for the i-th
|
||||
histogram dimension.
|
||||
The whole range [lower,upper] is then split
|
||||
into \texttt{dims[i]} equal parts to determine the \texttt{i-th} input
|
||||
tuple value ranges for every histogram bin. And if \texttt{uniform=0},
|
||||
then \texttt{i-th} element of \texttt{ranges} array contains
|
||||
\texttt{dims[i]+1} elements:
|
||||
$\texttt{lower}_0, \texttt{upper}_0,
|
||||
\texttt{lower}_1, \texttt{upper}_1 = \texttt{lower}_2,
|
||||
...
|
||||
\texttt{upper}_{dims[i]-1} $
|
||||
where
|
||||
$\texttt{lower}_j$ and $\texttt{upper}_j$
|
||||
are lower and upper
|
||||
boundaries of \texttt{i-th} input tuple value for \texttt{j-th}
|
||||
bin, respectively. In either case, the input values that are beyond
|
||||
the specified range for a histogram bin are not counted by
|
||||
\cvCPyCross{CalcHist} and filled with 0 by \cvCPyCross{CalcBackProject}}
|
||||
\end{description}
|
||||
|
||||
The function creates a histogram of the specified
|
||||
size and returns a pointer to the created histogram. If the array
|
||||
\texttt{ranges} is 0, the histogram bin ranges must be specified later
|
||||
via the function \cvCPyCross{SetHistBinRanges}. Though \cvCPyCross{CalcHist}
|
||||
and \cvCPyCross{CalcBackProject} may process 8-bit images without setting
|
||||
bin ranges, they assume thy are equally spaced in 0 to 255 bins.
|
||||
|
||||
\ifC % {
|
||||
\cvCPyFunc{GetHistValue*D}
|
||||
Returns a pointer to the histogram bin.
|
||||
|
||||
\cvdefC{float cvGetHistValue\_1D(hist, idx0) \newline
|
||||
float cvGetHistValue\_2D(hist, idx0, idx1) \newline
|
||||
float cvGetHistValue\_3D(hist, idx0, idx1, idx2) \newline
|
||||
float cvGetHistValue\_nD(hist, idx) \newline
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Histogram}
|
||||
\cvarg{idx0, idx1, idx2, idx3}{Indices of the bin}
|
||||
\cvarg{idx}{Array of indices}
|
||||
\end{description}
|
||||
|
||||
\begin{lstlisting}
|
||||
#define cvGetHistValue_1D( hist, idx0 )
|
||||
((float*)(cvPtr1D( (hist)->bins, (idx0), 0 ))
|
||||
#define cvGetHistValue_2D( hist, idx0, idx1 )
|
||||
((float*)(cvPtr2D( (hist)->bins, (idx0), (idx1), 0 )))
|
||||
#define cvGetHistValue_3D( hist, idx0, idx1, idx2 )
|
||||
((float*)(cvPtr3D( (hist)->bins, (idx0), (idx1), (idx2), 0 )))
|
||||
#define cvGetHistValue_nD( hist, idx )
|
||||
((float*)(cvPtrND( (hist)->bins, (idx), 0 )))
|
||||
\end{lstlisting}
|
||||
|
||||
The macros \texttt{GetHistValue} return a pointer to the specified bin of the 1D, 2D, 3D or N-D histogram. In the case of a sparse histogram the function creates a new bin and sets it to 0, unless it exists already.
|
||||
\fi % }
|
||||
|
||||
\cvCPyFunc{GetMinMaxHistValue}
|
||||
Finds the minimum and maximum histogram bins.
|
||||
|
||||
\cvdefC{
|
||||
void cvGetMinMaxHistValue( \par const CvHistogram* hist,\par float* min\_value,\par float* max\_value,\par int* min\_idx=NULL,\par int* max\_idx=NULL );
|
||||
|
||||
}
|
||||
\cvdefPy{GetMinMaxHistValue(hist)-> (min\_value,max\_value,min\_idx,max\_idx)}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Histogram}
|
||||
\ifC
|
||||
\cvarg{min\_value}{Pointer to the minimum value of the histogram}
|
||||
\cvarg{max\_value}{Pointer to the maximum value of the histogram}
|
||||
\cvarg{min\_idx}{Pointer to the array of coordinates for the minimum}
|
||||
\cvarg{max\_idx}{Pointer to the array of coordinates for the maximum}
|
||||
\else
|
||||
\cvarg{min\_value}{Minimum value of the histogram}
|
||||
\cvarg{max\_value}{Maximum value of the histogram}
|
||||
\cvarg{min\_idx}{Coordinates of the minimum}
|
||||
\cvarg{max\_idx}{Coordinates of the maximum}
|
||||
\fi
|
||||
|
||||
\end{description}
|
||||
|
||||
The function finds the minimum and
|
||||
maximum histogram bins and their positions. All of output arguments are
|
||||
optional. Among several extremas with the same value the ones with the
|
||||
minimum index (in lexicographical order) are returned. In the case of several maximums
|
||||
or minimums, the earliest in lexicographical order (extrema locations)
|
||||
is returned.
|
||||
|
||||
\ifC % {
|
||||
\cvCPyFunc{MakeHistHeaderForArray}
|
||||
Makes a histogram out of an array.
|
||||
|
||||
\cvdefC{
|
||||
CvHistogram* cvMakeHistHeaderForArray( \par int dims,\par int* sizes,\par CvHistogram* hist,\par float* data,\par float** ranges=NULL,\par int uniform=1 );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{dims}{Number of histogram dimensions}
|
||||
\cvarg{sizes}{Array of the histogram dimension sizes}
|
||||
\cvarg{hist}{The histogram header initialized by the function}
|
||||
\cvarg{data}{Array that will be used to store histogram bins}
|
||||
\cvarg{ranges}{Histogram bin ranges, see \cvCPyCross{CreateHist}}
|
||||
\cvarg{uniform}{Uniformity flag, see \cvCPyCross{CreateHist}}
|
||||
\end{description}
|
||||
|
||||
The function initializes the histogram, whose header and bins are allocated by th user. \cvCPyCross{ReleaseHist} does not need to be called afterwards. Only dense histograms can be initialized this way. The function returns \texttt{hist}.
|
||||
\fi % }
|
||||
|
||||
\cvCPyFunc{NormalizeHist}
|
||||
Normalizes the histogram.
|
||||
|
||||
\cvdefC{
|
||||
void cvNormalizeHist( CvHistogram* hist, double factor );
|
||||
}\cvdefPy{NormalizeHist(hist,factor)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Pointer to the histogram}
|
||||
\cvarg{factor}{Normalization factor}
|
||||
\end{description}
|
||||
|
||||
The function normalizes the histogram bins by scaling them, such that the sum of the bins becomes equal to \texttt{factor}.
|
||||
|
||||
\ifC
|
||||
\cvCPyFunc{QueryHistValue*D}
|
||||
Queries the value of the histogram bin.
|
||||
|
||||
\cvdefC{float QueryHistValue\_1D(CvHistogram hist, int idx0)}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Histogram}
|
||||
\cvarg{idx0, idx1, idx2, idx3}{Indices of the bin}
|
||||
\cvarg{idx}{Array of indices}
|
||||
\end{description}
|
||||
|
||||
\begin{lstlisting}
|
||||
#define cvQueryHistValue\_1D( hist, idx0 ) \
|
||||
cvGetReal1D( (hist)->bins, (idx0) )
|
||||
#define cvQueryHistValue\_2D( hist, idx0, idx1 ) \
|
||||
cvGetReal2D( (hist)->bins, (idx0), (idx1) )
|
||||
#define cvQueryHistValue\_3D( hist, idx0, idx1, idx2 ) \
|
||||
cvGetReal3D( (hist)->bins, (idx0), (idx1), (idx2) )
|
||||
#define cvQueryHistValue\_nD( hist, idx ) \
|
||||
cvGetRealND( (hist)->bins, (idx) )
|
||||
\end{lstlisting}
|
||||
|
||||
The macros return the value of the specified bin of the 1D, 2D, 3D or N-D histogram. In the case of a sparse histogram the function returns 0, if the bin is not present in the histogram no new bin is created.
|
||||
\else
|
||||
|
||||
\cvfunc{QueryHistValue\_1D}
|
||||
Returns the value from a 1D histogram bin.
|
||||
|
||||
\cvdefPy{QueryHistValue\_1D(hist, idx0) -> float}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Histogram}
|
||||
\cvarg{idx0}{bin index 0}
|
||||
\end{description}
|
||||
|
||||
\cvfunc{QueryHistValue\_2D}
|
||||
Returns the value from a 2D histogram bin.
|
||||
|
||||
\cvdefPy{QueryHistValue\_2D(hist, idx0, idx1) -> float}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Histogram}
|
||||
\cvarg{idx0}{bin index 0}
|
||||
\cvarg{idx1}{bin index 1}
|
||||
\end{description}
|
||||
|
||||
\cvfunc{QueryHistValue\_3D}
|
||||
Returns the value from a 3D histogram bin.
|
||||
|
||||
\cvdefPy{QueryHistValue\_3D(hist, idx0, idx1, idx2) -> float}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Histogram}
|
||||
\cvarg{idx0}{bin index 0}
|
||||
\cvarg{idx1}{bin index 1}
|
||||
\cvarg{idx2}{bin index 2}
|
||||
\end{description}
|
||||
|
||||
\cvfunc{QueryHistValue\_nD}
|
||||
Returns the value from a 1D histogram bin.
|
||||
|
||||
\cvdefPy{QueryHistValue\_nD(hist, idx) -> float}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Histogram}
|
||||
\cvarg{idx}{list of indices, of same length as the dimension of the histogram's bin.}
|
||||
\end{description}
|
||||
|
||||
\fi
|
||||
|
||||
\ifC
|
||||
\cvCPyFunc{ReleaseHist}
|
||||
Releases the histogram.
|
||||
|
||||
\cvdefC{
|
||||
void cvReleaseHist( CvHistogram** hist );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Double pointer to the released histogram}
|
||||
\end{description}
|
||||
|
||||
The function releases the histogram (header and the data). The pointer to the histogram is cleared by the function. If \texttt{*hist} pointer is already \texttt{NULL}, the function does nothing.
|
||||
|
||||
\cvCPyFunc{SetHistBinRanges}
|
||||
Sets the bounds of the histogram bins.
|
||||
|
||||
\cvdefC{
|
||||
void cvSetHistBinRanges( \par CvHistogram* hist,\par float** ranges,\par int uniform=1 );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Histogram}
|
||||
\cvarg{ranges}{Array of bin ranges arrays, see \cvCPyCross{CreateHist}}
|
||||
\cvarg{uniform}{Uniformity flag, see \cvCPyCross{CreateHist}}
|
||||
\end{description}
|
||||
|
||||
The function is a stand-alone function for setting bin ranges in the histogram. For a more detailed description of the parameters \texttt{ranges} and \texttt{uniform} see the \cvCPyCross{CalcHist} function, that can initialize the ranges as well. Ranges for the histogram bins must be set before the histogram is calculated or the backproject of the histogram is calculated.
|
||||
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{ThreshHist}
|
||||
Thresholds the histogram.
|
||||
|
||||
\cvdefC{
|
||||
void cvThreshHist( CvHistogram* hist, double threshold );
|
||||
}
|
||||
\cvdefPy{ThreshHist(hist,threshold)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{hist}{Pointer to the histogram}
|
||||
\cvarg{threshold}{Threshold level}
|
||||
\end{description}
|
||||
|
||||
The function clears histogram bins that are below the specified threshold.
|
||||
|
||||
\fi
|
||||
|
||||
\ifCpp
|
||||
|
||||
\cvCppFunc{calcHist}
|
||||
Calculates histogram of a set of arrays
|
||||
|
||||
\cvdefCpp{void calcHist( const Mat* arrays, int narrays,\par
|
||||
const int* channels, const Mat\& mask,\par
|
||||
MatND\& hist, int dims, const int* histSize,\par
|
||||
const float** ranges, bool uniform=true,\par
|
||||
bool accumulate=false );\newline
|
||||
void calcHist( const Mat* arrays, int narrays,\par
|
||||
const int* channels, const Mat\& mask,\par
|
||||
SparseMat\& hist, int dims, const int* histSize,\par
|
||||
const float** ranges, bool uniform=true,\par
|
||||
bool accumulate=false );}
|
||||
\begin{description}
|
||||
\cvarg{arrays}{Source arrays. They all should have the same depth, \texttt{CV\_8U} or \texttt{CV\_32F}, and the same size. Each of them can have an arbitrary number of channels}
|
||||
\cvarg{narrays}{The number of source arrays}
|
||||
\cvarg{channels}{The list of \texttt{dims} channels that are used to compute the histogram. The first array channels are numerated from 0 to \texttt{arrays[0].channels()-1}, the second array channels are counted from \texttt{arrays[0].channels()} to \texttt{arrays[0].channels() + arrays[1].channels()-1} etc.}
|
||||
\cvarg{mask}{The optional mask. If the matrix is not empty, it must be 8-bit array of the same size as \texttt{arrays[i]}. The non-zero mask elements mark the array elements that are counted in the histogram}
|
||||
\cvarg{hist}{The output histogram, a dense or sparse \texttt{dims}-dimensional array}
|
||||
\cvarg{dims}{The histogram dimensionality; must be positive and not greater than \texttt{CV\_MAX\_DIMS}(=32 in the current OpenCV version)}
|
||||
\cvarg{histSize}{The array of histogram sizes in each dimension}
|
||||
\cvarg{ranges}{The array of \texttt{dims} arrays of the histogram bin boundaries in each dimension. When the histogram is uniform (\texttt{uniform}=true), then for each dimension \texttt{i} it's enough to specify the lower (inclusive) boundary $L_0$ of the 0-th histogram bin and the upper (exclusive) boundary $U_{\texttt{histSize}[i]-1}$ for the last histogram bin \texttt{histSize[i]-1}. That is, in the case of uniform histogram each of \texttt{ranges[i]} is an array of 2 elements. When the histogram is not uniform (\texttt{uniform=false}), then each of \texttt{ranges[i]} contains \texttt{histSize[i]+1} elements: $L_0, U_0=L_1, U_1=L_2, ..., U_{\texttt{histSize[i]}-2}=L_{\texttt{histSize[i]}-1}, U_{\texttt{histSize[i]}-1}$. The array elements, which are not between $L_0$ and $U_{\texttt{histSize[i]}-1}$, are not counted in the histogram}
|
||||
\cvarg{uniform}{Indicates whether the histogram is uniform or not, see above}
|
||||
\cvarg{accumulate}{Accumulation flag. If it is set, the histogram is not cleared in the beginning (when it is allocated). This feature allows user to compute a single histogram from several sets of arrays, or to update the histogram in time}
|
||||
\end{description}
|
||||
|
||||
The functions \texttt{calcHist} calculate the histogram of one or more
|
||||
arrays. The elements of a tuple that is used to increment
|
||||
a histogram bin are taken at the same location from the corresponding
|
||||
input arrays. The sample below shows how to compute 2D Hue-Saturation histogram for a color imag
|
||||
|
||||
\begin{lstlisting}
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
Mat src, hsv;
|
||||
if( argc != 2 || !(src=imread(argv[1], 1)).data )
|
||||
return -1;
|
||||
|
||||
cvtColor(src, hsv, CV_BGR2HSV);
|
||||
|
||||
// let's quantize the hue to 30 levels
|
||||
// and the saturation to 32 levels
|
||||
int hbins = 30, sbins = 32;
|
||||
int histSize[] = {hbins, sbins};
|
||||
// hue varies from 0 to 179, see cvtColor
|
||||
float hranges[] = { 0, 180 };
|
||||
// saturation varies from 0 (black-gray-white) to
|
||||
// 255 (pure spectrum color)
|
||||
float sranges[] = { 0, 256 };
|
||||
const float* ranges[] = { hranges, sranges };
|
||||
MatND hist;
|
||||
// we compute the histogram from the 0-th and 1-st channels
|
||||
int channels[] = {0, 1};
|
||||
|
||||
calcHist( &hsv, 1, channels, Mat(), // do not use mask
|
||||
hist, 2, histSize, ranges,
|
||||
true, // the histogram is uniform
|
||||
false );
|
||||
double maxVal=0;
|
||||
minMaxLoc(hist, 0, &maxVal, 0, 0);
|
||||
|
||||
int scale = 10;
|
||||
Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);
|
||||
|
||||
for( int h = 0; h < hbins; h++ )
|
||||
for( int s = 0; s < sbins; s++ )
|
||||
{
|
||||
float binVal = hist.at<float>(h, s);
|
||||
int intensity = cvRound(binVal*255/maxVal);
|
||||
rectangle( histImg, Point(h*scale, s*scale),
|
||||
Point( (h+1)*scale - 1, (s+1)*scale - 1),
|
||||
Scalar::all(intensity),
|
||||
CV_FILLED );
|
||||
}
|
||||
|
||||
namedWindow( "Source", 1 );
|
||||
imshow( "Source", src );
|
||||
|
||||
namedWindow( "H-S Histogram", 1 );
|
||||
imshow( "H-S Histogram", histImg );
|
||||
waitKey();
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvCppFunc{calcBackProject}
|
||||
Calculates the back projection of a histogram.
|
||||
|
||||
\cvdefCpp{void calcBackProject( const Mat* arrays, int narrays,\par
|
||||
const int* channels, const MatND\& hist,\par
|
||||
Mat\& backProject, const float** ranges,\par
|
||||
double scale=1, bool uniform=true );\newline
|
||||
void calcBackProject( const Mat* arrays, int narrays,\par
|
||||
const int* channels, const SparseMat\& hist,\par
|
||||
Mat\& backProject, const float** ranges,\par
|
||||
double scale=1, bool uniform=true );}
|
||||
\begin{description}
|
||||
\cvarg{arrays}{Source arrays. They all should have the same depth, \texttt{CV\_8U} or \texttt{CV\_32F}, and the same size. Each of them can have an arbitrary number of channels}
|
||||
\cvarg{narrays}{The number of source arrays}
|
||||
\cvarg{channels}{The list of channels that are used to compute the back projection. The number of channels must match the histogram dimensionality. The first array channels are numerated from 0 to \texttt{arrays[0].channels()-1}, the second array channels are counted from \texttt{arrays[0].channels()} to \texttt{arrays[0].channels() + arrays[1].channels()-1} etc.}
|
||||
\cvarg{hist}{The input histogram, a dense or sparse}
|
||||
\cvarg{backProject}{Destination back projection aray; will be a single-channel array of the same size and the same depth as \texttt{arrays[0]}}
|
||||
\cvarg{ranges}{The array of arrays of the histogram bin boundaries in each dimension. See \cvCppCross{calcHist}}
|
||||
\cvarg{scale}{The optional scale factor for the output back projection}
|
||||
\cvarg{uniform}{Indicates whether the histogram is uniform or not, see above}
|
||||
\end{description}
|
||||
|
||||
The functions \texttt{calcBackProject} calculate the back project of the histogram. That is, similarly to \texttt{calcHist}, at each location \texttt{(x, y)} the function collects the values from the selected channels in the input images and finds the corresponding histogram bin. But instead of incrementing it, the function reads the bin value, scales it by \texttt{scale} and stores in \texttt{backProject(x,y)}. In terms of statistics, the function computes probability of each element value in respect with the empirical probability distribution represented by the histogram. Here is how, for example, you can find and track a bright-colored object in a scene:
|
||||
|
||||
\begin{enumerate}
|
||||
\item Before the tracking, show the object to the camera such that covers almost the whole frame. Calculate a hue histogram. The histogram will likely have a strong maximums, corresponding to the dominant colors in the object.
|
||||
\item During the tracking, calculate back projection of a hue plane of each input video frame using that pre-computed histogram. Threshold the back projection to suppress weak colors. It may also have sense to suppress pixels with non sufficient color saturation and too dark or too bright pixels.
|
||||
\item Find connected components in the resulting picture and choose, for example, the largest component.
|
||||
\end{enumerate}
|
||||
|
||||
That is the approximate algorithm of \cvCppCross{CAMShift} color object tracker.
|
||||
|
||||
See also: \cvCppCross{calcHist}
|
||||
|
||||
\cvCppFunc{compareHist}
|
||||
Compares two histograms
|
||||
|
||||
\cvdefCpp{double compareHist( const MatND\& H1, const MatND\& H2, int method );\newline
|
||||
double compareHist( const SparseMat\& H1, \par const SparseMat\& H2, int method );}
|
||||
\begin{description}
|
||||
\cvarg{H1}{The first compared histogram}
|
||||
\cvarg{H2}{The second compared histogram of the same size as \texttt{H1}}
|
||||
\cvarg{method}{The comparison method, one of the following:
|
||||
\begin{description}
|
||||
\cvarg{CV\_COMP\_CORREL}{Correlation}
|
||||
\cvarg{CV\_COMP\_CHISQR}{Chi-Square}
|
||||
\cvarg{CV\_COMP\_INTERSECT}{Intersection}
|
||||
\cvarg{CV\_COMP\_BHATTACHARYYA}{Bhattacharyya distance}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
The functions \texttt{compareHist} compare two dense or two sparse histograms using the specified method:
|
||||
|
||||
\begin{description}
|
||||
\item[Correlation (method=CV\_COMP\_CORREL)]
|
||||
\[
|
||||
d(H_1,H_2) = \frac
|
||||
{\sum_I (H_1(I) - \bar{H_1}) (H_2(I) - \bar{H_2})}
|
||||
{\sqrt{\sum_I(H_1(I) - \bar{H_1})^2 \sum_I(H_2(I) - \bar{H_2})^2}}
|
||||
\]
|
||||
where
|
||||
\[
|
||||
\bar{H_k} = \frac{1}{N} \sum_J H_k(J)
|
||||
\]
|
||||
and $N$ is the total number of histogram bins.
|
||||
|
||||
\item[Chi-Square (method=CV\_COMP\_CHISQR)]
|
||||
\[ d(H_1,H_2) = \sum_I \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)+H_2(I)} \]
|
||||
|
||||
\item[Intersection (method=CV\_COMP\_INTERSECT)]
|
||||
\[ d(H_1,H_2) = \sum_I \min (H_1(I), H_2(I)) \]
|
||||
|
||||
\item[Bhattacharyya distance (method=CV\_COMP\_BHATTACHARYYA)]
|
||||
\[ d(H_1,H_2) = \sqrt{1 - \frac{1}{\sqrt{\bar{H_1} \bar{H_2} N^2}} \sum_I \sqrt{H_1(I) \cdot H_2(I)}} \]
|
||||
|
||||
\end{description}
|
||||
|
||||
The function returns $d(H_1, H_2)$.
|
||||
|
||||
While the function works well with 1-, 2-, 3-dimensional dense histograms, it may not be suitable for high-dimensional sparse histograms, where, because of aliasing and sampling problems the coordinates of non-zero histogram bins can slightly shift. To compare such histograms or more general sparse configurations of weighted points, consider using the \cvCppCross{calcEMD} function.
|
||||
|
||||
\cvCppFunc{equalizeHist}
|
||||
Equalizes the histogram of a grayscale image.
|
||||
|
||||
\cvdefCpp{void equalizeHist( const Mat\& src, Mat\& dst );}
|
||||
\begin{description}
|
||||
\cvarg{src}{The source 8-bit single channel image}
|
||||
\cvarg{dst}{The destination image; will have the same size and the same type as \texttt{src}}
|
||||
\end{description}
|
||||
|
||||
The function equalizes the histogram of the input image using the following algorithm:
|
||||
|
||||
\begin{enumerate}
|
||||
\item calculate the histogram $H$ for \texttt{src}.
|
||||
\item normalize the histogram so that the sum of histogram bins is 255.
|
||||
\item compute the integral of the histogram:
|
||||
\[
|
||||
H'_i = \sum_{0 \le j < i} H(j)
|
||||
\]
|
||||
\item transform the image using $H'$ as a look-up table: $\texttt{dst}(x,y) = H'(\texttt{src}(x,y))$
|
||||
\end{enumerate}
|
||||
|
||||
The algorithm normalizes the brightness and increases the contrast of the image.
|
||||
|
||||
\fi
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,773 +0,0 @@
|
||||
\section{Geometric Image Transformations}
|
||||
|
||||
The functions in this section perform various geometrical transformations of 2D images. That is, they do not change the image content, but deform the pixel grid, and map this deformed grid to the destination image. In fact, to avoid sampling artifacts, the mapping is done in the reverse order, from destination to the source. That is, for each pixel $(x, y)$ of the destination image, the functions compute coordinates of the corresponding "donor" pixel in the source image and copy the pixel value, that is:
|
||||
|
||||
\[\texttt{dst}(x,y)=\texttt{src}(f_x(x,y), f_y(x,y))\]
|
||||
|
||||
In the case when the user specifies the forward mapping: $\left<g_x, g_y\right>: \texttt{src} \rightarrow \texttt{dst}$, the OpenCV functions first compute the corresponding inverse mapping: $\left<f_x, f_y\right>: \texttt{dst} \rightarrow \texttt{src}$ and then use the above formula.
|
||||
|
||||
The actual implementations of the geometrical transformations, from the most generic \cvCross{Remap}{remap} and to the simplest and the fastest \cvCross{Resize}{resize}, need to solve the 2 main problems with the above formula:
|
||||
\begin{enumerate}
|
||||
\item extrapolation of non-existing pixels. Similarly to the filtering functions, described in the previous section, for some $(x,y)$ one of $f_x(x,y)$ or $f_y(x,y)$, or they both, may fall outside of the image, in which case some extrapolation method needs to be used. OpenCV provides the same selection of the extrapolation methods as in the filtering functions, but also an additional method \texttt{BORDER\_TRANSPARENT}, which means that the corresponding pixels in the destination image will not be modified at all.
|
||||
\item interpolation of pixel values. Usually $f_x(x,y)$ and $f_y(x,y)$ are floating-point numbers (i.e. $\left<f_x, f_y\right>$ can be an affine or perspective transformation, or radial lens distortion correction etc.), so a pixel values at fractional coordinates needs to be retrieved. In the simplest case the coordinates can be just rounded to the nearest integer coordinates and the corresponding pixel used, which is called nearest-neighbor interpolation. However, a better result can be achieved by using more sophisticated \href{http://en.wikipedia.org/wiki/Multivariate_interpolation}{interpolation methods}, where a polynomial function is fit into some neighborhood of the computed pixel $(f_x(x,y), f_y(x,y))$ and then the value of the polynomial at $(f_x(x,y), f_y(x,y))$ is taken as the interpolated pixel value. In OpenCV you can choose between several interpolation methods, see \cvCross{Resize}{resize}.
|
||||
\end{enumerate}
|
||||
|
||||
\ifCPy
|
||||
|
||||
\cvCPyFunc{GetRotationMatrix2D}
|
||||
Calculates the affine matrix of 2d rotation.
|
||||
|
||||
\cvdefC{
|
||||
CvMat* cv2DRotationMatrix(
|
||||
\par CvPoint2D32f center,
|
||||
\par double angle,
|
||||
\par double scale,
|
||||
\par CvMat* mapMatrix );
|
||||
}\cvdefPy{GetRotationMatrix2D(center,angle,scale,mapMatrix)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{center}{Center of the rotation in the source image}
|
||||
\cvarg{angle}{The rotation angle in degrees. Positive values mean counter-clockwise rotation (the coordinate origin is assumed to be the top-left corner)}
|
||||
\cvarg{scale}{Isotropic scale factor}
|
||||
\cvarg{mapMatrix}{Pointer to the destination $2\times 3$ matrix}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cv2DRotationMatrix} calculates the following matrix:
|
||||
|
||||
\[
|
||||
\begin{bmatrix}
|
||||
\alpha & \beta & (1-\alpha) \cdot \texttt{center.x} - \beta \cdot \texttt{center.y} \\
|
||||
-\beta & \alpha & \beta \cdot \texttt{center.x} - (1-\alpha) \cdot \texttt{center.y}
|
||||
\end{bmatrix}
|
||||
\]
|
||||
|
||||
where
|
||||
|
||||
\[
|
||||
\alpha = \texttt{scale} \cdot cos(\texttt{angle}), \beta = \texttt{scale} \cdot sin(\texttt{angle})
|
||||
\]
|
||||
|
||||
The transformation maps the rotation center to itself. If this is not the purpose, the shift should be adjusted.
|
||||
|
||||
\cvCPyFunc{GetAffineTransform}
|
||||
Calculates the affine transform from 3 corresponding points.
|
||||
|
||||
\cvdefC{
|
||||
CvMat* cvGetAffineTransform(
|
||||
\par const CvPoint2D32f* src,
|
||||
\par const CvPoint2D32f* dst,
|
||||
\par CvMat* mapMatrix );
|
||||
}\cvdefPy{GetAffineTransform(src,dst,mapMatrix)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{ Coordinates of 3 triangle vertices in the source image}
|
||||
\cvarg{dst}{ Coordinates of the 3 corresponding triangle vertices in the destination image}
|
||||
\cvarg{mapMatrix}{ Pointer to the destination $2 \times 3$ matrix}
|
||||
\end{description}
|
||||
|
||||
The function cvGetAffineTransform calculates the matrix of an affine transform such that:
|
||||
|
||||
\[
|
||||
\begin{bmatrix}
|
||||
x'_i\\
|
||||
y'_i
|
||||
\end{bmatrix}
|
||||
=
|
||||
\texttt{mapMatrix}
|
||||
\cdot
|
||||
\begin{bmatrix}
|
||||
x_i\\
|
||||
y_i\\
|
||||
1
|
||||
\end{bmatrix}
|
||||
\]
|
||||
|
||||
where
|
||||
|
||||
\[
|
||||
dst(i)=(x'_i,y'_i),
|
||||
src(i)=(x_i, y_i),
|
||||
i=0,1,2
|
||||
\]
|
||||
|
||||
\cvCPyFunc{GetPerspectiveTransform}
|
||||
Calculates the perspective transform from 4 corresponding points.
|
||||
|
||||
\cvdefC{
|
||||
CvMat* cvGetPerspectiveTransform(
|
||||
\par const CvPoint2D32f* src,
|
||||
\par const CvPoint2D32f* dst,
|
||||
\par CvMat* mapMatrix );
|
||||
}\cvdefPy{GetPerspectiveTransform(src,dst,mapMatrix)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Coordinates of 4 quadrangle vertices in the source image}
|
||||
\cvarg{dst}{Coordinates of the 4 corresponding quadrangle vertices in the destination image}
|
||||
\cvarg{mapMatrix}{Pointer to the destination $3\times 3$ matrix}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvGetPerspectiveTransform} calculates a matrix of perspective transforms such that:
|
||||
|
||||
\[
|
||||
\begin{bmatrix}
|
||||
x'_i\\
|
||||
y'_i
|
||||
\end{bmatrix}
|
||||
=
|
||||
\texttt{mapMatrix}
|
||||
\cdot
|
||||
\begin{bmatrix}
|
||||
x_i\\
|
||||
y_i\\
|
||||
1
|
||||
\end{bmatrix}
|
||||
\]
|
||||
|
||||
where
|
||||
|
||||
\[
|
||||
dst(i)=(x'_i,y'_i),
|
||||
src(i)=(x_i, y_i),
|
||||
i=0,1,2,3
|
||||
\]
|
||||
|
||||
\cvCPyFunc{GetQuadrangleSubPix}
|
||||
Retrieves the pixel quadrangle from an image with sub-pixel accuracy.
|
||||
|
||||
\cvdefC{
|
||||
void cvGetQuadrangleSubPix(
|
||||
\par const CvArr* src,
|
||||
\par CvArr* dst,
|
||||
\par const CvMat* mapMatrix );
|
||||
}\cvdefPy{GetQuadrangleSubPix(src,dst,mapMatrix)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{dst}{Extracted quadrangle}
|
||||
\cvarg{mapMatrix}{The transformation $2 \times 3$ matrix $[A|b]$ (see the discussion)}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvGetQuadrangleSubPix} extracts pixels from \texttt{src} at sub-pixel accuracy and stores them to \texttt{dst} as follows:
|
||||
|
||||
\[
|
||||
dst(x, y)= src( A_{11} x' + A_{12} y' + b_1, A_{21} x' + A_{22} y' + b_2)
|
||||
\]
|
||||
|
||||
where
|
||||
|
||||
\[
|
||||
x'=x-\frac{(width(dst)-1)}{2},
|
||||
y'=y-\frac{(height(dst)-1)}{2}
|
||||
\]
|
||||
|
||||
and
|
||||
|
||||
\[
|
||||
\texttt{mapMatrix} = \begin{bmatrix}
|
||||
A_{11} & A_{12} & b_1\\
|
||||
A_{21} & A_{22} & b_2
|
||||
\end{bmatrix}
|
||||
\]
|
||||
|
||||
The values of pixels at non-integer coordinates are retrieved using bilinear interpolation. When the function needs pixels outside of the image, it uses replication border mode to reconstruct the values. Every channel of multiple-channel images is processed independently.
|
||||
|
||||
|
||||
\cvCPyFunc{GetRectSubPix}
|
||||
Retrieves the pixel rectangle from an image with sub-pixel accuracy.
|
||||
|
||||
\cvdefC{void cvGetRectSubPix(
|
||||
\par const CvArr* src,
|
||||
\par CvArr* dst,
|
||||
\par CvPoint2D32f center );
|
||||
}\cvdefPy{GetRectSubPix(src,dst,center)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{dst}{Extracted rectangle}
|
||||
\cvarg{center}{Floating point coordinates of the extracted rectangle center within the source image. The center must be inside the image}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvGetRectSubPix} extracts pixels from \texttt{src}:
|
||||
|
||||
\[
|
||||
dst(x, y) = src(x + \texttt{center.x} - (width(\texttt{dst})-1)*0.5, y + \texttt{center.y} - (height(\texttt{dst} )-1)*0.5)
|
||||
\]
|
||||
|
||||
where the values of the pixels at non-integer coordinates are retrieved
|
||||
using bilinear interpolation. Every channel of multiple-channel
|
||||
images is processed independently. While the rectangle center
|
||||
must be inside the image, parts of the rectangle may be
|
||||
outside. In this case, the replication border mode is used to get
|
||||
pixel values beyond the image boundaries.
|
||||
|
||||
|
||||
\cvCPyFunc{LogPolar}
|
||||
Remaps an image to log-polar space.
|
||||
|
||||
\cvdefC{
|
||||
void cvLogPolar(
|
||||
\par const CvArr* src,
|
||||
\par CvArr* dst,
|
||||
\par CvPoint2D32f center,
|
||||
\par double M,
|
||||
\par int flags=CV\_INTER\_LINEAR+CV\_WARP\_FILL\_OUTLIERS );}
|
||||
\cvdefPy{LogPolar(src,dst,center,M,flags=CV\_INNER\_LINEAR+CV\_WARP\_FILL\_OUTLIERS)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{dst}{Destination image}
|
||||
\cvarg{center}{The transformation center; where the output precision is maximal}
|
||||
\cvarg{M}{Magnitude scale parameter. See below}
|
||||
\cvarg{flags}{A combination of interpolation methods and the following optional flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_WARP\_FILL\_OUTLIERS}{fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to zero}
|
||||
\cvarg{CV\_WARP\_INVERSE\_MAP}{See below}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvLogPolar} transforms the source image using the following transformation:
|
||||
|
||||
Forward transformation (\texttt{CV\_WARP\_INVERSE\_MAP} is not set):
|
||||
|
||||
\[
|
||||
dst(\phi,\rho) = src(x,y)
|
||||
\]
|
||||
|
||||
Inverse transformation (\texttt{CV\_WARP\_INVERSE\_MAP} is set):
|
||||
|
||||
\[
|
||||
dst(x,y) = src(\phi,\rho)
|
||||
\]
|
||||
|
||||
where
|
||||
|
||||
\[
|
||||
\rho = M \cdot \log{\sqrt{x^2 + y^2}},
|
||||
\phi=atan(y/x)
|
||||
\]
|
||||
|
||||
The function emulates the human "foveal" vision and can be used for fast scale and rotation-invariant template matching, for object tracking and so forth.
|
||||
The function can not operate in-place.
|
||||
|
||||
\ifC
|
||||
% Example: Log-polar transformation
|
||||
\begin{lstlisting}
|
||||
#include <cv.h>
|
||||
#include <highgui.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
IplImage* src;
|
||||
|
||||
if( argc == 2 && (src=cvLoadImage(argv[1],1) != 0 )
|
||||
{
|
||||
IplImage* dst = cvCreateImage( cvSize(256,256), 8, 3 );
|
||||
IplImage* src2 = cvCreateImage( cvGetSize(src), 8, 3 );
|
||||
cvLogPolar( src, dst, cvPoint2D32f(src->width/2,src->height/2), 40,
|
||||
CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS );
|
||||
cvLogPolar( dst, src2, cvPoint2D32f(src->width/2,src->height/2), 40,
|
||||
CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS+CV_WARP_INVERSE_MAP );
|
||||
cvNamedWindow( "log-polar", 1 );
|
||||
cvShowImage( "log-polar", dst );
|
||||
cvNamedWindow( "inverse log-polar", 1 );
|
||||
cvShowImage( "inverse log-polar", src2 );
|
||||
cvWaitKey();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
And this is what the program displays when \texttt{opencv/samples/c/fruits.jpg} is passed to it
|
||||
\includegraphics[width=0.4\textwidth]{pics/logpolar.jpg}
|
||||
\includegraphics[width=0.4\textwidth]{pics/inv_logpolar.jpg}
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{Remap}
|
||||
Applies a generic geometrical transformation to the image.
|
||||
|
||||
\cvdefC{
|
||||
void cvRemap(
|
||||
\par const CvArr* src,
|
||||
\par CvArr* dst,
|
||||
\par const CvArr* mapx,
|
||||
\par const CvArr* mapy,
|
||||
\par int flags=CV\_INTER\_LINEAR+CV\_WARP\_FILL\_OUTLIERS,
|
||||
\par CvScalar fillval=cvScalarAll(0) );}
|
||||
\cvdefPy{Remap(src,dst,mapx,mapy,flags=CV\_INNER\_LINEAR+CV\_WARP\_FILL\_OUTLIERS,fillval=(0,0,0,0))-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{dst}{Destination image}
|
||||
\cvarg{mapx}{The map of x-coordinates (CV\_32FC1 image)}
|
||||
\cvarg{mapy}{The map of y-coordinates (CV\_32FC1 image)}
|
||||
\cvarg{flags}{A combination of interpolation method and the following optional flag(s):
|
||||
\begin{description}
|
||||
\cvarg{CV\_WARP\_FILL\_OUTLIERS}{fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to \texttt{fillval}}
|
||||
\end{description}}
|
||||
\cvarg{fillval}{A value used to fill outliers}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvRemap} transforms the source image using the specified map:
|
||||
|
||||
\[
|
||||
\texttt{dst}(x,y) = \texttt{src}(\texttt{mapx}(x,y),\texttt{mapy}(x,y))
|
||||
\]
|
||||
|
||||
Similar to other geometrical transformations, some interpolation method (specified by user) is used to extract pixels with non-integer coordinates.
|
||||
Note that the function can not operate in-place.
|
||||
|
||||
\cvCPyFunc{Resize}
|
||||
Resizes an image.
|
||||
|
||||
\cvdefC{
|
||||
void cvResize(
|
||||
\par const CvArr* src,
|
||||
\par CvArr* dst,
|
||||
\par int interpolation=CV\_INTER\_LINEAR );}
|
||||
\cvdefPy{Resize(src,dst,interpolation=CV\_INTER\_LINEAR)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{dst}{Destination image}
|
||||
\cvarg{interpolation}{Interpolation method:
|
||||
\begin{description}
|
||||
\cvarg{CV\_INTER\_NN}{nearest-neigbor interpolation}
|
||||
\cvarg{CV\_INTER\_LINEAR}{bilinear interpolation (used by default)}
|
||||
\cvarg{CV\_INTER\_AREA}{resampling using pixel area relation. It is the preferred method for image decimation that gives moire-free results. In terms of zooming it is similar to the \texttt{CV\_INTER\_NN} method}
|
||||
\cvarg{CV\_INTER\_CUBIC}{bicubic interpolation}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvResize} resizes an image \texttt{src} so that it fits exactly into \texttt{dst}. If ROI is set, the function considers the ROI as supported.
|
||||
|
||||
|
||||
\cvCPyFunc{WarpAffine}
|
||||
Applies an affine transformation to an image.
|
||||
|
||||
\cvdefC{
|
||||
void cvWarpAffine(
|
||||
\par const CvArr* src,
|
||||
\par CvArr* dst,
|
||||
\par const CvMat* mapMatrix,
|
||||
\par int flags=CV\_INTER\_LINEAR+CV\_WARP\_FILL\_OUTLIERS,
|
||||
\par CvScalar fillval=cvScalarAll(0) );
|
||||
}
|
||||
\cvdefPy{WarpAffine(src,dst,mapMatrix,flags=CV\_INTER\_LINEAR+CV\_WARP\_FILL\_OUTLIERS,fillval=(0,0,0,0))-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{dst}{Destination image}
|
||||
\cvarg{mapMatrix}{$2\times 3$ transformation matrix}
|
||||
\cvarg{flags}{A combination of interpolation methods and the following optional flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_WARP\_FILL\_OUTLIERS}{fills all of the destination image pixels; if some of them correspond to outliers in the source image, they are set to \texttt{fillval}}
|
||||
\cvarg{CV\_WARP\_INVERSE\_MAP}{indicates that \texttt{matrix} is inversely
|
||||
transformed from the destination image to the source and, thus, can be used
|
||||
directly for pixel interpolation. Otherwise, the function finds
|
||||
the inverse transform from \texttt{mapMatrix}}}
|
||||
\end{description}
|
||||
\cvarg{fillval}{A value used to fill outliers}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvWarpAffine} transforms the source image using the specified matrix:
|
||||
|
||||
\[
|
||||
dst(x',y') = src(x,y)
|
||||
\]
|
||||
|
||||
where
|
||||
|
||||
\[
|
||||
\begin{matrix}
|
||||
\begin{bmatrix}
|
||||
x'\\
|
||||
y'
|
||||
\end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix}
|
||||
x\\
|
||||
y\\
|
||||
1
|
||||
\end{bmatrix} & \mbox{if CV\_WARP\_INVERSE\_MAP is not set}\\
|
||||
\begin{bmatrix}
|
||||
x\\
|
||||
y
|
||||
\end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix}
|
||||
x'\\
|
||||
y'\\
|
||||
1
|
||||
\end{bmatrix}& \mbox{otherwise}
|
||||
\end{matrix}
|
||||
\]
|
||||
|
||||
The function is similar to \cvCPyCross{GetQuadrangleSubPix} but they are not exactly the same. \cvCPyCross{WarpAffine} requires input and output image have the same data type, has larger overhead (so it is not quite suitable for small images) and can leave part of destination image unchanged. While \cvCPyCross{GetQuadrangleSubPix} may extract quadrangles from 8-bit images into floating-point buffer, has smaller overhead and always changes the whole destination image content.
|
||||
Note that the function can not operate in-place.
|
||||
|
||||
To transform a sparse set of points, use the \cvCPyCross{Transform} function from cxcore.
|
||||
|
||||
\cvCPyFunc{WarpPerspective}
|
||||
Applies a perspective transformation to an image.
|
||||
|
||||
\cvdefC{
|
||||
void cvWarpPerspective(
|
||||
\par const CvArr* src,
|
||||
\par CvArr* dst,
|
||||
\par const CvMat* mapMatrix,
|
||||
\par int flags=CV\_INTER\_LINEAR+CV\_WARP\_FILL\_OUTLIERS,
|
||||
\par CvScalar fillval=cvScalarAll(0) );
|
||||
}
|
||||
\cvdefPy{WarpPerspective(src,dst,mapMatrix,flags=CV\_INNER\_LINEAR+CV\_WARP\_FILL\_OUTLIERS,fillval=(0,0,0,0))-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{dst}{Destination image}
|
||||
\cvarg{mapMatrix}{$3\times 3$ transformation matrix}
|
||||
\cvarg{flags}{A combination of interpolation methods and the following optional flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_WARP\_FILL\_OUTLIERS}{fills all of the destination image pixels; if some of them correspond to outliers in the source image, they are set to \texttt{fillval}}
|
||||
\cvarg{CV\_WARP\_INVERSE\_MAP}{indicates that \texttt{matrix} is inversely transformed from the destination image to the source and, thus, can be used directly for pixel interpolation. Otherwise, the function finds the inverse transform from \texttt{mapMatrix}}
|
||||
\end{description}}
|
||||
\cvarg{fillval}{A value used to fill outliers}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{cvWarpPerspective} transforms the source image using the specified matrix:
|
||||
|
||||
\[
|
||||
\begin{matrix}
|
||||
\begin{bmatrix}
|
||||
x'\\
|
||||
y'
|
||||
\end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix}
|
||||
x\\
|
||||
y\\
|
||||
1
|
||||
\end{bmatrix} & \mbox{if CV\_WARP\_INVERSE\_MAP is not set}\\
|
||||
\begin{bmatrix}
|
||||
x\\
|
||||
y
|
||||
\end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix}
|
||||
x'\\
|
||||
y'\\
|
||||
1
|
||||
\end{bmatrix}& \mbox{otherwise}
|
||||
\end{matrix}
|
||||
\]
|
||||
|
||||
Note that the function can not operate in-place.
|
||||
For a sparse set of points use the \cvCPyCross{PerspectiveTransform} function from CxCore.
|
||||
|
||||
\fi
|
||||
|
||||
\ifCpp
|
||||
|
||||
\cvCppFunc{convertMaps}
|
||||
Converts image transformation maps from one representation to another
|
||||
|
||||
\cvdefCpp{void convertMaps( const Mat\& map1, const Mat\& map2,\par
|
||||
Mat\& dstmap1, Mat\& dstmap2,\par
|
||||
int dstmap1type, bool nninterpolation=false );}
|
||||
\begin{description}
|
||||
\cvarg{map1}{The first input map of type \texttt{CV\_16SC2} or \texttt{CV\_32FC1} or \texttt{CV\_32FC2}}
|
||||
\cvarg{map2}{The second input map of type \texttt{CV\_16UC1} or \texttt{CV\_32FC1} or none (empty matrix), respectively}
|
||||
\cvarg{dstmap1}{The first output map; will have type \texttt{dstmap1type} and the same size as \texttt{src}}
|
||||
\cvarg{dstmap2}{The second output map}
|
||||
\cvarg{dstmap1type}{The type of the first output map; should be \texttt{CV\_16SC2}, \texttt{CV\_32FC1} or \texttt{CV\_32FC2}}
|
||||
\cvarg{nninterpolation}{Indicates whether the fixed-point maps will be used for nearest-neighbor or for more complex interpolation}
|
||||
\end{description}
|
||||
|
||||
The function converts a pair of maps for \cvCppCross{remap} from one representation to another. The following options (\texttt{(map1.type(), map2.type())} $\rightarrow$ \texttt{(dstmap1.type(), dstmap2.type())}) are supported:
|
||||
\begin{enumerate}
|
||||
\item $\texttt{(CV\_32FC1, CV\_32FC1)} \rightarrow \texttt{(CV\_16SC2, CV\_16UC1)}$. This is the most frequently used conversion operation, in which the original floating-point maps (see \cvCppCross{remap}) are converted to more compact and much faster fixed-point representation. The first output array will contain the rounded coordinates and the second array (created only when \texttt{nninterpolation=false}) will contain indices in the interpolation tables.
|
||||
\item $\texttt{(CV\_32FC2)} \rightarrow \texttt{(CV\_16SC2, CV\_16UC1)}$. The same as above, but the original maps are stored in one 2-channel matrix.
|
||||
\item the reverse conversion. Obviously, the reconstructed floating-point maps will not be exactly the same as the originals.
|
||||
\end{enumerate}
|
||||
|
||||
See also: \cvCppCross{remap}, \cvCppCross{undisort}, \cvCppCross{initUndistortRectifyMap}
|
||||
|
||||
\cvCppFunc{getAffineTransform}
|
||||
Calculates the affine transform from 3 pairs of the corresponding points
|
||||
|
||||
\cvdefCpp{Mat getAffineTransform( const Point2f src[], const Point2f dst[] );}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Coordinates of a triangle vertices in the source image}
|
||||
\cvarg{dst}{Coordinates of the corresponding triangle vertices in the destination image}
|
||||
\end{description}
|
||||
|
||||
The function calculates the $2 \times 3$ matrix of an affine transform such that:
|
||||
|
||||
\[
|
||||
\begin{bmatrix}
|
||||
x'_i\\
|
||||
y'_i
|
||||
\end{bmatrix}
|
||||
=
|
||||
\texttt{map\_matrix}
|
||||
\cdot
|
||||
\begin{bmatrix}
|
||||
x_i\\
|
||||
y_i\\
|
||||
1
|
||||
\end{bmatrix}
|
||||
\]
|
||||
|
||||
where
|
||||
|
||||
\[
|
||||
dst(i)=(x'_i,y'_i),
|
||||
src(i)=(x_i, y_i),
|
||||
i=0,1,2
|
||||
\]
|
||||
|
||||
See also: \cvCppCross{warpAffine}, \cvCppCross{transform}
|
||||
|
||||
\cvCppFunc{getPerspectiveTransform}
|
||||
Calculates the perspective transform from 4 pairs of the corresponding points
|
||||
|
||||
\cvdefCpp{Mat getPerspectiveTransform( const Point2f src[], \par const Point2f dst[] );}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{src}{Coordinates of a quadrange vertices in the source image}
|
||||
\cvarg{dst}{Coordinates of the corresponding quadrangle vertices in the destination image}
|
||||
\end{description}
|
||||
|
||||
The function calculates the $3 \times 3$ matrix of a perspective transform such that:
|
||||
|
||||
\[
|
||||
\begin{bmatrix}
|
||||
t_i x'_i\\
|
||||
t_i y'_i\\
|
||||
t_i
|
||||
\end{bmatrix}
|
||||
=
|
||||
\texttt{map\_matrix}
|
||||
\cdot
|
||||
\begin{bmatrix}
|
||||
x_i\\
|
||||
y_i\\
|
||||
1
|
||||
\end{bmatrix}
|
||||
\]
|
||||
|
||||
where
|
||||
|
||||
\[
|
||||
dst(i)=(x'_i,y'_i),
|
||||
src(i)=(x_i, y_i),
|
||||
i=0,1,2
|
||||
\]
|
||||
|
||||
See also: \cvCppCross{findHomography}, \cvCppCross{warpPerspective}, \cvCppCross{perspectiveTransform}
|
||||
|
||||
\cvCppFunc{getRectSubPix}
|
||||
Retrieves the pixel rectangle from an image with sub-pixel accuracy
|
||||
|
||||
\cvdefCpp{void getRectSubPix( const Mat\& image, Size patchSize,\par
|
||||
Point2f center, Mat\& dst, int patchType=-1 );}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{patchSize}{Size of the extracted patch}
|
||||
\cvarg{center}{Floating point coordinates of the extracted rectangle center within the source image. The center must be inside the image}
|
||||
\cvarg{dst}{The extracted patch; will have the size \texttt{patchSize} and the same number of channels as \texttt{src}}
|
||||
\cvarg{patchType}{The depth of the extracted pixels. By default they will have the same depth as \texttt{src}}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{getRectSubPix} extracts pixels from \texttt{src}:
|
||||
|
||||
\[
|
||||
dst(x, y) = src(x + \texttt{center.x} - (\texttt{dst.cols}-1)*0.5, y + \texttt{center.y} - (\texttt{dst.rows}-1)*0.5)
|
||||
\]
|
||||
|
||||
where the values of the pixels at non-integer coordinates are retrieved
|
||||
using bilinear interpolation. Every channel of multiple-channel
|
||||
images is processed independently. While the rectangle center
|
||||
must be inside the image, parts of the rectangle may be
|
||||
outside. In this case, the replication border mode (see \cvCppCross{borderInterpolate}) is used to extrapolate
|
||||
the pixel values outside of the image.
|
||||
|
||||
See also: \cvCppCross{warpAffine}, \cvCppCross{warpPerspective}
|
||||
|
||||
\cvCppFunc{getRotationMatrix2D}
|
||||
Calculates the affine matrix of 2d rotation.
|
||||
|
||||
\cvdefCpp{Mat getRotationMatrix2D( Point2f center, double angle, double scale );}
|
||||
\begin{description}
|
||||
\cvarg{center}{Center of the rotation in the source image}
|
||||
\cvarg{angle}{The rotation angle in degrees. Positive values mean counter-clockwise rotation (the coordinate origin is assumed to be the top-left corner)}
|
||||
\cvarg{scale}{Isotropic scale factor}
|
||||
\end{description}
|
||||
|
||||
The function calculates the following matrix:
|
||||
|
||||
\[
|
||||
\begin{bmatrix}
|
||||
\alpha & \beta & (1-\alpha) \cdot \texttt{center.x} - \beta \cdot \texttt{center.y} \\
|
||||
-\beta & \alpha & \beta \cdot \texttt{center.x} - (1-\alpha) \cdot \texttt{center.y}
|
||||
\end{bmatrix}
|
||||
\]
|
||||
|
||||
where
|
||||
|
||||
\[
|
||||
\begin{array}{l}
|
||||
\alpha = \texttt{scale} \cdot \cos \texttt{angle},\\
|
||||
\beta = \texttt{scale} \cdot \sin \texttt{angle}
|
||||
\end{array}
|
||||
\]
|
||||
|
||||
The transformation maps the rotation center to itself. If this is not the purpose, the shift should be adjusted.
|
||||
|
||||
See also: \cvCppCross{getAffineTransform}, \cvCppCross{warpAffine}, \cvCppCross{transform}
|
||||
|
||||
|
||||
\cvCppFunc{invertAffineTransform}
|
||||
Inverts an affine transformation
|
||||
|
||||
\cvdefCpp{void invertAffineTransform(const Mat\& M, Mat\& iM);}
|
||||
\begin{description}
|
||||
\cvarg{M}{The original affine transformation}
|
||||
\cvarg{iM}{The output reverse affine transformation}
|
||||
\end{description}
|
||||
|
||||
The function computes inverse affine transformation represented by $2 \times 3$ matrix \texttt{M}:
|
||||
|
||||
\[\begin{bmatrix}
|
||||
a_{11} & a_{12} & b_1 \\
|
||||
a_{21} & a_{22} & b_2
|
||||
\end{bmatrix}
|
||||
\]
|
||||
|
||||
The result will also be a $2 \times 3$ matrix of the same type as \texttt{M}.
|
||||
|
||||
\cvCppFunc{remap}
|
||||
Applies a generic geometrical transformation to an image.
|
||||
|
||||
\cvdefCpp{void remap( const Mat\& src, Mat\& dst, const Mat\& map1, const Mat\& map2,\par
|
||||
int interpolation, int borderMode=BORDER\_CONSTANT,\par
|
||||
const Scalar\& borderValue=Scalar());}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{dst}{Destination image. It will have the same size as \texttt{map1} and the same type as \texttt{src}}
|
||||
\cvarg{map1}{The first map of either \texttt{(x,y)} points or just \texttt{x} values having type \texttt{CV\_16SC2}, \texttt{CV\_32FC1} or \texttt{CV\_32FC2}. See \cvCppCross{convertMaps} for converting floating point representation to fixed-point for speed.}
|
||||
\cvarg{map2}{The second map of \texttt{y} values having type \texttt{CV\_16UC1}, \texttt{CV\_32FC1} or none (empty map if map1 is \texttt{(x,y)} points), respectively}
|
||||
\cvarg{interpolation}{The interpolation method, see \cvCppCross{resize}. The method \texttt{INTER\_AREA} is not supported by this function}
|
||||
\cvarg{borderMode}{The pixel extrapolation method, see \cvCppCross{borderInterpolate}. When the\\ \texttt{borderMode=BORDER\_TRANSPARENT}, it means that the pixels in the destination image that corresponds to the "outliers" in the source image are not modified by the function}
|
||||
\cvarg{borderValue}{A value used in the case of a constant border. By default it is 0}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{remap} transforms the source image using the specified map:
|
||||
|
||||
\[
|
||||
\texttt{dst}(x,y) = \texttt{src}(map_x(x,y),map_y(x,y))
|
||||
\]
|
||||
|
||||
Where values of pixels with non-integer coordinates are computed using one of the available interpolation methods. $map_x$ and $map_y$
|
||||
can be encoded as separate floating-point maps in $map_1$ and $map_2$ respectively, or interleaved floating-point maps of $(x,y)$ in $map_1$, or
|
||||
fixed-point maps made by using \cvCppCross{convertMaps}. The reason you might want to convert from floating to fixed-point
|
||||
representations of a map is that they can yield much faster (~2x) remapping operations. In the converted case, $map_1$ contains pairs
|
||||
\texttt{(cvFloor(x), cvFloor(y))} and $map_2$ contains indices in a table of interpolation coefficients.
|
||||
|
||||
This function can not operate in-place.
|
||||
|
||||
\cvCppFunc{resize}
|
||||
Resizes an image
|
||||
|
||||
\cvdefCpp{void resize( const Mat\& src, Mat\& dst,\par
|
||||
Size dsize, double fx=0, double fy=0,\par
|
||||
int interpolation=INTER\_LINEAR );}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{dst}{Destination image. It will have size \texttt{dsize} (when it is non-zero) or the size computed from \texttt{src.size()}
|
||||
and \texttt{fx} and \texttt{fy}. The type of \texttt{dst} will be the same as of \texttt{src}.}
|
||||
\cvarg{dsize}{The destination image size. If it is zero, then it is computed as:
|
||||
\[\texttt{dsize = Size(round(fx*src.cols), round(fy*src.rows))}\].
|
||||
Either \texttt{dsize} or both \texttt{fx} or \texttt{fy} must be non-zero.}
|
||||
\cvarg{fx}{The scale factor along the horizontal axis. When 0, it is computed as
|
||||
\[\texttt{(double)dsize.width/src.cols}\]}
|
||||
\cvarg{fy}{The scale factor along the vertical axis. When 0, it is computed as
|
||||
\[\texttt{(double)dsize.height/src.rows}\]}
|
||||
\cvarg{interpolation}{The interpolation method:
|
||||
\begin{description}
|
||||
\cvarg{INTER\_NEAREST}{nearest-neighbor interpolation}
|
||||
\cvarg{INTER\_LINEAR}{bilinear interpolation (used by default)}
|
||||
\cvarg{INTER\_AREA}{resampling using pixel area relation. It may be the preferred method for image decimation, as it gives moire-free results. But when the image is zoomed, it is similar to the \texttt{INTER\_NEAREST} method}
|
||||
\cvarg{INTER\_CUBIC}{bicubic interpolation over 4x4 pixel neighborhood}
|
||||
\cvarg{INTER\_LANCZOS4}{Lanczos interpolation over 8x8 pixel neighborhood}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{resize} resizes an image \texttt{src} down to or up to the specified size.
|
||||
Note that the initial \texttt{dst} type or size are not taken into account. Instead the size and type are derived from the \texttt{src}, \texttt{dsize}, \texttt{fx} and \texttt{fy}. If you want to resize \texttt{src} so that it fits the pre-created \texttt{dst}, you may call the function as:
|
||||
|
||||
\begin{lstlisting}
|
||||
// explicitly specify dsize=dst.size(); fx and fy will be computed from that.
|
||||
resize(src, dst, dst.size(), 0, 0, interpolation);
|
||||
\end{lstlisting}
|
||||
|
||||
If you want to decimate the image by factor of 2 in each direction, you can call the function this way:
|
||||
|
||||
\begin{lstlisting}
|
||||
// specify fx and fy and let the function to compute the destination image size.
|
||||
resize(src, dst, Size(), 0.5, 0.5, interpolation);
|
||||
\end{lstlisting}
|
||||
|
||||
See also: \cvCppCross{warpAffine}, \cvCppCross{warpPerspective}, \cvCppCross{remap}.
|
||||
|
||||
|
||||
\cvCppFunc{warpAffine}
|
||||
Applies an affine transformation to an image.
|
||||
|
||||
\cvdefCpp{void warpAffine( const Mat\& src, Mat\& dst,\par
|
||||
const Mat\& M, Size dsize,\par
|
||||
int flags=INTER\_LINEAR,\par
|
||||
int borderMode=BORDER\_CONSTANT,\par
|
||||
const Scalar\& borderValue=Scalar());}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{dst}{Destination image; will have size \texttt{dsize} and the same type as \texttt{src}}
|
||||
\cvarg{M}{$2\times 3$ transformation matrix}
|
||||
\cvarg{dsize}{Size of the destination image}
|
||||
\cvarg{flags}{A combination of interpolation methods, see \cvCppCross{resize}, and the optional flag \texttt{WARP\_INVERSE\_MAP} that means that \texttt{M} is the inverse transformation ($\texttt{dst}\rightarrow\texttt{src}$)}
|
||||
\cvarg{borderMode}{The pixel extrapolation method, see \cvCppCross{borderInterpolate}. When the \\ \texttt{borderMode=BORDER\_TRANSPARENT}, it means that the pixels in the destination image that corresponds to the "outliers" in the source image are not modified by the function}
|
||||
\cvarg{borderValue}{A value used in case of a constant border. By default it is 0}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{warpAffine} transforms the source image using the specified matrix:
|
||||
|
||||
\[
|
||||
\texttt{dst}(x,y) = \texttt{src}(\texttt{M}_{11} x + \texttt{M}_{12} y + \texttt{M}_{13}, \texttt{M}_{21} x + \texttt{M}_{22} y + \texttt{M}_{23})
|
||||
\]
|
||||
when the flag \texttt{WARP\_INVERSE\_MAP} is set. Otherwise, the transformation is first inverted with \cvCppCross{invertAffineTransform} and then put in the formula above instead of \texttt{M}.
|
||||
The function can not operate in-place.
|
||||
|
||||
See also: \cvCppCross{warpPerspective}, \cvCppCross{resize}, \cvCppCross{remap}, \cvCppCross{getRectSubPix}, \cvCppCross{transform}
|
||||
|
||||
\cvCppFunc{warpPerspective}
|
||||
Applies a perspective transformation to an image.
|
||||
|
||||
\cvdefCpp{void warpPerspective( const Mat\& src, Mat\& dst,\par
|
||||
const Mat\& M, Size dsize,\par
|
||||
int flags=INTER\_LINEAR,\par
|
||||
int borderMode=BORDER\_CONSTANT,\par
|
||||
const Scalar\& borderValue=Scalar());}
|
||||
\begin{description}
|
||||
\cvarg{src}{Source image}
|
||||
\cvarg{dst}{Destination image; will have size \texttt{dsize} and the same type as \texttt{src}}
|
||||
\cvarg{M}{$3\times 3$ transformation matrix}
|
||||
\cvarg{dsize}{Size of the destination image}
|
||||
\cvarg{flags}{A combination of interpolation methods, see \cvCppCross{resize}, and the optional flag \texttt{WARP\_INVERSE\_MAP} that means that \texttt{M} is the inverse transformation ($\texttt{dst}\rightarrow\texttt{src}$)}
|
||||
\cvarg{borderMode}{The pixel extrapolation method, see \cvCppCross{borderInterpolate}. When the \\ \texttt{borderMode=BORDER\_TRANSPARENT}, it means that the pixels in the destination image that corresponds to the "outliers" in the source image are not modified by the function}
|
||||
\cvarg{borderValue}{A value used in case of a constant border. By default it is 0}
|
||||
\end{description}
|
||||
|
||||
The function \texttt{warpPerspective} transforms the source image using the specified matrix:
|
||||
|
||||
\[
|
||||
\texttt{dst}(x,y) = \texttt{src}\left(\frac{M_{11} x + M_{12} y + M_{13}}{M_{31} x + M_{32} y + M_{33}},
|
||||
\frac{M_{21} x + M_{22} y + M_{23}}{M_{31} x + M_{32} y + M_{33}}\right)
|
||||
\]
|
||||
when the flag \texttt{WARP\_INVERSE\_MAP} is set. Otherwise, the transformation is first inverted with \cvCppCross{invert} and then put in the formula above instead of \texttt{M}.
|
||||
The function can not operate in-place.
|
||||
|
||||
See also: \cvCppCross{warpAffine}, \cvCppCross{resize}, \cvCppCross{remap}, \cvCppCross{getRectSubPix}, \cvCppCross{perspectiveTransform}
|
||||
|
||||
\fi
|
||||
|
@ -1,169 +0,0 @@
|
||||
%[TODO: FROM VIDEO]
|
||||
\section{Motion Analysis and Object Tracking}
|
||||
|
||||
\ifCPy
|
||||
|
||||
\cvCPyFunc{Acc}
|
||||
Adds a frame to an accumulator.
|
||||
|
||||
\cvdefC{
|
||||
void cvAcc( \par const CvArr* image,\par CvArr* sum,\par const CvArr* mask=NULL );
|
||||
}
|
||||
\cvdefPy{Acc(image,sum,mask=NULL)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Input image, 1- or 3-channel, 8-bit or 32-bit floating point. (each channel of multi-channel image is processed independently)}
|
||||
\cvarg{sum}{Accumulator with the same number of channels as input image, 32-bit or 64-bit floating-point}
|
||||
\cvarg{mask}{Optional operation mask}
|
||||
\end{description}
|
||||
|
||||
The function adds the whole image \texttt{image} or its selected region to the accumulator \texttt{sum}:
|
||||
|
||||
\[ \texttt{sum}(x,y) \leftarrow \texttt{sum}(x,y) + \texttt{image}(x,y) \quad \text{if} \quad \texttt{mask}(x,y) \ne 0 \]
|
||||
|
||||
\cvCPyFunc{MultiplyAcc}
|
||||
Adds the product of two input images to the accumulator.
|
||||
|
||||
\cvdefC{
|
||||
void cvMultiplyAcc( \par const CvArr* image1,\par const CvArr* image2,\par CvArr* acc,\par const CvArr* mask=NULL );
|
||||
}
|
||||
\cvdefPy{MultiplyAcc(image1,image2,acc,mask=NULL)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image1}{First input image, 1- or 3-channel, 8-bit or 32-bit floating point (each channel of multi-channel image is processed independently)}
|
||||
\cvarg{image2}{Second input image, the same format as the first one}
|
||||
\cvarg{acc}{Accumulator with the same number of channels as input images, 32-bit or 64-bit floating-point}
|
||||
\cvarg{mask}{Optional operation mask}
|
||||
\end{description}
|
||||
|
||||
The function adds the product of 2 images or their selected regions to the accumulator \texttt{acc}:
|
||||
|
||||
\[ \texttt{acc}(x,y) \leftarrow \texttt{acc}(x,y) + \texttt{image1}(x,y) \cdot \texttt{image2}(x,y) \quad \text{if} \quad \texttt{mask}(x,y) \ne 0 \]
|
||||
|
||||
|
||||
\cvCPyFunc{RunningAvg}
|
||||
Updates the running average.
|
||||
|
||||
\cvdefC{
|
||||
void cvRunningAvg( \par const CvArr* image,\par CvArr* acc,\par double alpha,\par const CvArr* mask=NULL );
|
||||
}
|
||||
\cvdefPy{RunningAvg(image,acc,alpha,mask=NULL)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Input image, 1- or 3-channel, 8-bit or 32-bit floating point (each channel of multi-channel image is processed independently)}
|
||||
\cvarg{acc}{Accumulator with the same number of channels as input image, 32-bit or 64-bit floating-point}
|
||||
\cvarg{alpha}{Weight of input image}
|
||||
\cvarg{mask}{Optional operation mask}
|
||||
\end{description}
|
||||
|
||||
The function calculates the weighted sum of the input image
|
||||
\texttt{image} and the accumulator \texttt{acc} so that \texttt{acc}
|
||||
becomes a running average of frame sequence:
|
||||
|
||||
\[ \texttt{acc}(x,y) \leftarrow (1-\alpha) \cdot \texttt{acc}(x,y) + \alpha \cdot \texttt{image}(x,y) \quad \text{if} \quad \texttt{mask}(x,y) \ne 0 \]
|
||||
|
||||
where $\alpha$ regulates the update speed (how fast the accumulator forgets about previous frames).
|
||||
|
||||
\cvCPyFunc{SquareAcc}
|
||||
Adds the square of the source image to the accumulator.
|
||||
|
||||
\cvdefC{
|
||||
void cvSquareAcc( \par const CvArr* image,\par CvArr* sqsum,\par const CvArr* mask=NULL );
|
||||
}\cvdefPy{SquareAcc(image,sqsum,mask=NULL)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Input image, 1- or 3-channel, 8-bit or 32-bit floating point (each channel of multi-channel image is processed independently)}
|
||||
\cvarg{sqsum}{Accumulator with the same number of channels as input image, 32-bit or 64-bit floating-point}
|
||||
\cvarg{mask}{Optional operation mask}
|
||||
\end{description}
|
||||
|
||||
The function adds the input image \texttt{image} or its selected region, raised to power 2, to the accumulator \texttt{sqsum}:
|
||||
|
||||
\[ \texttt{sqsum}(x,y) \leftarrow \texttt{sqsum}(x,y) + \texttt{image}(x,y)^2 \quad \text{if} \quad \texttt{mask}(x,y) \ne 0 \]
|
||||
|
||||
\fi
|
||||
|
||||
\ifCpp
|
||||
|
||||
\cvCppFunc{accumulate}
|
||||
Adds image to the accumulator.
|
||||
|
||||
\cvdefCpp{void accumulate( const Mat\& src, Mat\& dst, const Mat\& mask=Mat() );}
|
||||
\begin{description}
|
||||
\cvarg{src}{The input image, 1- or 3-channel, 8-bit or 32-bit floating point}
|
||||
\cvarg{dst}{The accumulator image with the same number of channels as input image, 32-bit or 64-bit floating-point}
|
||||
\cvarg{mask}{Optional operation mask}
|
||||
\end{description}
|
||||
|
||||
The function adds \texttt{src}, or some of its elements, to \texttt{dst}:
|
||||
|
||||
\[ \texttt{dst}(x,y) \leftarrow \texttt{dst}(x,y) + \texttt{src}(x,y) \quad \text{if} \quad \texttt{mask}(x,y) \ne 0 \]
|
||||
|
||||
The function supports multi-channel images; each channel is processed independently.
|
||||
|
||||
The functions \texttt{accumulate*} can be used, for example, to collect statistic of background of a scene, viewed by a still camera, for the further foreground-background segmentation.
|
||||
|
||||
See also: \cvCppCross{accumulateSquare}, \cvCppCross{accumulateProduct}, \cvCppCross{accumulateWeighted}
|
||||
|
||||
\cvCppFunc{accumulateSquare}
|
||||
Adds the square of the source image to the accumulator.
|
||||
|
||||
\cvdefCpp{void accumulateSquare( const Mat\& src, Mat\& dst, \par const Mat\& mask=Mat() );}
|
||||
\begin{description}
|
||||
\cvarg{src}{The input image, 1- or 3-channel, 8-bit or 32-bit floating point}
|
||||
\cvarg{dst}{The accumulator image with the same number of channels as input image, 32-bit or 64-bit floating-point}
|
||||
\cvarg{mask}{Optional operation mask}
|
||||
\end{description}
|
||||
|
||||
The function adds the input image \texttt{src} or its selected region, raised to power 2, to the accumulator \texttt{dst}:
|
||||
|
||||
\[ \texttt{dst}(x,y) \leftarrow \texttt{dst}(x,y) + \texttt{src}(x,y)^2 \quad \text{if} \quad \texttt{mask}(x,y) \ne 0 \]
|
||||
|
||||
The function supports multi-channel images; each channel is processed independently.
|
||||
|
||||
See also: \cvCppCross{accumulateSquare}, \cvCppCross{accumulateProduct}, \cvCppCross{accumulateWeighted}
|
||||
|
||||
\cvCppFunc{accumulateProduct}
|
||||
Adds the per-element product of two input images to the accumulator.
|
||||
|
||||
\cvdefCpp{void accumulateProduct( const Mat\& src1, const Mat\& src2,\par
|
||||
Mat\& dst, const Mat\& mask=Mat() );}
|
||||
\begin{description}
|
||||
\cvarg{src1}{The first input image, 1- or 3-channel, 8-bit or 32-bit floating point}
|
||||
\cvarg{src2}{The second input image of the same type and the same size as \texttt{src1}}
|
||||
\cvarg{dst}{Accumulator with the same number of channels as input images, 32-bit or 64-bit floating-point}
|
||||
\cvarg{mask}{Optional operation mask}
|
||||
\end{description}
|
||||
|
||||
The function adds the product of 2 images or their selected regions to the accumulator \texttt{dst}:
|
||||
|
||||
\[ \texttt{dst}(x,y) \leftarrow \texttt{dst}(x,y) + \texttt{src1}(x,y) \cdot \texttt{src2}(x,y) \quad \text{if} \quad \texttt{mask}(x,y) \ne 0 \]
|
||||
|
||||
The function supports multi-channel images; each channel is processed independently.
|
||||
|
||||
See also: \cvCppCross{accumulate}, \cvCppCross{accumulateSquare}, \cvCppCross{accumulateWeighted}
|
||||
|
||||
\cvCppFunc{accumulateWeighted}
|
||||
Updates the running average.
|
||||
|
||||
\cvdefCpp{void accumulateWeighted( const Mat\& src, Mat\& dst,\par
|
||||
double alpha, const Mat\& mask=Mat() );}
|
||||
\begin{description}
|
||||
\cvarg{src}{The input image, 1- or 3-channel, 8-bit or 32-bit floating point}
|
||||
\cvarg{dst}{The accumulator image with the same number of channels as input image, 32-bit or 64-bit floating-point}
|
||||
\cvarg{alpha}{Weight of the input image}
|
||||
\cvarg{mask}{Optional operation mask}
|
||||
\end{description}
|
||||
|
||||
The function calculates the weighted sum of the input image
|
||||
\texttt{src} and the accumulator \texttt{dst} so that \texttt{dst}
|
||||
becomes a running average of frame sequence:
|
||||
|
||||
\[ \texttt{dst}(x,y) \leftarrow (1-\texttt{alpha}) \cdot \texttt{dst}(x,y) + \texttt{alpha} \cdot \texttt{src}(x,y) \quad \text{if} \quad \texttt{mask}(x,y) \ne 0 \]
|
||||
|
||||
that is, \texttt{alpha} regulates the update speed (how fast the accumulator "forgets" about earlier images).
|
||||
The function supports multi-channel images; each channel is processed independently.
|
||||
|
||||
See also: \cvCppCross{accumulate}, \cvCppCross{accumulateSquare}, \cvCppCross{accumulateProduct}
|
||||
|
||||
\fi
|
@ -1,138 +0,0 @@
|
||||
%[TODO: from objdetect]
|
||||
\section{Object Detection}
|
||||
|
||||
\ifCPy
|
||||
\cvCPyFunc{MatchTemplate}
|
||||
Compares a template against overlapped image regions.
|
||||
|
||||
\cvdefC{
|
||||
void cvMatchTemplate( \par const CvArr* image,\par const CvArr* templ,\par CvArr* result,\par int method );
|
||||
}\cvdefPy{MatchTemplate(image,templ,result,method)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Image where the search is running; should be 8-bit or 32-bit floating-point}
|
||||
\cvarg{templ}{Searched template; must be not greater than the source image and the same data type as the image}
|
||||
\cvarg{result}{A map of comparison results; single-channel 32-bit floating-point.
|
||||
If \texttt{image} is $W \times H$ and
|
||||
\texttt{templ} is $w \times h$ then \texttt{result} must be $(W-w+1) \times (H-h+1)$}
|
||||
\cvarg{method}{Specifies the way the template must be compared with the image regions (see below)}
|
||||
\end{description}
|
||||
|
||||
The function is similar to
|
||||
\cvCPyCross{CalcBackProjectPatch}. It slides through \texttt{image}, compares the
|
||||
overlapped patches of size $w \times h$ against \texttt{templ}
|
||||
using the specified method and stores the comparison results to
|
||||
\texttt{result}. Here are the formulas for the different comparison
|
||||
methods one may use ($I$ denotes \texttt{image}, $T$ \texttt{template},
|
||||
$R$ \texttt{result}). The summation is done over template and/or the
|
||||
image patch: $x' = 0...w-1, y' = 0...h-1$
|
||||
|
||||
% \texttt{x'=0..w-1, y'=0..h-1}):
|
||||
|
||||
\begin{description}
|
||||
\item[method=CV\_TM\_SQDIFF]
|
||||
\[ R(x,y)=\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2 \]
|
||||
|
||||
\item[method=CV\_TM\_SQDIFF\_NORMED]
|
||||
\[ R(x,y)=\frac
|
||||
{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}
|
||||
{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}
|
||||
\]
|
||||
|
||||
\item[method=CV\_TM\_CCORR]
|
||||
\[ R(x,y)=\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y')) \]
|
||||
|
||||
\item[method=CV\_TM\_CCORR\_NORMED]
|
||||
\[ R(x,y)=\frac
|
||||
{\sum_{x',y'} (T(x',y') \cdot I'(x+x',y+y'))}
|
||||
{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}
|
||||
\]
|
||||
|
||||
\item[method=CV\_TM\_CCOEFF]
|
||||
\[ R(x,y)=\sum_{x',y'} (T'(x',y') \cdot I(x+x',y+y')) \]
|
||||
|
||||
where
|
||||
\[
|
||||
\begin{array}{l}
|
||||
T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum_{x'',y''} T(x'',y'')\\
|
||||
I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h) \cdot \sum_{x'',y''} I(x+x'',y+y'')
|
||||
\end{array}
|
||||
\]
|
||||
|
||||
\item[method=CV\_TM\_CCOEFF\_NORMED]
|
||||
\[ R(x,y)=\frac
|
||||
{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }
|
||||
{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }
|
||||
\]
|
||||
\end{description}
|
||||
|
||||
After the function finishes the comparison, the best matches can be found as global minimums (\texttt{CV\_TM\_SQDIFF}) or maximums (\texttt{CV\_TM\_CCORR} and \texttt{CV\_TM\_CCOEFF}) using the \cvCPyCross{MinMaxLoc} function. In the case of a color image, template summation in the numerator and each sum in the denominator is done over all of the channels (and separate mean values are used for each channel).
|
||||
|
||||
\fi
|
||||
|
||||
\ifCpp
|
||||
|
||||
\cvCppFunc{matchTemplate}
|
||||
Compares a template against overlapped image regions.
|
||||
|
||||
\cvdefCpp{void matchTemplate( const Mat\& image, const Mat\& templ,\par
|
||||
Mat\& result, int method );}
|
||||
\begin{description}
|
||||
\cvarg{image}{Image where the search is running; should be 8-bit or 32-bit floating-point}
|
||||
\cvarg{templ}{Searched template; must be not greater than the source image and have the same data type}
|
||||
\cvarg{result}{A map of comparison results; will be single-channel 32-bit floating-point.
|
||||
If \texttt{image} is $W \times H$ and
|
||||
\texttt{templ} is $w \times h$ then \texttt{result} will be $(W-w+1) \times (H-h+1)$}
|
||||
\cvarg{method}{Specifies the comparison method (see below)}
|
||||
\end{description}
|
||||
|
||||
The function slides through \texttt{image}, compares the
|
||||
overlapped patches of size $w \times h$ against \texttt{templ}
|
||||
using the specified method and stores the comparison results to
|
||||
\texttt{result}. Here are the formulas for the available comparison
|
||||
methods ($I$ denotes \texttt{image}, $T$ \texttt{template},
|
||||
$R$ \texttt{result}). The summation is done over template and/or the
|
||||
image patch: $x' = 0...w-1, y' = 0...h-1$
|
||||
|
||||
% \texttt{x'=0..w-1, y'=0..h-1}):
|
||||
|
||||
\begin{description}
|
||||
\item[method=CV\_TM\_SQDIFF]
|
||||
\[ R(x,y)=\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2 \]
|
||||
|
||||
\item[method=CV\_TM\_SQDIFF\_NORMED]
|
||||
\[ R(x,y)=\frac
|
||||
{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}
|
||||
{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}
|
||||
\]
|
||||
|
||||
\item[method=CV\_TM\_CCORR]
|
||||
\[ R(x,y)=\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y')) \]
|
||||
|
||||
\item[method=CV\_TM\_CCORR\_NORMED]
|
||||
\[ R(x,y)=\frac
|
||||
{\sum_{x',y'} (T(x',y') \cdot I'(x+x',y+y'))}
|
||||
{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}
|
||||
\]
|
||||
|
||||
\item[method=CV\_TM\_CCOEFF]
|
||||
\[ R(x,y)=\sum_{x',y'} (T'(x',y') \cdot I(x+x',y+y')) \]
|
||||
|
||||
where
|
||||
\[
|
||||
\begin{array}{l}
|
||||
T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum_{x'',y''} T(x'',y'')\\
|
||||
I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h) \cdot \sum_{x'',y''} I(x+x'',y+y'')
|
||||
\end{array}
|
||||
\]
|
||||
|
||||
\item[method=CV\_TM\_CCOEFF\_NORMED]
|
||||
\[ R(x,y)=\frac
|
||||
{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }
|
||||
{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }
|
||||
\]
|
||||
\end{description}
|
||||
|
||||
After the function finishes the comparison, the best matches can be found as global minimums (when \texttt{CV\_TM\_SQDIFF} was used) or maximums (when \texttt{CV\_TM\_CCORR} or \texttt{CV\_TM\_CCOEFF} was used) using the \cvCppCross{minMaxLoc} function. In the case of a color image, template summation in the numerator and each sum in the denominator is done over all of the channels (and separate mean values are used for each channel). That is, the function can take a color template and a color image; the result will still be a single-channel image, which is easier to analyze.
|
||||
|
||||
\fi
|
@ -1,325 +0,0 @@
|
||||
\section{Planar Subdivisions}
|
||||
|
||||
\ifCPy
|
||||
|
||||
\cvclass{CvSubdiv2D}\label{CvSubdiv2D}
|
||||
|
||||
Planar subdivision.
|
||||
|
||||
\ifC
|
||||
\begin{lstlisting}
|
||||
#define CV_SUBDIV2D_FIELDS() \
|
||||
CV_GRAPH_FIELDS() \
|
||||
int quad_edges; \
|
||||
int is_geometry_valid; \
|
||||
CvSubdiv2DEdge recent_edge; \
|
||||
CvPoint2D32f topleft; \
|
||||
CvPoint2D32f bottomright;
|
||||
|
||||
typedef struct CvSubdiv2D
|
||||
{
|
||||
CV_SUBDIV2D_FIELDS()
|
||||
}
|
||||
CvSubdiv2D;
|
||||
\end{lstlisting}
|
||||
\else
|
||||
\begin{description}
|
||||
\cvarg{edges}{A \cross{CvSet} of \cross{CvSubdiv2DEdge}}
|
||||
\end{description}
|
||||
\fi
|
||||
|
||||
Planar subdivision is the subdivision of a plane into a set of
|
||||
non-overlapped regions (facets) that cover the whole plane. The above
|
||||
structure describes a subdivision built on a 2d point set, where the points
|
||||
are linked together and form a planar graph, which, together with a few
|
||||
edges connecting the exterior subdivision points (namely, convex hull points)
|
||||
with infinity, subdivides a plane into facets by its edges.
|
||||
|
||||
For every subdivision there exists a dual subdivision in which facets and
|
||||
points (subdivision vertices) swap their roles, that is, a facet is
|
||||
treated as a vertex (called a virtual point below) of the dual subdivision and
|
||||
the original subdivision vertices become facets. On the picture below
|
||||
original subdivision is marked with solid lines and dual subdivision
|
||||
with dotted lines.
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/subdiv.png}
|
||||
|
||||
OpenCV subdivides a plane into triangles using Delaunay's
|
||||
algorithm. Subdivision is built iteratively starting from a dummy
|
||||
triangle that includes all the subdivision points for sure. In this
|
||||
case the dual subdivision is a Voronoi diagram of the input 2d point set. The
|
||||
subdivisions can be used for the 3d piece-wise transformation of a plane,
|
||||
morphing, fast location of points on the plane, building special graphs
|
||||
(such as NNG,RNG) and so forth.
|
||||
|
||||
\ifC
|
||||
\cvclass{CvQuadEdge2D}\label{CvQuadEdge2D}
|
||||
|
||||
Quad-edge of planar subdivision.
|
||||
|
||||
\begin{lstlisting}
|
||||
/* one of edges within quad-edge, lower 2 bits is index (0..3)
|
||||
and upper bits are quad-edge pointer */
|
||||
typedef long CvSubdiv2DEdge;
|
||||
|
||||
/* quad-edge structure fields */
|
||||
#define CV_QUADEDGE2D_FIELDS() \
|
||||
int flags; \
|
||||
struct CvSubdiv2DPoint* pt[4]; \
|
||||
CvSubdiv2DEdge next[4];
|
||||
|
||||
typedef struct CvQuadEdge2D
|
||||
{
|
||||
CV_QUADEDGE2D_FIELDS()
|
||||
}
|
||||
CvQuadEdge2D;
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
Quad-edge is a basic element of subdivision containing four edges (e, eRot, reversed e and reversed eRot):
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/quadedge.png}
|
||||
\fi
|
||||
|
||||
\cvclass{CvSubdiv2DPoint}\label{CvSubdiv2DPoint}
|
||||
|
||||
\ifC
|
||||
Point of original or dual subdivision.
|
||||
|
||||
\begin{lstlisting}
|
||||
#define CV_SUBDIV2D_POINT_FIELDS()\
|
||||
int flags; \
|
||||
CvSubdiv2DEdge first; \
|
||||
CvPoint2D32f pt; \
|
||||
int id;
|
||||
|
||||
#define CV_SUBDIV2D_VIRTUAL_POINT_FLAG (1 << 30)
|
||||
|
||||
typedef struct CvSubdiv2DPoint
|
||||
{
|
||||
CV_SUBDIV2D_POINT_FIELDS()
|
||||
}
|
||||
CvSubdiv2DPoint;
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{itemize}
|
||||
\item[id] This integer can be used to index auxillary data associated with each vertex of the planar subdivision
|
||||
\end{itemize}
|
||||
\else
|
||||
Point of original or dual subdivision.
|
||||
|
||||
\begin{description}
|
||||
\cvarg{first}{A connected \cross{CvSubdiv2DEdge}}
|
||||
\cvarg{pt}{Position, as a \cross{CvPoint2D32f}}
|
||||
\end{description}
|
||||
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{CalcSubdivVoronoi2D}
|
||||
Calculates the coordinates of Voronoi diagram cells.
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcSubdivVoronoi2D( \par CvSubdiv2D* subdiv );
|
||||
}
|
||||
\cvdefPy{CalcSubdivVoronoi2D(subdiv)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{subdiv}{Delaunay subdivision, in which all the points are already added}
|
||||
\end{description}
|
||||
|
||||
The function calculates the coordinates
|
||||
of virtual points. All virtual points corresponding to some vertex of the
|
||||
original subdivision form (when connected together) a boundary of the Voronoi
|
||||
cell at that point.
|
||||
|
||||
\cvCPyFunc{ClearSubdivVoronoi2D}
|
||||
Removes all virtual points.
|
||||
|
||||
\cvdefC{
|
||||
void cvClearSubdivVoronoi2D( CvSubdiv2D* subdiv );
|
||||
}\cvdefPy{ClearSubdivVoronoi2D(subdiv)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{subdiv}{Delaunay subdivision}
|
||||
\end{description}
|
||||
|
||||
The function removes all of the virtual points. It
|
||||
is called internally in \cvCPyCross{CalcSubdivVoronoi2D} if the subdivision
|
||||
was modified after previous call to the function.
|
||||
|
||||
|
||||
\cvCPyFunc{CreateSubdivDelaunay2D}
|
||||
Creates an empty Delaunay triangulation.
|
||||
|
||||
\cvdefC{
|
||||
CvSubdiv2D* cvCreateSubdivDelaunay2D( \par CvRect rect,\par CvMemStorage* storage );
|
||||
}\cvdefPy{CreateSubdivDelaunay2D(rect,storage)-> delaunay\_triangulation}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{rect}{Rectangle that includes all of the 2d points that are to be added to the subdivision}
|
||||
\cvarg{storage}{Container for subdivision}
|
||||
\end{description}
|
||||
|
||||
The function creates an empty Delaunay
|
||||
subdivision, where 2d points can be added using the function
|
||||
\cvCPyCross{SubdivDelaunay2DInsert}. All of the points to be added must be within
|
||||
the specified rectangle, otherwise a runtime error will be raised.
|
||||
|
||||
Note that the triangulation is a single large triangle that covers the given rectangle. Hence the three vertices of this triangle are outside the rectangle \texttt{rect}.
|
||||
|
||||
\cvCPyFunc{FindNearestPoint2D}
|
||||
Finds the closest subdivision vertex to the given point.
|
||||
|
||||
\cvdefC{
|
||||
CvSubdiv2DPoint* cvFindNearestPoint2D( \par CvSubdiv2D* subdiv,\par CvPoint2D32f pt );
|
||||
}\cvdefPy{FindNearestPoint2D(subdiv,pt)-> point}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{subdiv}{Delaunay or another subdivision}
|
||||
\cvarg{pt}{Input point}
|
||||
\end{description}
|
||||
|
||||
The function is another function that
|
||||
locates the input point within the subdivision. It finds the subdivision vertex that
|
||||
is the closest to the input point. It is not necessarily one of vertices
|
||||
of the facet containing the input point, though the facet (located using
|
||||
\cvCPyCross{Subdiv2DLocate}) is used as a starting
|
||||
point. The function returns a pointer to the found subdivision vertex.
|
||||
|
||||
\cvCPyFunc{Subdiv2DEdgeDst}
|
||||
Returns the edge destination.
|
||||
|
||||
\cvdefC{
|
||||
CvSubdiv2DPoint* cvSubdiv2DEdgeDst( \par CvSubdiv2DEdge edge );
|
||||
}
|
||||
\cvdefPy{Subdiv2DEdgeDst(edge)-> point}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{edge}{Subdivision edge (not a quad-edge)}
|
||||
\end{description}
|
||||
|
||||
The function returns the edge destination. The
|
||||
returned pointer may be NULL if the edge is from dual subdivision and
|
||||
the virtual point coordinates are not calculated yet. The virtual points
|
||||
can be calculated using the function \cvCPyCross{CalcSubdivVoronoi2D}.
|
||||
|
||||
\cvCPyFunc{Subdiv2DGetEdge}
|
||||
Returns one of the edges related to the given edge.
|
||||
|
||||
\cvdefC{
|
||||
CvSubdiv2DEdge cvSubdiv2DGetEdge( CvSubdiv2DEdge edge, CvNextEdgeType type );
|
||||
|
||||
|
||||
}\cvdefPy{Subdiv2DGetEdge(edge,type)-> CvSubdiv2DEdge}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{edge}{Subdivision edge (not a quad-edge)}
|
||||
\cvarg{type}{Specifies which of the related edges to return, one of the following:}
|
||||
\begin{description}
|
||||
\cvarg{CV\_NEXT\_AROUND\_ORG}{next around the edge origin (\texttt{eOnext} on the picture below if \texttt{e} is the input edge)}
|
||||
\cvarg{CV\_NEXT\_AROUND\_DST}{next around the edge vertex (\texttt{eDnext})}
|
||||
\cvarg{CV\_PREV\_AROUND\_ORG}{previous around the edge origin (reversed \texttt{eRnext})}
|
||||
\cvarg{CV\_PREV\_AROUND\_DST}{previous around the edge destination (reversed \texttt{eLnext})}
|
||||
\cvarg{CV\_NEXT\_AROUND\_LEFT}{next around the left facet (\texttt{eLnext})}
|
||||
\cvarg{CV\_NEXT\_AROUND\_RIGHT}{next around the right facet (\texttt{eRnext})}
|
||||
\cvarg{CV\_PREV\_AROUND\_LEFT}{previous around the left facet (reversed \texttt{eOnext})}
|
||||
\cvarg{CV\_PREV\_AROUND\_RIGHT}{previous around the right facet (reversed \texttt{eDnext})}
|
||||
\end{description}
|
||||
\end{description}
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/quadedge.png}
|
||||
|
||||
The function returns one of the edges related to the input edge.
|
||||
|
||||
\cvCPyFunc{Subdiv2DNextEdge}
|
||||
Returns next edge around the edge origin
|
||||
|
||||
\cvdefC{
|
||||
CvSubdiv2DEdge cvSubdiv2DNextEdge( CvSubdiv2DEdge edge );
|
||||
}
|
||||
\cvdefPy{Subdiv2DNextEdge(edge)-> CvSubdiv2DEdge}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{edge}{Subdivision edge (not a quad-edge)}
|
||||
\end{description}
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/quadedge.png}
|
||||
|
||||
The function returns the next edge around the edge origin: \texttt{eOnext} on the picture above if \texttt{e} is the input edge)
|
||||
|
||||
\cvCPyFunc{Subdiv2DLocate}
|
||||
Returns the location of a point within a Delaunay triangulation.
|
||||
|
||||
\cvdefC{
|
||||
CvSubdiv2DPointLocation cvSubdiv2DLocate( \par CvSubdiv2D* subdiv,\par CvPoint2D32f pt,\par CvSubdiv2DEdge* edge,\par CvSubdiv2DPoint** vertex=NULL );
|
||||
}
|
||||
\cvdefPy{Subdiv2DLocate(subdiv, pt) -> (loc, where)}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{subdiv}{Delaunay or another subdivision}
|
||||
\cvarg{pt}{The point to locate}
|
||||
\cvC{\cvarg{edge}{The output edge the point falls onto or right to}}
|
||||
\cvC{\cvarg{vertex}{Optional output vertex double pointer the input point coinsides with}}
|
||||
\cvPy{\cvarg{loc}{The location of the point within the triangulation}}
|
||||
\cvPy{\cvarg{where}{The edge or vertex. See below.}}
|
||||
\end{description}
|
||||
|
||||
The function locates the input point within the subdivision. There are 5 cases:
|
||||
|
||||
\ifC
|
||||
\begin{itemize}
|
||||
\item The point falls into some facet. The function returns \texttt{CV\_PTLOC\_INSIDE} and \texttt{*edge} will contain one of edges of the facet.
|
||||
\item The point falls onto the edge. The function returns \texttt{CV\_PTLOC\_ON\_EDGE} and \texttt{*edge} will contain this edge.
|
||||
\item The point coincides with one of the subdivision vertices. The function returns \texttt{CV\_PTLOC\_VERTEX} and \texttt{*vertex} will contain a pointer to the vertex.
|
||||
\item The point is outside the subdivsion reference rectangle. The function returns \texttt{CV\_PTLOC\_OUTSIDE\_RECT} and no pointers are filled.
|
||||
\item One of input arguments is invalid. A runtime error is raised or, if silent or "parent" error processing mode is selected, \texttt{CV\_PTLOC\_ERROR} is returnd.
|
||||
\end{itemize}
|
||||
\fi
|
||||
|
||||
\ifPy
|
||||
\begin{itemize}
|
||||
\item The point falls into some facet. \texttt{loc} is \texttt{CV\_PTLOC\_INSIDE} and \texttt{where} is one of edges of the facet.
|
||||
\item The point falls onto the edge. \texttt{loc} is \texttt{CV\_PTLOC\_ON\_EDGE} and \texttt{where} is the edge.
|
||||
\item The point coincides with one of the subdivision vertices. \texttt{loc} is \texttt{CV\_PTLOC\_VERTEX} and \texttt{where} is the vertex.
|
||||
\item The point is outside the subdivsion reference rectangle. \texttt{loc} is \texttt{CV\_PTLOC\_OUTSIDE\_RECT} and \texttt{where} is None.
|
||||
\item One of input arguments is invalid. The function raises an exception.
|
||||
\end{itemize}
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{Subdiv2DRotateEdge}
|
||||
Returns another edge of the same quad-edge.
|
||||
|
||||
\cvdefC{
|
||||
CvSubdiv2DEdge cvSubdiv2DRotateEdge( \par CvSubdiv2DEdge edge,\par int rotate );
|
||||
}\cvdefPy{Subdiv2DRotateEdge(edge,rotate)-> CvSubdiv2DEdge}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{edge}{Subdivision edge (not a quad-edge)}
|
||||
\cvarg{rotate}{Specifies which of the edges of the same quad-edge as the input one to return, one of the following:
|
||||
\begin{description}
|
||||
\cvarg{0}{the input edge (\texttt{e} on the picture below if \texttt{e} is the input edge)}
|
||||
\cvarg{1}{the rotated edge (\texttt{eRot})}
|
||||
\cvarg{2}{the reversed edge (reversed \texttt{e} (in green))}
|
||||
\cvarg{3}{the reversed rotated edge (reversed \texttt{eRot} (in green))}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/quadedge.png}
|
||||
|
||||
The function returns one of the edges of the same quad-edge as the input edge.
|
||||
|
||||
\cvCPyFunc{SubdivDelaunay2DInsert}
|
||||
Inserts a single point into a Delaunay triangulation.
|
||||
|
||||
\cvdefC{
|
||||
CvSubdiv2DPoint* cvSubdivDelaunay2DInsert( \par CvSubdiv2D* subdiv,\par CvPoint2D32f pt);
|
||||
}\cvdefPy{SubdivDelaunay2DInsert(subdiv,pt)-> point}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{subdiv}{Delaunay subdivision created by the function \cvCPyCross{CreateSubdivDelaunay2D}}
|
||||
\cvarg{pt}{Inserted point}
|
||||
\end{description}
|
||||
|
||||
The function inserts a single point into a subdivision and modifies the subdivision topology appropriately. If a point with the same coordinates exists already, no new point is added. The function returns a pointer to the allocated point. No virtual point coordinates are calculated at this stage.
|
||||
|
||||
\fi
|
File diff suppressed because it is too large
Load Diff
2083
doc/ml.tex
2083
doc/ml.tex
File diff suppressed because it is too large
Load Diff
@ -1,784 +0,0 @@
|
||||
\section{Cascade Classification}
|
||||
|
||||
\ifCPy
|
||||
|
||||
\subsection{Haar Feature-based Cascade Classifier for Object Detection}
|
||||
|
||||
The object detector described below has been initially proposed by Paul Viola
|
||||
\cvCPyCross{Viola01}
|
||||
and improved by Rainer Lienhart
|
||||
\cvCPyCross{Lienhart02}
|
||||
. First, a classifier (namely a \emph{cascade of boosted classifiers working with haar-like features}) is trained with a few hundred sample views of a particular object (i.e., a face or a car), called positive examples, that are scaled to the same size (say, 20x20), and negative examples - arbitrary images of the same size.
|
||||
|
||||
After a classifier is trained, it can be applied to a region of interest
|
||||
(of the same size as used during the training) in an input image. The
|
||||
classifier outputs a "1" if the region is likely to show the object
|
||||
(i.e., face/car), and "0" otherwise. To search for the object in the
|
||||
whole image one can move the search window across the image and check
|
||||
every location using the classifier. The classifier is designed so that
|
||||
it can be easily "resized" in order to be able to find the objects of
|
||||
interest at different sizes, which is more efficient than resizing the
|
||||
image itself. So, to find an object of an unknown size in the image the
|
||||
scan procedure should be done several times at different scales.
|
||||
|
||||
The word "cascade" in the classifier name means that the resultant
|
||||
classifier consists of several simpler classifiers (\emph{stages}) that
|
||||
are applied subsequently to a region of interest until at some stage the
|
||||
candidate is rejected or all the stages are passed. The word "boosted"
|
||||
means that the classifiers at every stage of the cascade are complex
|
||||
themselves and they are built out of basic classifiers using one of four
|
||||
different \texttt{boosting} techniques (weighted voting). Currently
|
||||
Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost are
|
||||
supported. The basic classifiers are decision-tree classifiers with at
|
||||
least 2 leaves. Haar-like features are the input to the basic classifers,
|
||||
and are calculated as described below. The current algorithm uses the
|
||||
following Haar-like features:
|
||||
|
||||
\includegraphics[width=0.5\textwidth]{pics/haarfeatures.png}
|
||||
|
||||
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 \cvCPyCross{Integral} description).
|
||||
|
||||
\ifPy
|
||||
A simple demonstration of face detection, which draws a rectangle around each detected face:
|
||||
|
||||
\begin{lstlisting}
|
||||
|
||||
hc = cv.Load("haarcascade_frontalface_default.xml")
|
||||
img = cv.LoadImage("faces.jpg", 0)
|
||||
faces = cv.HaarDetectObjects(img, hc, cv.CreateMemStorage())
|
||||
for (x,y,w,h),n in faces:
|
||||
cv.Rectangle(img, (x,y), (x+w,y+h), 255)
|
||||
cv.SaveImage("faces_detected.jpg", img)
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\fi
|
||||
|
||||
\ifC
|
||||
To see the object detector at work, have a look at the HaarFaceDetect demo.
|
||||
|
||||
The following reference is for the detection part only. There
|
||||
is a separate application called \texttt{haartraining} that can
|
||||
train a cascade of boosted classifiers from a set of samples. See
|
||||
\texttt{opencv/apps/haartraining} for details.
|
||||
|
||||
\cvclass{CvHaarFeature, CvHaarClassifier, CvHaarStageClassifier, CvHaarClassifierCascade}
|
||||
\label{CvHaarFeature}
|
||||
\label{CvHaarClassifier}
|
||||
\label{CvHaarStageClassifier}
|
||||
\label{CvHaarClassifierCascade}
|
||||
|
||||
Boosted Haar classifier structures.
|
||||
|
||||
\begin{lstlisting}
|
||||
#define CV_HAAR_FEATURE_MAX 3
|
||||
|
||||
/* a haar feature consists of 2-3 rectangles with appropriate weights */
|
||||
typedef struct CvHaarFeature
|
||||
{
|
||||
int tilted; /* 0 means up-right feature, 1 means 45--rotated feature */
|
||||
|
||||
/* 2-3 rectangles with weights of opposite signs and
|
||||
with absolute values inversely proportional to the areas of the
|
||||
rectangles. If rect[2].weight !=0, then
|
||||
the feature consists of 3 rectangles, otherwise it consists of 2 */
|
||||
struct
|
||||
{
|
||||
CvRect r;
|
||||
float weight;
|
||||
} rect[CV_HAAR_FEATURE_MAX];
|
||||
}
|
||||
CvHaarFeature;
|
||||
|
||||
/* a single tree classifier (stump in the simplest case) that returns the
|
||||
response for the feature at the particular image location (i.e. pixel
|
||||
sum over subrectangles of the window) and gives out a value depending
|
||||
on the response */
|
||||
typedef struct CvHaarClassifier
|
||||
{
|
||||
int count; /* number of nodes in the decision tree */
|
||||
|
||||
/* these are "parallel" arrays. Every index \texttt{i}
|
||||
corresponds to a node of the decision tree (root has 0-th index).
|
||||
|
||||
left[i] - index of the left child (or negated index if the
|
||||
left child is a leaf)
|
||||
right[i] - index of the right child (or negated index if the
|
||||
right child is a leaf)
|
||||
threshold[i] - branch threshold. if feature responce is <= threshold,
|
||||
left branch is chosen, otherwise right branch is chosen.
|
||||
alpha[i] - output value correponding to the leaf. */
|
||||
CvHaarFeature* haar_feature;
|
||||
float* threshold;
|
||||
int* left;
|
||||
int* right;
|
||||
float* alpha;
|
||||
}
|
||||
CvHaarClassifier;
|
||||
|
||||
/* a boosted battery of classifiers(=stage classifier):
|
||||
the stage classifier returns 1
|
||||
if the sum of the classifiers responses
|
||||
is greater than \texttt{threshold} and 0 otherwise */
|
||||
typedef struct CvHaarStageClassifier
|
||||
{
|
||||
int count; /* number of classifiers in the battery */
|
||||
float threshold; /* threshold for the boosted classifier */
|
||||
CvHaarClassifier* classifier; /* array of classifiers */
|
||||
|
||||
/* these fields are used for organizing trees of stage classifiers,
|
||||
rather than just stright cascades */
|
||||
int next;
|
||||
int child;
|
||||
int parent;
|
||||
}
|
||||
CvHaarStageClassifier;
|
||||
|
||||
typedef struct CvHidHaarClassifierCascade CvHidHaarClassifierCascade;
|
||||
|
||||
/* cascade or tree of stage classifiers */
|
||||
typedef struct CvHaarClassifierCascade
|
||||
{
|
||||
int flags; /* signature */
|
||||
int count; /* number of stages */
|
||||
CvSize orig_window_size; /* original object size (the cascade is
|
||||
trained for) */
|
||||
|
||||
/* these two parameters are set by cvSetImagesForHaarClassifierCascade */
|
||||
CvSize real_window_size; /* current object size */
|
||||
double scale; /* current scale */
|
||||
CvHaarStageClassifier* stage_classifier; /* array of stage classifiers */
|
||||
CvHidHaarClassifierCascade* hid_cascade; /* hidden optimized
|
||||
representation of the
|
||||
cascade, created by
|
||||
cvSetImagesForHaarClassifierCascade */
|
||||
}
|
||||
CvHaarClassifierCascade;
|
||||
\end{lstlisting}
|
||||
|
||||
All the structures are used for representing a cascaded of boosted Haar classifiers. The cascade has the following hierarchical structure:
|
||||
|
||||
\begin{verbatim}
|
||||
Cascade:
|
||||
Stage,,1,,:
|
||||
Classifier,,11,,:
|
||||
Feature,,11,,
|
||||
Classifier,,12,,:
|
||||
Feature,,12,,
|
||||
...
|
||||
Stage,,2,,:
|
||||
Classifier,,21,,:
|
||||
Feature,,21,,
|
||||
...
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
The whole hierarchy can be constructed manually or loaded from a file or an embedded base using the function \cvCPyCross{LoadHaarClassifierCascade}.
|
||||
|
||||
\cvCPyFunc{LoadHaarClassifierCascade}
|
||||
Loads a trained cascade classifier from a file or the classifier database embedded in OpenCV.
|
||||
|
||||
\cvdefC{
|
||||
CvHaarClassifierCascade* cvLoadHaarClassifierCascade( \par const char* directory,\par CvSize orig\_window\_size );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{directory}{Name of the directory containing the description of a trained cascade classifier}
|
||||
\cvarg{orig\_window\_size}{Original size of the objects the cascade has been trained on. Note that it is not stored in the cascade and therefore must be specified separately}
|
||||
\end{description}
|
||||
|
||||
The function loads a trained cascade
|
||||
of haar classifiers from a file or the classifier database embedded in
|
||||
OpenCV. The base can be trained using the \texttt{haartraining} application
|
||||
(see opencv/apps/haartraining for details).
|
||||
|
||||
\textbf{The function is obsolete}. Nowadays object detection classifiers are stored in XML or YAML files, rather than in directories. To load a cascade from a file, use the \cvCPyCross{Load} function.
|
||||
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{HaarDetectObjects}
|
||||
Detects objects in the image.
|
||||
|
||||
\ifC
|
||||
\begin{lstlisting}
|
||||
typedef struct CvAvgComp
|
||||
{
|
||||
CvRect rect; /* bounding rectangle for the object (average rectangle of a group) */
|
||||
int neighbors; /* number of neighbor rectangles in the group */
|
||||
}
|
||||
CvAvgComp;
|
||||
\end{lstlisting}
|
||||
\fi
|
||||
|
||||
\cvdefC{
|
||||
CvSeq* cvHaarDetectObjects( \par const CvArr* image,\par CvHaarClassifierCascade* cascade,\par CvMemStorage* storage,\par double scaleFactor=1.1,\par int minNeighbors=3,\par int flags=0,\par CvSize minSize=cvSize(0, 0),\par CvSize maxSize=cvSize(0,0) );
|
||||
}\cvdefPy{HaarDetectObjects(image,cascade,storage,scaleFactor=1.1,minNeighbors=3,flags=0,minSize=(0,0))-> detected\_objects}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Image to detect objects in}
|
||||
\cvarg{cascade}{Haar classifier cascade in internal representation}
|
||||
\cvarg{storage}{Memory storage to store the resultant sequence of the object candidate rectangles}
|
||||
\cvarg{scaleFactor}{The factor by which the search window is scaled between the subsequent scans, 1.1 means increasing window by 10\% }
|
||||
\cvarg{minNeighbors}{Minimum number (minus 1) of neighbor rectangles that makes up an object. All the groups of a smaller number of rectangles than \texttt{min\_neighbors}-1 are rejected. If \texttt{minNeighbors} is 0, the function does not any grouping at all and returns all the detected candidate rectangles, which may be useful if the user wants to apply a customized grouping procedure}
|
||||
\cvarg{flags}{Mode of operation. Currently the only flag that may be specified is \texttt{CV\_HAAR\_DO\_CANNY\_PRUNING}. If it is set, the function uses Canny edge detector to reject some image regions that contain too few or too much edges and thus can not contain the searched object. The particular threshold values are tuned for face detection and in this case the pruning speeds up the processing}
|
||||
\cvarg{minSize}{Minimum window size. By default, it is set to the size of samples the classifier has been trained on ($\sim 20\times 20$ for face detection)}
|
||||
\cvarg{maxSize}{Maximum window size to use. By default, it is set to the size of the image.}
|
||||
\end{description}
|
||||
|
||||
The function finds rectangular regions in the given image that are likely to contain objects the cascade has been trained for and returns those regions as a sequence of rectangles. The function scans the image several times at different scales (see \cvCPyCross{SetImagesForHaarClassifierCascade}). Each time it considers overlapping regions in the image and applies the classifiers to the regions using \cvCPyCross{RunHaarClassifierCascade}. It may also apply some heuristics to reduce number of analyzed regions, such as Canny prunning. After it has proceeded and collected the candidate rectangles (regions that passed the classifier cascade), it groups them and returns a sequence of average rectangles for each large enough group. The default parameters (\texttt{scale\_factor} =1.1, \texttt{min\_neighbors} =3, \texttt{flags} =0) are tuned for accurate yet slow object detection. For a faster operation on real video images the settings are: \texttt{scale\_factor} =1.2, \texttt{min\_neighbors} =2, \texttt{flags} =\texttt{CV\_HAAR\_DO\_CANNY\_PRUNING}, \texttt{min\_size} =\textit{minimum possible face size} (for example, $\sim$ 1/4 to 1/16 of the image area in the case of video conferencing).
|
||||
|
||||
\ifPy
|
||||
The function returns a list of tuples, \texttt{(rect, neighbors)}, where rect is a \cross{CvRect} specifying the object's extents
|
||||
and neighbors is a number of neighbors.
|
||||
|
||||
\begin{lstlisting}
|
||||
>>> import cv
|
||||
>>> image = cv.LoadImageM("lena.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE)
|
||||
>>> cascade = cv.Load("../../data/haarcascades/haarcascade_frontalface_alt.xml")
|
||||
>>> print cv.HaarDetectObjects(image, cascade, cv.CreateMemStorage(0), 1.2, 2, 0, (20, 20))
|
||||
[((217, 203, 169, 169), 24)]
|
||||
\end{lstlisting}
|
||||
\fi
|
||||
|
||||
\ifC
|
||||
% ===== Example. Using cascade of Haar classifiers to find objects (e.g. faces). =====
|
||||
\begin{lstlisting}
|
||||
#include "cv.h"
|
||||
#include "highgui.h"
|
||||
|
||||
CvHaarClassifierCascade* load_object_detector( const char* cascade_path )
|
||||
{
|
||||
return (CvHaarClassifierCascade*)cvLoad( cascade_path );
|
||||
}
|
||||
|
||||
void detect_and_draw_objects( IplImage* image,
|
||||
CvHaarClassifierCascade* cascade,
|
||||
int do_pyramids )
|
||||
{
|
||||
IplImage* small_image = image;
|
||||
CvMemStorage* storage = cvCreateMemStorage(0);
|
||||
CvSeq* faces;
|
||||
int i, scale = 1;
|
||||
|
||||
/* if the flag is specified, down-scale the input image to get a
|
||||
performance boost w/o loosing quality (perhaps) */
|
||||
if( do_pyramids )
|
||||
{
|
||||
small_image = cvCreateImage( cvSize(image->width/2,image->height/2), IPL_DEPTH_8U, 3 );
|
||||
cvPyrDown( image, small_image, CV_GAUSSIAN_5x5 );
|
||||
scale = 2;
|
||||
}
|
||||
|
||||
/* use the fastest variant */
|
||||
faces = cvHaarDetectObjects( small_image, cascade, storage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING );
|
||||
|
||||
/* draw all the rectangles */
|
||||
for( i = 0; i < faces->total; i++ )
|
||||
{
|
||||
/* extract the rectanlges only */
|
||||
CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i );
|
||||
cvRectangle( image, cvPoint(face_rect.x*scale,face_rect.y*scale),
|
||||
cvPoint((face_rect.x+face_rect.width)*scale,
|
||||
(face_rect.y+face_rect.height)*scale),
|
||||
CV_RGB(255,0,0), 3 );
|
||||
}
|
||||
|
||||
if( small_image != image )
|
||||
cvReleaseImage( &small_image );
|
||||
cvReleaseMemStorage( &storage );
|
||||
}
|
||||
|
||||
/* takes image filename and cascade path from the command line */
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
IplImage* image;
|
||||
if( argc==3 && (image = cvLoadImage( argv[1], 1 )) != 0 )
|
||||
{
|
||||
CvHaarClassifierCascade* cascade = load_object_detector(argv[2]);
|
||||
detect_and_draw_objects( image, cascade, 1 );
|
||||
cvNamedWindow( "test", 0 );
|
||||
cvShowImage( "test", image );
|
||||
cvWaitKey(0);
|
||||
cvReleaseHaarClassifierCascade( &cascade );
|
||||
cvReleaseImage( &image );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
\cvCPyFunc{SetImagesForHaarClassifierCascade}
|
||||
Assigns images to the hidden cascade.
|
||||
|
||||
\cvdefC{
|
||||
void cvSetImagesForHaarClassifierCascade( \par CvHaarClassifierCascade* cascade,\par const CvArr* sum,\par const CvArr* sqsum,\par const CvArr* tilted\_sum,\par double scale );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{cascade}{Hidden Haar classifier cascade, created by \cvCPyCross{CreateHidHaarClassifierCascade}}
|
||||
\cvarg{sum}{Integral (sum) single-channel image of 32-bit integer format. This image as well as the two subsequent images are used for fast feature evaluation and brightness/contrast normalization. They all can be retrieved from input 8-bit or floating point single-channel image using the function \cvCPyCross{Integral}}
|
||||
\cvarg{sqsum}{Square sum single-channel image of 64-bit floating-point format}
|
||||
\cvarg{tilted\_sum}{Tilted sum single-channel image of 32-bit integer format}
|
||||
\cvarg{scale}{Window scale for the cascade. If \texttt{scale} =1, the original window size is used (objects of that size are searched) - the same size as specified in \cvCPyCross{LoadHaarClassifierCascade} (24x24 in the case of \texttt{default\_face\_cascade}), if \texttt{scale} =2, a two times larger window is used (48x48 in the case of default face cascade). While this will speed-up search about four times, faces smaller than 48x48 cannot be detected}
|
||||
\end{description}
|
||||
|
||||
The function assigns images and/or window scale to the hidden classifier cascade. If image pointers are NULL, the previously set images are used further (i.e. NULLs mean "do not change images"). Scale parameter has no such a "protection" value, but the previous value can be retrieved by the \cvCPyCross{GetHaarClassifierCascadeScale} function and reused again. The function is used to prepare cascade for detecting object of the particular size in the particular image. The function is called internally by \cvCPyCross{HaarDetectObjects}, but it can be called by the user if they are using the lower-level function \cvCPyCross{RunHaarClassifierCascade}.
|
||||
|
||||
\cvCPyFunc{ReleaseHaarClassifierCascade}
|
||||
Releases the haar classifier cascade.
|
||||
|
||||
\cvdefC{
|
||||
void cvReleaseHaarClassifierCascade( \par CvHaarClassifierCascade** cascade );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{cascade}{Double pointer to the released cascade. The pointer is cleared by the function}
|
||||
\end{description}
|
||||
|
||||
The function deallocates the cascade that has been created manually or loaded using \cvCPyCross{LoadHaarClassifierCascade} or \cvCPyCross{Load}.
|
||||
|
||||
\cvCPyFunc{RunHaarClassifierCascade}
|
||||
Runs a cascade of boosted classifiers at the given image location.
|
||||
|
||||
\cvdefC{
|
||||
int cvRunHaarClassifierCascade( \par CvHaarClassifierCascade* cascade,\par CvPoint pt,\par int start\_stage=0 );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{cascade}{Haar classifier cascade}
|
||||
\cvarg{pt}{Top-left corner of the analyzed region. Size of the region is a original window size scaled by the currenly set scale. The current window size may be retrieved using the \cvCPyCross{GetHaarClassifierCascadeWindowSize} function}
|
||||
\cvarg{start\_stage}{Initial zero-based index of the cascade stage to start from. The function assumes that all the previous stages are passed. This feature is used internally by \cvCPyCross{HaarDetectObjects} for better processor cache utilization}
|
||||
\end{description}
|
||||
|
||||
The function runs the Haar classifier
|
||||
cascade at a single image location. Before using this function the
|
||||
integral images and the appropriate scale (window size) should be set
|
||||
using \cvCPyCross{SetImagesForHaarClassifierCascade}. The function returns
|
||||
a positive value if the analyzed rectangle passed all the classifier stages
|
||||
(it is a candidate) and a zero or negative value otherwise.
|
||||
|
||||
\fi
|
||||
|
||||
\fi
|
||||
|
||||
\ifCpp
|
||||
|
||||
\cvclass{FeatureEvaluator}
|
||||
Base class for computing feature values in cascade classifiers.
|
||||
|
||||
\begin{lstlisting}
|
||||
class CV_EXPORTS FeatureEvaluator
|
||||
{
|
||||
public:
|
||||
enum { HAAR = 0, LBP = 1 }; // supported feature types
|
||||
virtual ~FeatureEvaluator(); // destructor
|
||||
virtual bool read(const FileNode& node);
|
||||
virtual Ptr<FeatureEvaluator> clone() const;
|
||||
virtual int getFeatureType() const;
|
||||
|
||||
virtual bool setImage(const Mat& img, Size origWinSize);
|
||||
virtual bool setWindow(Point p);
|
||||
|
||||
virtual double calcOrd(int featureIdx) const;
|
||||
virtual int calcCat(int featureIdx) const;
|
||||
|
||||
static Ptr<FeatureEvaluator> create(int type);
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{FeatureEvaluator::read}
|
||||
Reads parameters of the features from a FileStorage node.
|
||||
|
||||
\cvdefCpp{
|
||||
bool FeatureEvaluator::read(const FileNode\& node);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{node}{File node from which the feature parameters are read.}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{FeatureEvaluator::clone}
|
||||
Returns a full copy of the feature evaluator.
|
||||
|
||||
\cvdefCpp{
|
||||
Ptr<FeatureEvaluator> FeatureEvaluator::clone() const;
|
||||
}
|
||||
|
||||
\cvCppFunc{FeatureEvaluator::getFeatureType}
|
||||
Returns the feature type (HAAR or LBP for now).
|
||||
|
||||
\cvdefCpp{
|
||||
int FeatureEvaluator::getFeatureType() const;
|
||||
}
|
||||
|
||||
\cvCppFunc{FeatureEvaluator::setImage}
|
||||
Sets the image in which to compute the features.
|
||||
|
||||
\cvdefCpp{
|
||||
bool FeatureEvaluator::setImage(const Mat\& img, Size origWinSize);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{img}{Matrix of type \texttt{CV\_8UC1} containing the image in which to compute the features.}
|
||||
\cvarg{origWinSize}{Size of training images.}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{FeatureEvaluator::setWindow}
|
||||
Sets window in the current image in which the features will be computed (called by \cvCppCross{CascadeClassifier::runAt}).
|
||||
|
||||
\cvdefCpp{
|
||||
bool FeatureEvaluator::setWindow(Point p);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{p}{The upper left point of window in which the features will be computed. Size of the window is equal to size of training images.}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{FeatureEvaluator::calcOrd}
|
||||
Computes value of an ordered (numerical) feature.
|
||||
|
||||
\cvdefCpp{
|
||||
double FeatureEvaluator::calcOrd(int featureIdx) const;
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{featureIdx}{Index of feature whose value will be computed.}
|
||||
\end{description}
|
||||
Returns computed value of ordered feature.
|
||||
|
||||
\cvCppFunc{FeatureEvaluator::calcCat}
|
||||
Computes value of a categorical feature.
|
||||
|
||||
\cvdefCpp{
|
||||
int FeatureEvaluator::calcCat(int featureIdx) const;
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{featureIdx}{Index of feature whose value will be computed.}
|
||||
\end{description}
|
||||
Returns computed label of categorical feature, i.e. value from [0,... (number of categories - 1)].
|
||||
|
||||
\cvCppFunc{FeatureEvaluator::create}
|
||||
Constructs feature evaluator.
|
||||
|
||||
\cvdefCpp{
|
||||
static Ptr<FeatureEvaluator> FeatureEvaluator::create(int type);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{type}{Type of features evaluated by cascade (HAAR or LBP for now).}
|
||||
\end{description}
|
||||
|
||||
\cvclass{CascadeClassifier}
|
||||
The cascade classifier class for object detection.
|
||||
|
||||
\begin{lstlisting}
|
||||
class CascadeClassifier
|
||||
{
|
||||
public:
|
||||
// structure for storing tree node
|
||||
struct CV_EXPORTS DTreeNode
|
||||
{
|
||||
int featureIdx; // feature index on which is a split
|
||||
float threshold; // split threshold of ordered features only
|
||||
int left; // left child index in the tree nodes array
|
||||
int right; // right child index in the tree nodes array
|
||||
};
|
||||
|
||||
// structure for storing desision tree
|
||||
struct CV_EXPORTS DTree
|
||||
{
|
||||
int nodeCount; // nodes count
|
||||
};
|
||||
|
||||
// structure for storing cascade stage (BOOST only for now)
|
||||
struct CV_EXPORTS Stage
|
||||
{
|
||||
int first; // first tree index in tree array
|
||||
int ntrees; // number of trees
|
||||
float threshold; // treshold of stage sum
|
||||
};
|
||||
|
||||
enum { BOOST = 0 }; // supported stage types
|
||||
|
||||
// mode of detection (see parameter flags in function HaarDetectObjects)
|
||||
enum { DO_CANNY_PRUNING = CV_HAAR_DO_CANNY_PRUNING,
|
||||
SCALE_IMAGE = CV_HAAR_SCALE_IMAGE,
|
||||
FIND_BIGGEST_OBJECT = CV_HAAR_FIND_BIGGEST_OBJECT,
|
||||
DO_ROUGH_SEARCH = CV_HAAR_DO_ROUGH_SEARCH };
|
||||
|
||||
CascadeClassifier(); // default constructor
|
||||
CascadeClassifier(const string& filename);
|
||||
~CascadeClassifier(); // destructor
|
||||
|
||||
bool empty() const;
|
||||
bool load(const string& filename);
|
||||
bool read(const FileNode& node);
|
||||
|
||||
void detectMultiScale( const Mat& image, vector<Rect>& objects,
|
||||
double scaleFactor=1.1, int minNeighbors=3,
|
||||
int flags=0, Size minSize=Size());
|
||||
|
||||
bool setImage( Ptr<FeatureEvaluator>&, const Mat& );
|
||||
int runAt( Ptr<FeatureEvaluator>&, Point );
|
||||
|
||||
bool is_stump_based; // true, if the trees are stumps
|
||||
|
||||
int stageType; // stage type (BOOST only for now)
|
||||
int featureType; // feature type (HAAR or LBP for now)
|
||||
int ncategories; // number of categories (for categorical features only)
|
||||
Size origWinSize; // size of training images
|
||||
|
||||
vector<Stage> stages; // vector of stages (BOOST for now)
|
||||
vector<DTree> classifiers; // vector of decision trees
|
||||
vector<DTreeNode> nodes; // vector of tree nodes
|
||||
vector<float> leaves; // vector of leaf values
|
||||
vector<int> subsets; // subsets of split by categorical feature
|
||||
|
||||
Ptr<FeatureEvaluator> feval; // pointer to feature evaluator
|
||||
Ptr<CvHaarClassifierCascade> oldCascade; // pointer to old cascade
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
\cvCppFunc{CascadeClassifier::CascadeClassifier}
|
||||
Loads the classifier from file.
|
||||
|
||||
\cvdefCpp{
|
||||
CascadeClassifier::CascadeClassifier(const string\& filename);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{filename}{Name of file from which classifier will be load.}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{CascadeClassifier::empty}
|
||||
Checks if the classifier has been loaded or not.
|
||||
|
||||
\cvdefCpp{
|
||||
bool CascadeClassifier::empty() const;
|
||||
}
|
||||
|
||||
\cvCppFunc{CascadeClassifier::load}
|
||||
Loads the classifier from file. The previous content is destroyed.
|
||||
|
||||
\cvdefCpp{
|
||||
bool CascadeClassifier::load(const string\& filename);
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{filename}{Name of file from which classifier will be load. File may contain as old haar classifier (trained by haartraining application) or new cascade classifier (trained traincascade application).}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{CascadeClassifier::read}
|
||||
Reads the classifier from a FileStorage node. File may contain a new cascade classifier (trained traincascade application) only.
|
||||
|
||||
\cvdefCpp{
|
||||
bool CascadeClassifier::read(const FileNode\& node);
|
||||
}
|
||||
|
||||
\cvCppFunc{CascadeClassifier::detectMultiScale}
|
||||
Detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles.
|
||||
|
||||
\cvdefCpp{
|
||||
void CascadeClassifier::detectMultiScale( const Mat\& image,
|
||||
vector<Rect>\& objects,
|
||||
double scaleFactor=1.1,
|
||||
int minNeighbors=3, int flags=0,
|
||||
Size minSize=Size());
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Matrix of type \texttt{CV\_8U} containing the image in which to detect objects.}
|
||||
\cvarg{objects}{Vector of rectangles such that each rectangle contains the detected object.}
|
||||
\cvarg{scaleFactor}{Specifies how much the image size is reduced at each image scale.}
|
||||
\cvarg{minNeighbors}{Speficifes how many neighbors should each candiate rectangle have to retain it.}
|
||||
\cvarg{flags}{This parameter is not used for new cascade and have the same meaning for old cascade as in function cvHaarDetectObjects.}
|
||||
\cvarg{minSize}{The minimum possible object size. Objects smaller than that are ignored.}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{CascadeClassifier::setImage}
|
||||
Sets the image for detection (called by detectMultiScale at each image level).
|
||||
|
||||
\cvdefCpp{
|
||||
bool CascadeClassifier::setImage( Ptr<FeatureEvaluator>\& feval, const Mat\& image );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{feval}{Pointer to feature evaluator which is used for computing features.}
|
||||
\cvarg{image}{Matrix of type \texttt{CV\_8UC1} containing the image in which to compute the features.}
|
||||
\end{description}
|
||||
|
||||
\cvCppFunc{CascadeClassifier::runAt}
|
||||
Runs the detector at the specified point (the image that the detector is working with should be set by setImage).
|
||||
|
||||
\cvdefCpp{
|
||||
int CascadeClassifier::runAt( Ptr<FeatureEvaluator>\& feval, Point pt );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{feval}{Feature evaluator which is used for computing features.}
|
||||
\cvarg{pt}{The upper left point of window in which the features will be computed. Size of the window is equal to size of training images.}
|
||||
\end{description}
|
||||
Returns:
|
||||
1 - if cascade classifier detects object in the given location.
|
||||
-si - otherwise. si is an index of stage which first predicted that given window is a background image.
|
||||
|
||||
\cvCppFunc{groupRectangles}
|
||||
Groups the object candidate rectangles
|
||||
|
||||
\cvdefCpp{void groupRectangles(vector<Rect>\& rectList,\par
|
||||
int groupThreshold, double eps=0.2);}
|
||||
\begin{description}
|
||||
\cvarg{rectList}{The input/output vector of rectangles. On output there will be retained and grouped rectangles}
|
||||
\cvarg{groupThreshold}{The minimum possible number of rectangles, minus 1, in a group of rectangles to retain it.}
|
||||
\cvarg{eps}{The relative difference between sides of the rectangles to merge them into a group}
|
||||
\end{description}
|
||||
|
||||
The function is a wrapper for a generic function \cvCppCross{partition}. It clusters all the input rectangles using the rectangle equivalence criteria, that combines rectangles that have similar sizes and similar locations (the similarity is defined by \texttt{eps}). When \texttt{eps=0}, no clustering is done at all. If $\texttt{eps}\rightarrow +\inf$, all the rectangles will be put in one cluster. Then, the small clusters, containing less than or equal to \texttt{groupThreshold} rectangles, will be rejected. In each other cluster the average rectangle will be computed and put into the output rectangle list.
|
||||
\fi
|
||||
|
||||
\ifC
|
||||
|
||||
\section{Discriminatively Trained Part Based Models for Object Detection}
|
||||
|
||||
\subsection{Discriminatively Trained Part Based Models for Object Detection}
|
||||
|
||||
The object detector described below has been initially proposed by
|
||||
P.F. Felzenszwalb in \cvCPyCross{Felzenszwalb10}. It is based on a
|
||||
Dalal-Triggs detector that uses a single filter on histogram of
|
||||
oriented gradients (HOG) features to represent an object category.
|
||||
This detector uses a sliding window approach, where a filter is
|
||||
applied at all positions and scales of an image. The first
|
||||
innovation is enriching the Dalal-Triggs model using a
|
||||
star-structured part-based model defined by a "root" filter
|
||||
(analogous to the Dalal-Triggs filter) plus a set of parts filters
|
||||
and associated deformation models. The score of one of star models
|
||||
at a particular position and scale within an image is the score of
|
||||
the root filter at the given location plus the sum over parts of the
|
||||
maximum, over placements of that part, of the part filter score on
|
||||
its location minus a deformation cost measuring the deviation of the
|
||||
part from its ideal location relative to the root. Both root and
|
||||
part filter scores are defined by the dot product between a filter
|
||||
(a set of weights) and a subwindow of a feature pyramid computed
|
||||
from the input image. Another improvement is a representation of the
|
||||
class of models by a mixture of star models. The score of a mixture
|
||||
model at a particular position and scale is the maximum over
|
||||
components, of the score of that component model at the given
|
||||
location.
|
||||
|
||||
\fi
|
||||
|
||||
\ifC
|
||||
|
||||
\cvclass{CvLSVMFilterPosition, CvLSVMFilterObject,
|
||||
CvLatentSvmDetector, CvObjectDetection}
|
||||
|
||||
\begin{lstlisting}
|
||||
/* DataType: STRUCT position
|
||||
Structure describes the position of the filter in the feature pyramid
|
||||
l - level in the feature pyramid
|
||||
(x, y) - coordinate in level l */
|
||||
typedef struct {
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int l;
|
||||
} CvLSVMFilterPosition;
|
||||
|
||||
/* DataType: STRUCT filterObject
|
||||
Description of the filter, which corresponds to the part of the object
|
||||
V - ideal (penalty = 0) position of the partial filter
|
||||
from the root filter position (V_i in the paper)
|
||||
penaltyFunction - vector describes penalty function (d_i in the paper)
|
||||
pf[0] * x + pf[1] * y + pf[2] * x^2 + pf[3] * y^2
|
||||
FILTER DESCRIPTION
|
||||
Rectangular map (sizeX x sizeY),
|
||||
every cell stores feature vector (dimension = p)
|
||||
H - matrix of feature vectors
|
||||
to set and get feature vectors (i,j)
|
||||
used formula H[(j * sizeX + i) * p + k], where
|
||||
k - component of feature vector in cell (i, j)
|
||||
END OF FILTER DESCRIPTION
|
||||
xp - auxillary parameter for internal use
|
||||
size of row in feature vectors
|
||||
(yp = (int) (p / xp); p = xp * yp) */
|
||||
typedef struct{
|
||||
CvLSVMFilterPosition V;
|
||||
float fineFunction[4];
|
||||
unsigned int sizeX;
|
||||
unsigned int sizeY;
|
||||
unsigned int p;
|
||||
unsigned int xp;
|
||||
float *H;
|
||||
} CvLSVMFilterObject;
|
||||
|
||||
/* data type: STRUCT CvLatentSvmDetector
|
||||
structure contains internal representation of trained Latent SVM detector
|
||||
num_filters - total number of filters (root plus part) in model
|
||||
num_components - number of components in model
|
||||
num_part_filters - array containing number of part filters for each component
|
||||
filters - root and part filters for all model components
|
||||
b - biases for all model components
|
||||
score_threshold - confidence level threshold */
|
||||
typedef struct CvLatentSvmDetector {
|
||||
int num_filters;
|
||||
int num_components;
|
||||
int* num_part_filters;
|
||||
CvLSVMFilterObject** filters;
|
||||
float* b;
|
||||
float score_threshold;
|
||||
} CvLatentSvmDetector;
|
||||
|
||||
/* data type: STRUCT CvObjectDetection
|
||||
structure contains the bounding box and confidence level for detected object
|
||||
rect - bounding box for a detected object
|
||||
score - confidence level */
|
||||
typedef struct CvObjectDetection {
|
||||
CvRect rect;
|
||||
float score;
|
||||
} CvObjectDetection;
|
||||
|
||||
\end{lstlisting}
|
||||
|
||||
\fi
|
||||
|
||||
|
||||
\ifC
|
||||
|
||||
\cvCPyFunc{LoadLatentSvmDetector} Loads trained detector from a file
|
||||
|
||||
\cvdefC{ CvLatentSvmDetector* cvLoadLatentSvmDetector( \par const
|
||||
char* filename); }
|
||||
|
||||
\begin{description}
|
||||
\cvarg{filename}{Name of the file containing the description of a
|
||||
trained detector}
|
||||
\end{description}
|
||||
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{LatentSvmDetectObjects} Detects objects in the image.
|
||||
|
||||
\cvdefC{ void cvLatentSvmDetectObjects( \par IplImage* image,
|
||||
\par CvLatentSvmDetector* detector,
|
||||
\par CvMemStorage* storage,
|
||||
\par float overlap\_threshold CV\_DEFAULT(0.5f),
|
||||
\par int numThreads CV\_DEFAULT(-1));
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{Image to detect objects in} \cvarg{detector}{LatentSVM
|
||||
detector in internal representation} \cvarg{storage}{Memory storage
|
||||
to store the resultant sequence of the object candidate rectangles}
|
||||
\cvarg{overlap\_threshod}{Threshold for the non-maximum suppression
|
||||
algorithm} \cvarg{numThreads}{Number of threads used in parallel
|
||||
version of the algorithm}
|
||||
\end{description}
|
||||
|
||||
% \begin{description}
|
||||
% \cvarg{directory}{Name of the directory containing the description
|
||||
% of a trained cascade classifier} \cvarg{orig\_window\_size}{Original
|
||||
% size of the objects the cascade has been trained on. Note that it is
|
||||
% not stored in the cascade and therefore must be specified
|
||||
% separately}
|
||||
% \end{description}
|
@ -1,26 +0,0 @@
|
||||
\documentclass[11pt]{book}
|
||||
\newcommand{\targetlang}{}
|
||||
|
||||
\usepackage{myopencv}
|
||||
\usepackage{amsmath}
|
||||
\usepackage{ifthen}
|
||||
|
||||
\def\genc{true}
|
||||
\def\genpy{false}
|
||||
\def\targetlang{cpp}
|
||||
|
||||
\title{OpenCV Reference Manual} % used by \maketitle
|
||||
\author{v2.0} % used by \maketitle
|
||||
\date{Nov 25, 2009} % used by \maketitle
|
||||
|
||||
\begin{document}
|
||||
\maketitle % automatic title!
|
||||
|
||||
\setcounter{tocdepth}{8}
|
||||
\tableofcontents
|
||||
|
||||
%%% Chapters %%%
|
||||
\input{opencvref_body}
|
||||
%%%%%%%%%%%%%%%%
|
||||
|
||||
\end{document} % End of document.
|
@ -1,939 +0,0 @@
|
||||
\section{Motion Analysis and Object Tracking}
|
||||
|
||||
\ifCPy
|
||||
|
||||
\cvCPyFunc{CalcGlobalOrientation}
|
||||
Calculates the global motion orientation of some selected region.
|
||||
|
||||
\cvdefC{
|
||||
double cvCalcGlobalOrientation( \par const CvArr* orientation,\par const CvArr* mask,\par const CvArr* mhi,\par double timestamp,\par double duration );
|
||||
}\cvdefPy{CalcGlobalOrientation(orientation,mask,mhi,timestamp,duration)-> float}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{orientation}{Motion gradient orientation image; calculated by the function \cvCPyCross{CalcMotionGradient}}
|
||||
\cvarg{mask}{Mask image. It may be a conjunction of a valid gradient mask, obtained with \cvCPyCross{CalcMotionGradient} and the mask of the region, whose direction needs to be calculated}
|
||||
\cvarg{mhi}{Motion history image}
|
||||
\cvarg{timestamp}{Current time in milliseconds or other units, it is better to store time passed to \cvCPyCross{UpdateMotionHistory} before and reuse it here, because running \cvCPyCross{UpdateMotionHistory} and \cvCPyCross{CalcMotionGradient} on large images may take some time}
|
||||
\cvarg{duration}{Maximal duration of motion track in milliseconds, the same as \cvCPyCross{UpdateMotionHistory}}
|
||||
\end{description}
|
||||
|
||||
The function calculates the general
|
||||
motion direction in the selected region and returns the angle between
|
||||
0 degrees and 360 degrees . At first the function builds the orientation histogram
|
||||
and finds the basic orientation as a coordinate of the histogram
|
||||
maximum. After that the function calculates the shift relative to the
|
||||
basic orientation as a weighted sum of all of the orientation vectors: the more
|
||||
recent the motion, the greater the weight. The resultant angle is
|
||||
a circular sum of the basic orientation and the shift.
|
||||
|
||||
\cvCPyFunc{CalcMotionGradient}
|
||||
Calculates the gradient orientation of a motion history image.
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcMotionGradient( \par const CvArr* mhi,\par CvArr* mask,\par CvArr* orientation,\par double delta1,\par double delta2,\par int apertureSize=3 );
|
||||
}\cvdefPy{CalcMotionGradient(mhi,mask,orientation,delta1,delta2,apertureSize=3)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{mhi}{Motion history image}
|
||||
\cvarg{mask}{Mask image; marks pixels where the motion gradient data is correct; output parameter}
|
||||
\cvarg{orientation}{Motion gradient orientation image; contains angles from 0 to ~360 degrees }
|
||||
\cvarg{delta1}{See below}
|
||||
\cvarg{delta2}{See below}
|
||||
\cvarg{apertureSize}{Aperture size of derivative operators used by the function: CV\_SCHARR, 1, 3, 5 or 7 (see \cvCPyCross{Sobel})}
|
||||
\end{description}
|
||||
|
||||
The function calculates the derivatives $Dx$ and $Dy$ of \texttt{mhi} and then calculates gradient orientation as:
|
||||
|
||||
\[
|
||||
\texttt{orientation}(x,y)=\arctan{\frac{Dy(x,y)}{Dx(x,y)}}
|
||||
\]
|
||||
|
||||
where both $Dx(x,y)$ and $Dy(x,y)$ signs are taken into account (as in the \cvCPyCross{CartToPolar} function). After that \texttt{mask} is filled to indicate where the orientation is valid (see the \texttt{delta1} and \texttt{delta2} description).
|
||||
|
||||
The function finds the minimum ($m(x,y)$) and maximum ($M(x,y)$) mhi values over each pixel $(x,y)$ neighborhood and assumes the gradient is valid only if
|
||||
\[
|
||||
\min(\texttt{delta1} , \texttt{delta2} ) \le M(x,y)-m(x,y) \le \max(\texttt{delta1} ,\texttt{delta2} ).
|
||||
\]
|
||||
|
||||
\cvCPyFunc{CalcOpticalFlowBM}
|
||||
Calculates the optical flow for two images by using the block matching method.
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcOpticalFlowBM( \par const CvArr* prev,\par const CvArr* curr,\par CvSize blockSize,\par CvSize shiftSize,\par CvSize max\_range,\par int usePrevious,\par CvArr* velx,\par CvArr* vely );
|
||||
}\cvdefPy{CalcOpticalFlowBM(prev,curr,blockSize,shiftSize,max\_range,usePrevious,velx,vely)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{prev}{First image, 8-bit, single-channel}
|
||||
\cvarg{curr}{Second image, 8-bit, single-channel}
|
||||
\cvarg{blockSize}{Size of basic blocks that are compared}
|
||||
\cvarg{shiftSize}{Block coordinate increments}
|
||||
\cvarg{max\_range}{Size of the scanned neighborhood in pixels around the block}
|
||||
\cvarg{usePrevious}{Uses the previous (input) velocity field}
|
||||
\cvarg{velx}{Horizontal component of the optical flow of
|
||||
\[
|
||||
\left\lfloor \frac{\texttt{prev->width} - \texttt{blockSize.width}}{\texttt{shiftSize.width}} \right\rfloor
|
||||
\times
|
||||
\left\lfloor \frac{\texttt{prev->height} - \texttt{blockSize.height}}{\texttt{shiftSize.height}} \right\rfloor
|
||||
\]
|
||||
size, 32-bit floating-point, single-channel}
|
||||
\cvarg{vely}{Vertical component of the optical flow of the same size \texttt{velx}, 32-bit floating-point, single-channel}
|
||||
\end{description}
|
||||
|
||||
The function calculates the optical
|
||||
flow for overlapped blocks $\texttt{blockSize.width} \times \texttt{blockSize.height}$ pixels each, thus the velocity
|
||||
fields are smaller than the original images. For every block in \texttt{prev} the functions tries to find a similar block in
|
||||
\texttt{curr} in some neighborhood of the original block or shifted by (velx(x0,y0),vely(x0,y0)) block as has been calculated by previous
|
||||
function call (if \texttt{usePrevious=1})
|
||||
|
||||
\cvCPyFunc{CalcOpticalFlowHS}
|
||||
Calculates the optical flow for two images.
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcOpticalFlowHS( \par const CvArr* prev,\par const CvArr* curr,\par int usePrevious,\par CvArr* velx,\par CvArr* vely,\par double lambda,\par CvTermCriteria criteria );
|
||||
}\cvdefPy{CalcOpticalFlowHS(prev,curr,usePrevious,velx,vely,lambda,criteria)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{prev}{First image, 8-bit, single-channel}
|
||||
\cvarg{curr}{Second image, 8-bit, single-channel}
|
||||
\cvarg{usePrevious}{Uses the previous (input) velocity field}
|
||||
\cvarg{velx}{Horizontal component of the optical flow of the same size as input images, 32-bit floating-point, single-channel}
|
||||
\cvarg{vely}{Vertical component of the optical flow of the same size as input images, 32-bit floating-point, single-channel}
|
||||
\cvarg{lambda}{Lagrangian multiplier}
|
||||
\cvarg{criteria}{Criteria of termination of velocity computing}
|
||||
\end{description}
|
||||
|
||||
The function computes the flow for every pixel of the first input image using the Horn and Schunck algorithm
|
||||
\cite{Horn81}.
|
||||
|
||||
\cvCPyFunc{CalcOpticalFlowLK}
|
||||
Calculates the optical flow for two images.
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcOpticalFlowLK( \par const CvArr* prev,\par const CvArr* curr,\par CvSize winSize,\par CvArr* velx,\par CvArr* vely );
|
||||
}\cvdefPy{CalcOpticalFlowLK(prev,curr,winSize,velx,vely)-> None}
|
||||
\begin{description}
|
||||
|
||||
\cvarg{prev}{First image, 8-bit, single-channel}
|
||||
\cvarg{curr}{Second image, 8-bit, single-channel}
|
||||
\cvarg{winSize}{Size of the averaging window used for grouping pixels}
|
||||
\cvarg{velx}{Horizontal component of the optical flow of the same size as input images, 32-bit floating-point, single-channel}
|
||||
\cvarg{vely}{Vertical component of the optical flow of the same size as input images, 32-bit floating-point, single-channel}
|
||||
\end{description}
|
||||
|
||||
The function computes the flow for every pixel of the first input image using the Lucas and Kanade algorithm
|
||||
\cite{Lucas81}.
|
||||
|
||||
\cvCPyFunc{CalcOpticalFlowPyrLK}
|
||||
Calculates the optical flow for a sparse feature set using the iterative Lucas-Kanade method with pyramids.
|
||||
|
||||
\cvdefC{
|
||||
void cvCalcOpticalFlowPyrLK( \par const CvArr* prev,\par const CvArr* curr,\par CvArr* prevPyr,\par CvArr* currPyr,\par const CvPoint2D32f* prevFeatures,\par CvPoint2D32f* currFeatures,\par int count,\par CvSize winSize,\par int level,\par char* status,\par float* track\_error,\par CvTermCriteria criteria,\par int flags );
|
||||
}
|
||||
\cvdefPy{CalcOpticalFlowPyrLK( prev, curr, prevPyr, currPyr, prevFeatures, winSize, level, criteria, flags, guesses = None) -> (currFeatures, status, track\_error)}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{prev}{First frame, at time \texttt{t}}
|
||||
\cvarg{curr}{Second frame, at time \texttt{t + dt} }
|
||||
\cvarg{prevPyr}{Buffer for the pyramid for the first frame. If the pointer is not \texttt{NULL} , the buffer must have a sufficient size to store the pyramid from level \texttt{1} to level \texttt{level} ; the total size of \texttt{(image\_width+8)*image\_height/3} bytes is sufficient}
|
||||
\cvarg{currPyr}{Similar to \texttt{prevPyr}, used for the second frame}
|
||||
\cvarg{prevFeatures}{Array of points for which the flow needs to be found}
|
||||
\cvarg{currFeatures}{Array of 2D points containing the calculated new positions of the input features in the second image}
|
||||
\ifC
|
||||
\cvarg{count}{Number of feature points}
|
||||
\fi
|
||||
\cvarg{winSize}{Size of the search window of each pyramid level}
|
||||
\cvarg{level}{Maximal pyramid level number. If \texttt{0} , pyramids are not used (single level), if \texttt{1} , two levels are used, etc}
|
||||
\cvarg{status}{Array. Every element of the array is set to \texttt{1} if the flow for the corresponding feature has been found, \texttt{0} otherwise}
|
||||
\cvarg{track\_error}{Array of double numbers containing the difference between patches around the original and moved points. Optional parameter; can be \texttt{NULL}}
|
||||
\cvarg{criteria}{Specifies when the iteration process of finding the flow for each point on each pyramid level should be stopped}
|
||||
\cvarg{flags}{Miscellaneous flags:
|
||||
\begin{description}
|
||||
\cvarg{CV\_LKFLOWPyr\_A\_READY}{pyramid for the first frame is precalculated before the call}
|
||||
\cvarg{CV\_LKFLOWPyr\_B\_READY}{ pyramid for the second frame is precalculated before the call}
|
||||
\cvC{\cvarg{CV\_LKFLOW\_INITIAL\_GUESSES}{array B contains initial coordinates of features before the function call}}
|
||||
\end{description}}
|
||||
\cvPy{\cvarg{guesses}{optional array of estimated coordinates of features in second frame, with same length as \texttt{prevFeatures}}}
|
||||
\end{description}
|
||||
|
||||
The function implements the sparse iterative version of the Lucas-Kanade optical flow in pyramids
|
||||
\cite{Bouguet00}
|
||||
. It calculates the coordinates of the feature points on the current video
|
||||
frame given their coordinates on the previous frame. The function finds
|
||||
the coordinates with sub-pixel accuracy.
|
||||
|
||||
Both parameters \texttt{prevPyr} and \texttt{currPyr} comply with the
|
||||
following rules: if the image pointer is 0, the function allocates the
|
||||
buffer internally, calculates the pyramid, and releases the buffer after
|
||||
processing. Otherwise, the function calculates the pyramid and stores
|
||||
it in the buffer unless the flag \texttt{CV\_LKFLOWPyr\_A[B]\_READY}
|
||||
is set. The image should be large enough to fit the Gaussian pyramid
|
||||
data. After the function call both pyramids are calculated and the
|
||||
readiness flag for the corresponding image can be set in the next call
|
||||
(i.e., typically, for all the image pairs except the very first one
|
||||
\texttt{CV\_LKFLOWPyr\_A\_READY} is set).
|
||||
|
||||
|
||||
\cvCPyFunc{CamShift}
|
||||
Finds the object center, size, and orientation.
|
||||
|
||||
\cvdefC{
|
||||
int cvCamShift( \par const CvArr* prob\_image,\par CvRect window,\par CvTermCriteria criteria,\par CvConnectedComp* comp,\par CvBox2D* box=NULL );
|
||||
}
|
||||
\cvdefPy{CamShift(prob\_image,window,criteria)-> (int, comp, box)}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{prob\_image}{Back projection of object histogram (see \cvCPyCross{CalcBackProject})}
|
||||
\cvarg{window}{Initial search window}
|
||||
\cvarg{criteria}{Criteria applied to determine when the window search should be finished}
|
||||
\cvarg{comp}{Resultant structure that contains the converged search window coordinates (\texttt{comp->rect} field) and the sum of all of the pixels inside the window (\texttt{comp->area} field)}
|
||||
\ifC % {
|
||||
\cvarg{box}{Circumscribed box for the object. If not \texttt{NULL}, it contains object size and orientation}
|
||||
\else % }{
|
||||
\cvarg{box}{Circumscribed box for the object.}
|
||||
\fi % }
|
||||
\end{description}
|
||||
|
||||
The function implements the CAMSHIFT object tracking algrorithm
|
||||
\cite{Bradski98}.
|
||||
First, it finds an object center using \cvCPyCross{MeanShift} and, after that, calculates the object size and orientation. The function returns number of iterations made within \cvCPyCross{MeanShift}.
|
||||
|
||||
The \texttt{CamShiftTracker} class declared in cv.hpp implements the color object tracker that uses the function.
|
||||
|
||||
\ifC % {
|
||||
\subsection{CvConDensation}
|
||||
ConDenstation state.
|
||||
|
||||
\begin{lstlisting}
|
||||
typedef struct CvConDensation
|
||||
{
|
||||
int MP; //Dimension of measurement vector
|
||||
int DP; // Dimension of state vector
|
||||
float* DynamMatr; // Matrix of the linear Dynamics system
|
||||
float* State; // Vector of State
|
||||
int SamplesNum; // Number of the Samples
|
||||
float** flSamples; // array of the Sample Vectors
|
||||
float** flNewSamples; // temporary array of the Sample Vectors
|
||||
float* flConfidence; // Confidence for each Sample
|
||||
float* flCumulative; // Cumulative confidence
|
||||
float* Temp; // Temporary vector
|
||||
float* RandomSample; // RandomVector to update sample set
|
||||
CvRandState* RandS; // Array of structures to generate random vectors
|
||||
} CvConDensation;
|
||||
|
||||
\end{lstlisting}
|
||||
The structure \texttt{CvConDensation} stores the CONditional DENSity propagATION tracker state. The information about the algorithm can be found at \url{http://www.dai.ed.ac.uk/CVonline/LOCAL\_COPIES/ISARD1/condensation.html}.
|
||||
|
||||
\cvCPyFunc{CreateConDensation}
|
||||
Allocates the ConDensation filter structure.
|
||||
|
||||
\cvdefC{
|
||||
CvConDensation* cvCreateConDensation( \par int dynam\_params,\par int measure\_params,\par int sample\_count );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{dynam\_params}{Dimension of the state vector}
|
||||
\cvarg{measure\_params}{Dimension of the measurement vector}
|
||||
\cvarg{sample\_count}{Number of samples}
|
||||
\end{description}
|
||||
|
||||
The function creates a \texttt{CvConDensation} structure and returns a pointer to the structure.
|
||||
|
||||
\cvCPyFunc{ConDensInitSampleSet}
|
||||
Initializes the sample set for the ConDensation algorithm.
|
||||
|
||||
\cvdefC{
|
||||
void cvConDensInitSampleSet( CvConDensation* condens, \par CvMat* lower\_bound, \par CvMat* upper\_bound );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{condens}{Pointer to a structure to be initialized}
|
||||
\cvarg{lower\_bound}{Vector of the lower boundary for each dimension}
|
||||
\cvarg{upper\_bound}{Vector of the upper boundary for each dimension}
|
||||
\end{description}
|
||||
|
||||
The function fills the samples arrays in the structure \texttt{condens} with values within the specified ranges.
|
||||
\fi
|
||||
|
||||
\cvclass{CvKalman}\label{CvKalman}
|
||||
Kalman filter state.
|
||||
|
||||
\ifC
|
||||
\begin{lstlisting}
|
||||
typedef struct CvKalman
|
||||
{
|
||||
int MP; /* number of measurement vector dimensions */
|
||||
int DP; /* number of state vector dimensions */
|
||||
int CP; /* number of control vector dimensions */
|
||||
|
||||
/* backward compatibility fields */
|
||||
#if 1
|
||||
float* PosterState; /* =state_pre->data.fl */
|
||||
float* PriorState; /* =state_post->data.fl */
|
||||
float* DynamMatr; /* =transition_matrix->data.fl */
|
||||
float* MeasurementMatr; /* =measurement_matrix->data.fl */
|
||||
float* MNCovariance; /* =measurement_noise_cov->data.fl */
|
||||
float* PNCovariance; /* =process_noise_cov->data.fl */
|
||||
float* KalmGainMatr; /* =gain->data.fl */
|
||||
float* PriorErrorCovariance;/* =error_cov_pre->data.fl */
|
||||
float* PosterErrorCovariance;/* =error_cov_post->data.fl */
|
||||
float* Temp1; /* temp1->data.fl */
|
||||
float* Temp2; /* temp2->data.fl */
|
||||
#endif
|
||||
|
||||
CvMat* state_pre; /* predicted state (x'(k)):
|
||||
x(k)=A*x(k-1)+B*u(k) */
|
||||
CvMat* state_post; /* corrected state (x(k)):
|
||||
x(k)=x'(k)+K(k)*(z(k)-H*x'(k)) */
|
||||
CvMat* transition_matrix; /* state transition matrix (A) */
|
||||
CvMat* control_matrix; /* control matrix (B)
|
||||
(it is not used if there is no control)*/
|
||||
CvMat* measurement_matrix; /* measurement matrix (H) */
|
||||
CvMat* process_noise_cov; /* process noise covariance matrix (Q) */
|
||||
CvMat* measurement_noise_cov; /* measurement noise covariance matrix (R) */
|
||||
CvMat* error_cov_pre; /* priori error estimate covariance matrix (P'(k)):
|
||||
P'(k)=A*P(k-1)*At + Q*/
|
||||
CvMat* gain; /* Kalman gain matrix (K(k)):
|
||||
K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)*/
|
||||
CvMat* error_cov_post; /* posteriori error estimate covariance matrix (P(k)):
|
||||
P(k)=(I-K(k)*H)*P'(k) */
|
||||
CvMat* temp1; /* temporary matrices */
|
||||
CvMat* temp2;
|
||||
CvMat* temp3;
|
||||
CvMat* temp4;
|
||||
CvMat* temp5;
|
||||
}
|
||||
CvKalman;
|
||||
\end{lstlisting}
|
||||
\else
|
||||
\begin{description}
|
||||
\cvarg{MP}{number of measurement vector dimensions}
|
||||
\cvarg{DP}{number of state vector dimensions}
|
||||
\cvarg{CP}{number of control vector dimensions}
|
||||
\cvarg{state\_pre}{predicted state (x'(k)): x(k)=A*x(k-1)+B*u(k)}
|
||||
\cvarg{state\_post}{corrected state (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k))}
|
||||
\cvarg{transition\_matrix}{state transition matrix (A)}
|
||||
\cvarg{control\_matrix}{control matrix (B) (it is not used if there is no control)}
|
||||
\cvarg{measurement\_matrix}{measurement matrix (H)}
|
||||
\cvarg{process\_noise\_cov}{process noise covariance matrix (Q)}
|
||||
\cvarg{measurement\_noise\_cov}{measurement noise covariance matrix (R)}
|
||||
\cvarg{error\_cov\_pre}{priori error estimate covariance matrix (P'(k)): P'(k)=A*P(k-1)*At + Q}
|
||||
\cvarg{gain}{Kalman gain matrix (K(k)): K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)}
|
||||
\cvarg{error\_cov\_post}{posteriori error estimate covariance matrix (P(k)): P(k)=(I-K(k)*H)*P'(k)}
|
||||
\end{description}
|
||||
\fi
|
||||
|
||||
The structure \texttt{CvKalman} is used to keep the Kalman filter
|
||||
state. It is created by the \cvCPyCross{CreateKalman} function, updated
|
||||
by the \cvCPyCross{KalmanPredict} and \cvCPyCross{KalmanCorrect} functions
|
||||
\ifC
|
||||
and released by the \cvCPyCross{ReleaseKalman} function
|
||||
\fi
|
||||
. Normally, the
|
||||
structure is used for the standard Kalman filter (notation and the
|
||||
formulas below are borrowed from the excellent Kalman tutorial
|
||||
\cite{Welch95})
|
||||
|
||||
\[
|
||||
\begin{array}{l}
|
||||
x_k=A \cdot x_{k-1}+B \cdot u_k+w_k\\
|
||||
z_k=H \cdot x_k+v_k
|
||||
\end{array}
|
||||
\]
|
||||
|
||||
where:
|
||||
|
||||
\[
|
||||
\begin{array}{l l}
|
||||
x_k\;(x_{k-1})& \text{state of the system at the moment \emph{k} (\emph{k-1})}\\
|
||||
z_k & \text{measurement of the system state at the moment \emph{k}}\\
|
||||
u_k & \text{external control applied at the moment \emph{k}}
|
||||
\end{array}
|
||||
\]
|
||||
|
||||
$w_k$ and $v_k$ are normally-distributed process and measurement noise, respectively:
|
||||
|
||||
\[
|
||||
\begin{array}{l}
|
||||
p(w) \sim N(0,Q)\\
|
||||
p(v) \sim N(0,R)
|
||||
\end{array}
|
||||
\]
|
||||
|
||||
that is,
|
||||
|
||||
$Q$ process noise covariance matrix, constant or variable,
|
||||
|
||||
$R$ measurement noise covariance matrix, constant or variable
|
||||
|
||||
In the case of the standard Kalman filter, all of the matrices: A, B, H, Q and R are initialized once after the \cvCPyCross{CvKalman} structure is allocated via \cvCPyCross{CreateKalman}. However, the same structure and the same functions may be used to simulate the extended Kalman filter by linearizing the extended Kalman filter equation in the current system state neighborhood, in this case A, B, H (and, probably, Q and R) should be updated on every step.
|
||||
|
||||
\cvCPyFunc{CreateKalman}
|
||||
Allocates the Kalman filter structure.
|
||||
|
||||
\cvdefC{
|
||||
CvKalman* cvCreateKalman( \par int dynam\_params,\par int measure\_params,\par int control\_params=0 );
|
||||
}
|
||||
|
||||
\cvdefPy{CreateKalman(dynam\_params, measure\_params, control\_params=0) -> CvKalman}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{dynam\_params}{dimensionality of the state vector}
|
||||
\cvarg{measure\_params}{dimensionality of the measurement vector}
|
||||
\cvarg{control\_params}{dimensionality of the control vector}
|
||||
\end{description}
|
||||
|
||||
The function allocates \cvCPyCross{CvKalman} and all its matrices and initializes them somehow.
|
||||
|
||||
|
||||
\cvCPyFunc{KalmanCorrect}
|
||||
Adjusts the model state.
|
||||
|
||||
\cvdefC{const CvMat* cvKalmanCorrect( CvKalman* kalman, const CvMat* measurement );}
|
||||
\cvdefPy{KalmanCorrect(kalman, measurement) -> cvmat}
|
||||
|
||||
\begin{description}
|
||||
\ifC
|
||||
\cvarg{kalman}{Pointer to the structure to be updated}
|
||||
\else
|
||||
\cvarg{kalman}{Kalman filter object returned by \cvCPyCross{CreateKalman}}
|
||||
\fi
|
||||
\cvarg{measurement}{CvMat containing the measurement vector}
|
||||
\end{description}
|
||||
|
||||
The function adjusts the stochastic model state on the basis of the given measurement of the model state:
|
||||
|
||||
\[
|
||||
\begin{array}{l}
|
||||
K_k=P'_k \cdot H^T \cdot (H \cdot P'_k \cdot H^T+R)^{-1}\\
|
||||
x_k=x'_k+K_k \cdot (z_k-H \cdot x'_k)\\
|
||||
P_k=(I-K_k \cdot H) \cdot P'_k
|
||||
\end{array}
|
||||
\]
|
||||
|
||||
where
|
||||
|
||||
\begin{tabular}{l p{4 in}}
|
||||
\hline
|
||||
$z_k$ & given measurement (\texttt{mesurement} parameter)\\ \hline
|
||||
$K_k$ & Kalman "gain" matrix.\\ \hline
|
||||
\end{tabular}
|
||||
|
||||
The function stores the adjusted state at \texttt{kalman->state\_post} and returns it on output.
|
||||
|
||||
\ifC
|
||||
Example. Using Kalman filter to track a rotating point
|
||||
\begin{lstlisting}
|
||||
#include "cv.h"
|
||||
#include "highgui.h"
|
||||
#include <math.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
/* A matrix data */
|
||||
const float A[] = { 1, 1, 0, 1 };
|
||||
|
||||
IplImage* img = cvCreateImage( cvSize(500,500), 8, 3 );
|
||||
CvKalman* kalman = cvCreateKalman( 2, 1, 0 );
|
||||
/* state is (phi, delta_phi) - angle and angle increment */
|
||||
CvMat* state = cvCreateMat( 2, 1, CV_32FC1 );
|
||||
CvMat* process_noise = cvCreateMat( 2, 1, CV_32FC1 );
|
||||
/* only phi (angle) is measured */
|
||||
CvMat* measurement = cvCreateMat( 1, 1, CV_32FC1 );
|
||||
CvRandState rng;
|
||||
int code = -1;
|
||||
|
||||
cvRandInit( &rng, 0, 1, -1, CV_RAND_UNI );
|
||||
|
||||
cvZero( measurement );
|
||||
cvNamedWindow( "Kalman", 1 );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
cvRandSetRange( &rng, 0, 0.1, 0 );
|
||||
rng.disttype = CV_RAND_NORMAL;
|
||||
|
||||
cvRand( &rng, state );
|
||||
|
||||
memcpy( kalman->transition_matrix->data.fl, A, sizeof(A));
|
||||
cvSetIdentity( kalman->measurement_matrix, cvRealScalar(1) );
|
||||
cvSetIdentity( kalman->process_noise_cov, cvRealScalar(1e-5) );
|
||||
cvSetIdentity( kalman->measurement_noise_cov, cvRealScalar(1e-1) );
|
||||
cvSetIdentity( kalman->error_cov_post, cvRealScalar(1));
|
||||
/* choose random initial state */
|
||||
cvRand( &rng, kalman->state_post );
|
||||
|
||||
rng.disttype = CV_RAND_NORMAL;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
#define calc_point(angle) \
|
||||
cvPoint( cvRound(img->width/2 + img->width/3*cos(angle)), \
|
||||
cvRound(img->height/2 - img->width/3*sin(angle)))
|
||||
|
||||
float state_angle = state->data.fl[0];
|
||||
CvPoint state_pt = calc_point(state_angle);
|
||||
|
||||
/* predict point position */
|
||||
const CvMat* prediction = cvKalmanPredict( kalman, 0 );
|
||||
float predict_angle = prediction->data.fl[0];
|
||||
CvPoint predict_pt = calc_point(predict_angle);
|
||||
float measurement_angle;
|
||||
CvPoint measurement_pt;
|
||||
|
||||
cvRandSetRange( &rng,
|
||||
0,
|
||||
sqrt(kalman->measurement_noise_cov->data.fl[0]),
|
||||
0 );
|
||||
cvRand( &rng, measurement );
|
||||
|
||||
/* generate measurement */
|
||||
cvMatMulAdd( kalman->measurement_matrix, state, measurement, measurement );
|
||||
|
||||
measurement_angle = measurement->data.fl[0];
|
||||
measurement_pt = calc_point(measurement_angle);
|
||||
|
||||
/* plot points */
|
||||
#define draw_cross( center, color, d ) \
|
||||
cvLine( img, cvPoint( center.x - d, center.y - d ), \
|
||||
cvPoint( center.x + d, center.y + d ), \
|
||||
color, 1, 0 ); \
|
||||
cvLine( img, cvPoint( center.x + d, center.y - d ), \
|
||||
cvPoint( center.x - d, center.y + d ), \
|
||||
color, 1, 0 )
|
||||
|
||||
cvZero( img );
|
||||
draw_cross( state_pt, CV_RGB(255,255,255), 3 );
|
||||
draw_cross( measurement_pt, CV_RGB(255,0,0), 3 );
|
||||
draw_cross( predict_pt, CV_RGB(0,255,0), 3 );
|
||||
cvLine( img, state_pt, predict_pt, CV_RGB(255,255,0), 3, 0 );
|
||||
|
||||
/* adjust Kalman filter state */
|
||||
cvKalmanCorrect( kalman, measurement );
|
||||
|
||||
cvRandSetRange( &rng,
|
||||
0,
|
||||
sqrt(kalman->process_noise_cov->data.fl[0]),
|
||||
0 );
|
||||
cvRand( &rng, process_noise );
|
||||
cvMatMulAdd( kalman->transition_matrix,
|
||||
state,
|
||||
process_noise,
|
||||
state );
|
||||
|
||||
cvShowImage( "Kalman", img );
|
||||
code = cvWaitKey( 100 );
|
||||
|
||||
if( code > 0 ) /* break current simulation by pressing a key */
|
||||
break;
|
||||
}
|
||||
if( code == 27 ) /* exit by ESCAPE */
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
\end{lstlisting}
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{KalmanPredict}
|
||||
Estimates the subsequent model state.
|
||||
|
||||
\cvdefC{const CvMat* cvKalmanPredict( \par CvKalman* kalman, \par const CvMat* control=NULL);}
|
||||
\cvdefPy{KalmanPredict(kalman, control=None) -> cvmat}
|
||||
|
||||
\begin{description}
|
||||
\ifC
|
||||
\cvarg{kalman}{Kalman filter state}
|
||||
\else
|
||||
\cvarg{kalman}{Kalman filter object returned by \cvCPyCross{CreateKalman}}
|
||||
\fi
|
||||
\cvarg{control}{Control vector $u_k$, should be NULL iff there is no external control (\texttt{control\_params} =0)}
|
||||
\end{description}
|
||||
|
||||
The function estimates the subsequent stochastic model state by its current state and stores it at \texttt{kalman->state\_pre}:
|
||||
|
||||
\[
|
||||
\begin{array}{l}
|
||||
x'_k=A x_{k-1} + B u_k\\
|
||||
P'_k=A P_{k-1} A^T + Q
|
||||
\end{array}
|
||||
\]
|
||||
|
||||
where
|
||||
|
||||
\begin{tabular}{l p{5 in}}
|
||||
\hline
|
||||
$x'_k$ & is predicted state \texttt{kalman->state\_pre},\\ \hline
|
||||
$x_{k-1}$ & is corrected state on the previous step \texttt{kalman->state\_post}
|
||||
(should be initialized somehow in the beginning, zero vector by default),\\ \hline
|
||||
$u_k$ & is external control (\texttt{control} parameter),\\ \hline
|
||||
$P'_k$ & is priori error covariance matrix \texttt{kalman->error\_cov\_pre}\\ \hline
|
||||
$P_{k-1}$ & is posteriori error covariance matrix on the previous step \texttt{kalman->error\_cov\_post}
|
||||
(should be initialized somehow in the beginning, identity matrix by default),
|
||||
\end{tabular}
|
||||
|
||||
The function returns the estimated state.
|
||||
|
||||
\subsection{KalmanUpdateByMeasurement}
|
||||
|
||||
Synonym for \cross{KalmanCorrect}
|
||||
|
||||
\subsection{KalmanUpdateByTime}
|
||||
|
||||
Synonym for \cross{KalmanPredict}
|
||||
|
||||
\cvCPyFunc{MeanShift}
|
||||
Finds the object center on back projection.
|
||||
|
||||
\cvdefC{
|
||||
int cvMeanShift( \par const CvArr* prob\_image,\par CvRect window,\par CvTermCriteria criteria,\par CvConnectedComp* comp );
|
||||
}\cvdefPy{MeanShift(prob\_image,window,criteria)-> comp}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{prob\_image}{Back projection of the object histogram (see \cvCPyCross{CalcBackProject})}
|
||||
\cvarg{window}{Initial search window}
|
||||
\cvarg{criteria}{Criteria applied to determine when the window search should be finished}
|
||||
\cvarg{comp}{Resultant structure that contains the converged search window coordinates (\texttt{comp->rect} field) and the sum of all of the pixels inside the window (\texttt{comp->area} field)}
|
||||
\end{description}
|
||||
|
||||
The function iterates to find the object center
|
||||
given its back projection and initial position of search window. The
|
||||
iterations are made until the search window center moves by less than
|
||||
the given value and/or until the function has done the maximum number
|
||||
of iterations. The function returns the number of iterations made.
|
||||
|
||||
\ifC % {
|
||||
\cvCPyFunc{ReleaseConDensation}
|
||||
Deallocates the ConDensation filter structure.
|
||||
|
||||
\cvdefC{
|
||||
void cvReleaseConDensation( CvConDensation** condens );
|
||||
|
||||
}
|
||||
\begin{description}
|
||||
\cvarg{condens}{Pointer to the pointer to the structure to be released}
|
||||
\end{description}
|
||||
|
||||
The function releases the structure \texttt{condens}) and frees all memory previously allocated for the structure.
|
||||
|
||||
\fi % }
|
||||
|
||||
\ifC % {
|
||||
|
||||
\cvCPyFunc{ReleaseKalman}
|
||||
Deallocates the Kalman filter structure.
|
||||
|
||||
\cvdefC{
|
||||
void cvReleaseKalman( \par CvKalman** kalman );
|
||||
}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{kalman}{double pointer to the Kalman filter structure}
|
||||
\end{description}
|
||||
|
||||
The function releases the structure \cvCPyCross{CvKalman} and all of the underlying matrices.
|
||||
|
||||
\fi % }
|
||||
|
||||
\cvCPyFunc{SegmentMotion}
|
||||
Segments a whole motion into separate moving parts.
|
||||
|
||||
\cvdefC{
|
||||
CvSeq* cvSegmentMotion( \par const CvArr* mhi,\par CvArr* seg\_mask,\par CvMemStorage* storage,\par double timestamp,\par double seg\_thresh );
|
||||
}\cvdefPy{SegmentMotion(mhi,seg\_mask,storage,timestamp,seg\_thresh)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{mhi}{Motion history image}
|
||||
\cvarg{seg\_mask}{Image where the mask found should be stored, single-channel, 32-bit floating-point}
|
||||
\cvarg{storage}{Memory storage that will contain a sequence of motion connected components}
|
||||
\cvarg{timestamp}{Current time in milliseconds or other units}
|
||||
\cvarg{seg\_thresh}{Segmentation threshold; recommended to be equal to the interval between motion history "steps" or greater}
|
||||
\end{description}
|
||||
|
||||
The function finds all of the motion segments and
|
||||
marks them in \texttt{seg\_mask} with individual values (1,2,...). It
|
||||
also returns a sequence of \cvCPyCross{CvConnectedComp}
|
||||
structures, one for each motion component. After that the
|
||||
motion direction for every component can be calculated with
|
||||
\cvCPyCross{CalcGlobalOrientation} using the extracted mask of the particular
|
||||
component \cvCPyCross{Cmp}.
|
||||
|
||||
\cvCPyFunc{SnakeImage}
|
||||
Changes the contour position to minimize its energy.
|
||||
|
||||
\cvdefC{
|
||||
void cvSnakeImage( \par const IplImage* image,\par CvPoint* points,\par int length,\par float* alpha,\par float* beta,\par float* gamma,\par int coeff\_usage,\par CvSize win,\par CvTermCriteria criteria,\par int calc\_gradient=1 );
|
||||
}
|
||||
|
||||
\cvdefPy{SnakeImage(image,points,alpha,beta,gamma,win,criteria,calc\_gradient=1)-> new\_points}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{image}{The source image or external energy field}
|
||||
\cvarg{points}{Contour points (snake)}
|
||||
\ifC
|
||||
\cvarg{length}{Number of points in the contour}
|
||||
\cvarg{alpha}{Weight[s] of continuity energy, single float or
|
||||
array of \texttt{length} floats, one for each contour point}
|
||||
\else
|
||||
\cvarg{alpha}{Weight[s] of continuity energy, single float or
|
||||
a list of floats, one for each contour point}
|
||||
\fi
|
||||
\cvarg{beta}{Weight[s] of curvature energy, similar to \texttt{alpha}}
|
||||
\cvarg{gamma}{Weight[s] of image energy, similar to \texttt{alpha}}
|
||||
\ifC
|
||||
\cvarg{coeff\_usage}{Different uses of the previous three parameters:
|
||||
\begin{description}
|
||||
\cvarg{CV\_VALUE}{indicates that each of \texttt{alpha, beta, gamma} is a pointer to a single value to be used for all points;}
|
||||
\cvarg{CV\_ARRAY}{indicates that each of \texttt{alpha, beta, gamma} is a pointer to an array of coefficients different for all the points of the snake. All the arrays must have the size equal to the contour size.}
|
||||
\end{description}}
|
||||
\fi
|
||||
\cvarg{win}{Size of neighborhood of every point used to search the minimum, both \texttt{win.width} and \texttt{win.height} must be odd}
|
||||
\cvarg{criteria}{Termination criteria}
|
||||
\cvarg{calc\_gradient}{Gradient flag; if not 0, the function calculates the gradient magnitude for every image pixel and consideres it as the energy field, otherwise the input image itself is considered}
|
||||
\end{description}
|
||||
|
||||
The function updates the snake in order to minimize its
|
||||
total energy that is a sum of internal energy that depends on the contour
|
||||
shape (the smoother contour is, the smaller internal energy is) and
|
||||
external energy that depends on the energy field and reaches minimum at
|
||||
the local energy extremums that correspond to the image edges in the case
|
||||
of using an image gradient.
|
||||
|
||||
The parameter \texttt{criteria.epsilon} is used to define the minimal
|
||||
number of points that must be moved during any iteration to keep the
|
||||
iteration process running.
|
||||
|
||||
If at some iteration the number of moved points is less
|
||||
than \texttt{criteria.epsilon} or the function performed
|
||||
\texttt{criteria.max\_iter} iterations, the function terminates.
|
||||
|
||||
\ifPy
|
||||
The function returns the updated list of points.
|
||||
\fi
|
||||
|
||||
\cvCPyFunc{UpdateMotionHistory}
|
||||
Updates the motion history image by a moving silhouette.
|
||||
|
||||
\cvdefC{
|
||||
void cvUpdateMotionHistory( \par const CvArr* silhouette,\par CvArr* mhi,\par double timestamp,\par double duration );
|
||||
}\cvdefPy{UpdateMotionHistory(silhouette,mhi,timestamp,duration)-> None}
|
||||
|
||||
\begin{description}
|
||||
\cvarg{silhouette}{Silhouette mask that has non-zero pixels where the motion occurs}
|
||||
\cvarg{mhi}{Motion history image, that is updated by the function (single-channel, 32-bit floating-point)}
|
||||
\cvarg{timestamp}{Current time in milliseconds or other units}
|
||||
\cvarg{duration}{Maximal duration of the motion track in the same units as \texttt{timestamp}}
|
||||
\end{description}
|
||||
|
||||
The function updates the motion history image as following:
|
||||
|
||||
\[
|
||||
\texttt{mhi}(x,y)=\forkthree
|
||||
{\texttt{timestamp}}{if $\texttt{silhouette}(x,y) \ne 0$}
|
||||
{0}{if $\texttt{silhouette}(x,y) = 0$ and $\texttt{mhi} < (\texttt{timestamp} - \texttt{duration})$}
|
||||
{\texttt{mhi}(x,y)}{otherwise}
|
||||
\]
|
||||
That is, MHI pixels where motion occurs are set to the current timestamp, while the pixels where motion happened far ago are cleared.
|
||||
|
||||
\fi
|
||||
|
||||
\ifCpp
|
||||
|
||||
\cvCppFunc{calcOpticalFlowPyrLK}
|
||||
Calculates the optical flow for a sparse feature set using the iterative Lucas-Kanade method with pyramids
|
||||
|
||||
\cvdefCpp{void calcOpticalFlowPyrLK( const Mat\& prevImg, const Mat\& nextImg,\par
|
||||
const vector<Point2f>\& prevPts, vector<Point2f>\& nextPts,\par
|
||||
vector<uchar>\& status, vector<float>\& err, \par
|
||||
Size winSize=Size(15,15), int maxLevel=3,\par
|
||||
TermCriteria criteria=TermCriteria(\par
|
||||
TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),\par
|
||||
double derivLambda=0.5, int flags=0 );}
|
||||
\begin{description}
|
||||
\cvarg{prevImg}{The first 8-bit single-channel or 3-channel input image}
|
||||
\cvarg{nextImg}{The second input image of the same size and the same type as \texttt{prevImg}}
|
||||
\cvarg{prevPts}{Vector of points for which the flow needs to be found}
|
||||
\cvarg{nextPts}{The output vector of points containing the calculated new positions of the input features in the second image}
|
||||
\cvarg{status}{The output status vector. Each element of the vector is set to 1 if the flow for the corresponding features has been found, 0 otherwise}
|
||||
\cvarg{err}{The output vector that will contain the difference between patches around the original and moved points}
|
||||
\cvarg{winSize}{Size of the search window at each pyramid level}
|
||||
\cvarg{maxLevel}{0-based maximal pyramid level number. If 0, pyramids are not used (single level), if 1, two levels are used etc.}
|
||||
\cvarg{criteria}{Specifies the termination criteria of the iterative search algorithm (after the specified maximum number of iterations \texttt{criteria.maxCount} or when the search window moves by less than \texttt{criteria.epsilon}}
|
||||
\cvarg{derivLambda}{The relative weight of the spatial image derivatives impact to the optical flow estimation. If \texttt{derivLambda=0}, only the image intensity is used, if \texttt{derivLambda=1}, only derivatives are used. Any other values between 0 and 1 means that both derivatives and the image intensity are used (in the corresponding proportions).}
|
||||
\cvarg{flags}{The operation flags:
|
||||
\begin{description}
|
||||
\cvarg{OPTFLOW\_USE\_INITIAL\_FLOW}{use initial estimations stored in \texttt{nextPts}. If the flag is not set, then initially $\texttt{nextPts}\leftarrow\texttt{prevPts}$}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
The function implements the sparse iterative version of the Lucas-Kanade optical flow in pyramids, see \cite{Bouguet00}.
|
||||
|
||||
\cvCppFunc{calcOpticalFlowFarneback}
|
||||
Computes dense optical flow using Gunnar Farneback's algorithm
|
||||
|
||||
\cvdefCpp{void calcOpticalFlowFarneback( const Mat\& prevImg, const Mat\& nextImg,\par
|
||||
Mat\& flow, double pyrScale, int levels, int winsize,\par
|
||||
int iterations, int polyN, double polySigma, int flags );}
|
||||
\begin{description}
|
||||
\cvarg{prevImg}{The first 8-bit single-channel input image}
|
||||
\cvarg{nextImg}{The second input image of the same size and the same type as \texttt{prevImg}}
|
||||
\cvarg{flow}{The computed flow image; will have the same size as \texttt{prevImg} and type \texttt{CV\_32FC2}}
|
||||
\cvarg{pyrScale}{Specifies the image scale (<1) to build the pyramids for each image. \texttt{pyrScale=0.5} means the classical pyramid, where each next layer is twice smaller than the previous}
|
||||
\cvarg{levels}{The number of pyramid layers, including the initial image. \texttt{levels=1} means that no extra layers are created and only the original images are used}
|
||||
\cvarg{winsize}{The averaging window size; The larger values increase the algorithm robustness to image noise and give more chances for fast motion detection, but yield more blurred motion field}
|
||||
\cvarg{iterations}{The number of iterations the algorithm does at each pyramid level}
|
||||
\cvarg{polyN}{Size of the pixel neighborhood used to find polynomial expansion in each pixel. The larger values mean that the image will be approximated with smoother surfaces, yielding more robust algorithm and more blurred motion field. Typically, \texttt{polyN}=5 or 7}
|
||||
\cvarg{polySigma}{Standard deviation of the Gaussian that is used to smooth derivatives that are used as a basis for the polynomial expansion. For \texttt{polyN=5} you can set \texttt{polySigma=1.1}, for \texttt{polyN=7} a good value would be \texttt{polySigma=1.5}}
|
||||
\cvarg{flags}{The operation flags; can be a combination of the following:
|
||||
\begin{description}
|
||||
\cvarg{OPTFLOW\_USE\_INITIAL\_FLOW}{Use the input \texttt{flow} as the initial flow approximation}
|
||||
\cvarg{OPTFLOW\_FARNEBACK\_GAUSSIAN}{Use a Gaussian $\texttt{winsize}\times\texttt{winsize}$ filter instead of box filter of the same size for optical flow estimation. Usually, this option gives more accurate flow than with a box filter, at the cost of lower speed (and normally \texttt{winsize} for a Gaussian window should be set to a larger value to achieve the same level of robustness)}
|
||||
\end{description}}
|
||||
\end{description}
|
||||
|
||||
The function finds optical flow for each \texttt{prevImg} pixel using the alorithm so that
|
||||
|
||||
\[\texttt{prevImg}(x,y) \sim \texttt{nextImg}(\texttt{flow}(x,y)[0], \texttt{flow}(x,y)[1])\]
|
||||
|
||||
|
||||
\cvCppFunc{updateMotionHistory}
|
||||
Updates the motion history image by a moving silhouette.
|
||||
|
||||
\cvdefCpp{void updateMotionHistory( const Mat\& silhouette, Mat\& mhi,\par
|
||||
double timestamp, double duration );}
|
||||
\begin{description}
|
||||
\cvarg{silhouette}{Silhouette mask that has non-zero pixels where the motion occurs}
|
||||
\cvarg{mhi}{Motion history image, that is updated by the function (single-channel, 32-bit floating-point)}
|
||||
\cvarg{timestamp}{Current time in milliseconds or other units}
|
||||
\cvarg{duration}{Maximal duration of the motion track in the same units as \texttt{timestamp}}
|
||||
\end{description}
|
||||
|
||||
The function updates the motion history image as following:
|
||||
|
||||
\[
|
||||
\texttt{mhi}(x,y)=\forkthree
|
||||
{\texttt{timestamp}}{if $\texttt{silhouette}(x,y) \ne 0$}
|
||||
{0}{if $\texttt{silhouette}(x,y) = 0$ and $\texttt{mhi} < (\texttt{timestamp} - \texttt{duration})$}
|
||||
{\texttt{mhi}(x,y)}{otherwise}
|
||||
\]
|
||||
That is, MHI pixels where motion occurs are set to the current \texttt{timestamp}, while the pixels where motion happened last time a long time ago are cleared.
|
||||
|
||||
The function, together with \cvCppCross{calcMotionGradient} and \cvCppCross{calcGlobalOrientation}, implements the motion templates technique, described in \cite{Davis97} and \cite{Bradski00}.
|
||||
See also the OpenCV sample \texttt{motempl.c} that demonstrates the use of all the motion template functions.
|
||||
|
||||
\cvCppFunc{calcMotionGradient}
|
||||
Calculates the gradient orientation of a motion history image.
|
||||
|
||||
\cvdefCpp{void calcMotionGradient( const Mat\& mhi, Mat\& mask,\par
|
||||
Mat\& orientation,\par
|
||||
double delta1, double delta2,\par
|
||||
int apertureSize=3 );}
|
||||
\begin{description}
|
||||
\cvarg{mhi}{Motion history single-channel floating-point image}
|
||||
\cvarg{mask}{The output mask image; will have the type \texttt{CV\_8UC1} and the same size as \texttt{mhi}. Its non-zero elements will mark pixels where the motion gradient data is correct}
|
||||
\cvarg{orientation}{The output motion gradient orientation image; will have the same type and the same size as \texttt{mhi}. Each pixel of it will the motion orientation in degrees, from 0 to 360.}
|
||||
\cvarg{delta1, delta2}{The minimal and maximal allowed difference between \texttt{mhi} values within a pixel neighorhood. That is, the function finds the minimum ($m(x,y)$) and maximum ($M(x,y)$) \texttt{mhi} values over $3 \times 3$ neighborhood of each pixel and marks the motion orientation at $(x, y)$ as valid only if
|
||||
\[
|
||||
\min(\texttt{delta1} , \texttt{delta2} ) \le M(x,y)-m(x,y) \le \max(\texttt{delta1} ,\texttt{delta2}).
|
||||
\]}
|
||||
\cvarg{apertureSize}{The aperture size of \cvCppCross{Sobel} operator}
|
||||
\end{description}
|
||||
|
||||
The function calculates the gradient orientation at each pixel $(x, y)$ as:
|
||||
|
||||
\[
|
||||
\texttt{orientation}(x,y)=\arctan{\frac{d\texttt{mhi}/dy}{d\texttt{mhi}/dx}}
|
||||
\]
|
||||
|
||||
(in fact, \cvCppCross{fastArctan} and \cvCppCross{phase} are used, so that the computed angle is measured in degrees and covers the full range 0..360). Also, the \texttt{mask} is filled to indicate pixels where the computed angle is valid.
|
||||
|
||||
\cvCppFunc{calcGlobalOrientation}
|
||||
Calculates the global motion orientation in some selected region.
|
||||
|
||||
\cvdefCpp{double calcGlobalOrientation( const Mat\& orientation, const Mat\& mask,\par
|
||||
const Mat\& mhi, double timestamp,\par
|
||||
double duration );}
|
||||
\begin{description}
|
||||
\cvarg{orientation}{Motion gradient orientation image, calculated by the function \cvCppCross{calcMotionGradient}}
|
||||
\cvarg{mask}{Mask image. It may be a conjunction of a valid gradient mask, also calculated by \cvCppCross{calcMotionGradient}, and the mask of the region, whose direction needs to be calculated}
|
||||
\cvarg{mhi}{The motion history image, calculated by \cvCppCross{updateMotionHistory}}
|
||||
\cvarg{timestamp}{The timestamp passed to \cvCppCross{updateMotionHistory}}
|
||||
\cvarg{duration}{Maximal duration of motion track in milliseconds, passed to \cvCppCross{updateMotionHistory}}
|
||||
\end{description}
|
||||
|
||||
The function calculates the average
|
||||
motion direction in the selected region and returns the angle between
|
||||
0 degrees and 360 degrees. The average direction is computed from
|
||||
the weighted orientation histogram, where a recent motion has larger
|
||||
weight and the motion occurred in the past has smaller weight, as recorded in \texttt{mhi}.
|
||||
|
||||
\cvCppFunc{CamShift}
|
||||
Finds the object center, size, and orientation
|
||||
|
||||
\cvdefCpp{RotatedRect CamShift( const Mat\& probImage, Rect\& window,\par
|
||||
TermCriteria criteria );}
|
||||
\begin{description}
|
||||
\cvarg{probImage}{Back projection of the object histogram; see \cvCppCross{calcBackProject}}
|
||||
\cvarg{window}{Initial search window}
|
||||
\cvarg{criteria}{Stop criteria for the underlying \cvCppCross{meanShift}}
|
||||
\end{description}
|
||||
|
||||
The function implements the CAMSHIFT object tracking algrorithm
|
||||
\cite{Bradski98}.
|
||||
First, it finds an object center using \cvCppCross{meanShift} and then adjust the window size and finds the optimal rotation. The function returns the rotated rectangle structure that includes the object position, size and the orientation. The next position of the search window can be obtained with \texttt{RotatedRect::boundingRect()}.
|
||||
|
||||
See the OpenCV sample \texttt{camshiftdemo.c} that tracks colored objects.
|
||||
|
||||
\cvCppFunc{meanShift}
|
||||
Finds the object on a back projection image.
|
||||
|
||||
\cvdefCpp{int meanShift( const Mat\& probImage, Rect\& window,\par
|
||||
TermCriteria criteria );}
|
||||
\begin{description}
|
||||
\cvarg{probImage}{Back projection of the object histogram; see \cvCppCross{calcBackProject}}
|
||||
\cvarg{window}{Initial search window}
|
||||
\cvarg{criteria}{The stop criteria for the iterative search algorithm}
|
||||
\end{description}
|
||||
|
||||
The function implements iterative object search algorithm. It takes the object back projection on input and the initial position. The mass center in \texttt{window} of the back projection image is computed and the search window center shifts to the mass center. The procedure is repeated until the specified number of iterations \texttt{criteria.maxCount} is done or until the window center shifts by less than \texttt{criteria.epsilon}. The algorithm is used inside \cvCppCross{CamShift} and, unlike \cvCppCross{CamShift}, the search window size or orientation do not change during the search. You can simply pass the output of \cvCppCross{calcBackProject} to this function, but better results can be obtained if you pre-filter the back projection and remove the noise (e.g. by retrieving connected components with \cvCppCross{findContours}, throwing away contours with small area (\cvCppCross{contourArea}) and rendering the remaining contours with \cvCppCross{drawContours})
|
||||
|
||||
|
||||
\cvclass{KalmanFilter}
|
||||
Kalman filter class
|
||||
|
||||
\begin{lstlisting}
|
||||
class KalmanFilter
|
||||
{
|
||||
public:
|
||||
KalmanFilter();
|
||||
KalmanFilter(int dynamParams, int measureParams, int controlParams=0);
|
||||
void init(int dynamParams, int measureParams, int controlParams=0);
|
||||
// predicts statePre from statePost
|
||||
const Mat& predict(const Mat& control=Mat());
|
||||
// corrects statePre based on the input measurement vector
|
||||
// and stores the result to statePost.
|
||||
const Mat& correct(const Mat& measurement);
|
||||
|
||||
Mat statePre; // predicted state (x'(k)):
|
||||
// x(k)=A*x(k-1)+B*u(k)
|
||||
Mat statePost; // corrected state (x(k)):
|
||||
// x(k)=x'(k)+K(k)*(z(k)-H*x'(k))
|
||||
Mat transitionMatrix; // state transition matrix (A)
|
||||
Mat controlMatrix; // control matrix (B)
|
||||
// (it is not used if there is no control)
|
||||
Mat measurementMatrix; // measurement matrix (H)
|
||||
Mat processNoiseCov; // process noise covariance matrix (Q)
|
||||
Mat measurementNoiseCov;// measurement noise covariance matrix (R)
|
||||
Mat errorCovPre; // priori error estimate covariance matrix (P'(k)):
|
||||
// P'(k)=A*P(k-1)*At + Q)*/
|
||||
Mat gain; // Kalman gain matrix (K(k)):
|
||||
// K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)
|
||||
Mat errorCovPost; // posteriori error estimate covariance matrix (P(k)):
|
||||
// P(k)=(I-K(k)*H)*P'(k)
|
||||
...
|
||||
};
|
||||
\end{lstlisting}
|
||||
|
||||
The class implements standard Kalman filter \url{http://en.wikipedia.org/wiki/Kalman_filter}. However, you can modify \texttt{transitionMatrix}, \texttt{controlMatrix} and \texttt{measurementMatrix} to get the extended Kalman filter functionality. See the OpenCV sample \texttt{kalman.c}
|
||||
|
||||
\fi
|
Loading…
x
Reference in New Issue
Block a user