Commit f39db3f1 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

fixed problems indicated with ? marks

parent 3467c6f7
...@@ -48,7 +48,7 @@ copyright = u'2010, authors' ...@@ -48,7 +48,7 @@ copyright = u'2010, authors'
# The short X.Y version. # The short X.Y version.
version = '2.2' version = '2.2'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '2.2' release = '2.2.9'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.
......
...@@ -440,6 +440,7 @@ int CvFMEstimator::run8Point( const CvMat* _m1, const CvMat* _m2, CvMat* _fmatri ...@@ -440,6 +440,7 @@ int CvFMEstimator::run8Point( const CvMat* _m1, const CvMat* _m2, CvMat* _fmatri
const CvPoint2D64f* m1 = (const CvPoint2D64f*)_m1->data.ptr; const CvPoint2D64f* m1 = (const CvPoint2D64f*)_m1->data.ptr;
const CvPoint2D64f* m2 = (const CvPoint2D64f*)_m2->data.ptr; const CvPoint2D64f* m2 = (const CvPoint2D64f*)_m2->data.ptr;
double* fmatrix = _fmatrix->data.db; double* fmatrix = _fmatrix->data.db;
CV_Assert( (_m1->cols == 1 || _m1->rows == 1) && CV_ARE_SIZES_EQ(_m1, _m2));
int i, j, k, count = _m1->cols*_m1->rows; int i, j, k, count = _m1->cols*_m1->rows;
// compute centers and average distances for each of the two point sets // compute centers and average distances for each of the two point sets
...@@ -464,7 +465,7 @@ int CvFMEstimator::run8Point( const CvMat* _m1, const CvMat* _m2, CvMat* _fmatri ...@@ -464,7 +465,7 @@ int CvFMEstimator::run8Point( const CvMat* _m1, const CvMat* _m2, CvMat* _fmatri
double x = m1[i].x - m0c.x, y = m1[i].y - m0c.y; double x = m1[i].x - m0c.x, y = m1[i].y - m0c.y;
scale0 += sqrt(x*x + y*y); scale0 += sqrt(x*x + y*y);
x = fabs(m2[i].x - m1c.x), y = fabs(m2[i].y - m1c.y); x = m2[i].x - m1c.x, y = m2[i].y - m1c.y;
scale1 += sqrt(x*x + y*y); scale1 += sqrt(x*x + y*y);
} }
......
...@@ -27,7 +27,7 @@ MSER ...@@ -27,7 +27,7 @@ MSER
---- ----
.. c:type:: MSER .. c:type:: MSER
Maximally (or Most??) stable extremal region extractor :: Maximally stable extremal region extractor ::
class MSER : public CvMSERParams class MSER : public CvMSERParams
{ {
...@@ -85,7 +85,7 @@ Class implementing the Star keypoint detector :: ...@@ -85,7 +85,7 @@ Class implementing the Star keypoint detector ::
}; };
The class implements a modified version of the CenSurE keypoint detector described in The class implements a modified version of the CenSurE keypoint detector described in
Agrawal08??. [Agrawal08].
.. index:: SIFT .. index:: SIFT
...@@ -210,10 +210,10 @@ Class for extracting Speeded Up Robust Features from an image :: ...@@ -210,10 +210,10 @@ Class for extracting Speeded Up Robust Features from an image ::
bool useProvidedKeypoints=false) const; bool useProvidedKeypoints=false) const;
}; };
The class implements the Speeded Up Robust Features descriptor Bay06. The class implements the Speeded Up Robust Features descriptor [Bay06].
There is a fast multi-scale Hessian keypoint detector that can be used to find keypoints There is a fast multi-scale Hessian keypoint detector that can be used to find keypoints
(which is the default option). But the descriptors can be also computed for the user-specified 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, and so on. See the ``find_obj.cpp`` demo in OpenCV samples directory. The algorithm can be used for object tracking and localization, image stitching, and so on. See the ``find_obj.cpp`` demo in OpenCV samples directory.
.. index:: RandomizedTree .. index:: RandomizedTree
...@@ -301,13 +301,19 @@ RandomizedTree::train ...@@ -301,13 +301,19 @@ RandomizedTree::train
.. c:function:: void train(std::vector<BaseKeypoint> const& base_set, RNG& rng, PatchGenerator& make_patch, int depth, int views, size_t reduced_num_dim, int num_quant_bits) .. c:function:: void train(std::vector<BaseKeypoint> const& base_set, RNG& rng, PatchGenerator& make_patch, int depth, int views, size_t reduced_num_dim, int num_quant_bits)
{Vector of ``BaseKeypoint`` type. Contains keypoints from the image that are used for training}?? :param base_set: Vector of ``BaseKeypoint`` type. Contains keypoints from the image that are used for training
{Random numbers generator is used for training}??
{Patch generator is used for training}?? :param rng: Random numbers generator is used for training
{Maximum tree depth}??
:param make_patch: Patch generator is used for training
:param depth: Maximum tree depth
{Number of dimensions are used in compressed signature}?? :param views: The number of random views of each keypoint neighborhood to generate
{Number of bits are used for quantization}??
:param reduced_num_dim: Number of dimensions are used in compressed signature
:param num_quant_bits: Number of bits are used for quantization
.. index:: RandomizedTree::read .. index:: RandomizedTree::read
...@@ -315,15 +321,15 @@ RandomizedTree::read ...@@ -315,15 +321,15 @@ RandomizedTree::read
------------------------ ------------------------
.. c:function:: read(const char* file_name, int num_quant_bits) .. c:function:: read(const char* file_name, int num_quant_bits)
Reads a pre-saved randomized tree from a file or stream. ?? is it applied to the 1st func only? .. c:function:: read(std::istream &is, int num_quant_bits)
.. c:function:: read(std::istream \&is, int num_quant_bits) Read a pre-saved randomized tree from a file or stream.
:param file_name: Name of the file that contains randomized tree data. :param file_name: Name of the file that contains randomized tree data.
:param is: Input stream associated with the file that contains randomized tree data. :param is: Input stream associated with the file that contains randomized tree data.
{Number of bits are used for quantization}?? :param num_quant_bits: Number of bits are used for quantization
.. index:: RandomizedTree::write .. index:: RandomizedTree::write
...@@ -347,7 +353,7 @@ RandomizedTree::applyQuantization ...@@ -347,7 +353,7 @@ RandomizedTree::applyQuantization
Applies quantization to the current randomized tree. Applies quantization to the current randomized tree.
{Number of bits are used for quantization}?? :param num_quant_bits: Number of bits are used for quantization
.. index:: RTreeNode .. index:: RTreeNode
...@@ -459,15 +465,23 @@ RTreeClassifier::train ...@@ -459,15 +465,23 @@ RTreeClassifier::train
.. c:function:: void train(vector<BaseKeypoint> const& base_set, 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) .. c:function:: void train(vector<BaseKeypoint> const& base_set, 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)
{Vector of ``BaseKeypoint`` type. Contains image keypoints used for training}?? :param base_set: Vector of ``BaseKeypoint`` type. Contains image keypoints used for training
{Random-number generator is used for training}??
{Patch generator is used for training}?? :param rng: Random-number generator is used for training
{Number of randomized trees used in RTreeClassificator}??
{Maximum tree depth}?? :param make_patch: Patch generator is used for training
:param num_trees: Number of randomized trees used in RTreeClassificator
:param depth: Maximum tree depth
:param views: The number of random views of each keypoint neighborhood to generate
{Number of dimensions are used in compressed signature}?? :param reduced_num_dim: Number of dimensions are used in compressed signature
{Number of bits are used for quantization}??
{Print current status of training on the console}?? :param num_quant_bits: Number of bits are used for quantization
:param print_status: Print current status of training on the console
.. index:: RTreeClassifier::getSignature .. index:: RTreeClassifier::getSignature
...@@ -479,8 +493,8 @@ RTreeClassifier::getSignature ...@@ -479,8 +493,8 @@ RTreeClassifier::getSignature
.. c:function:: void getSignature(IplImage *patch, float *sig) .. c:function:: void getSignature(IplImage *patch, float *sig)
{Image patch to calculate signature for} :param patch: Image patch to calculate signature for
{Output signature (array dimension is ``reduced_num_dim)`` } :param sig: Output signature (array dimension is ``reduced_num_dim)``
.. index:: RTreeClassifier::getSparseSignature .. index:: RTreeClassifier::getSparseSignature
...@@ -489,11 +503,13 @@ RTreeClassifier::getSparseSignature ...@@ -489,11 +503,13 @@ RTreeClassifier::getSparseSignature
.. c:function:: void getSparseSignature(IplImage *patch, float *sig, float thresh) .. c:function:: void getSparseSignature(IplImage *patch, float *sig, float thresh)
Similarly to ``getSignaturebut`` , uses a threshold for removing all signature elements below the threshold so that the signature is compressed.?? Similarly to ``getSignature``, but it uses a threshold for removing all signature elements below the threshold so that the signature is compressed.
{Image patch to calculate signature for}?? :param patch: Image patch to calculate signature for
{Output signature (array dimension is ``reduced_num_dim)``}??
{The threshold that is used for compressing the signature}?? :param sig: Output signature (array dimension is ``reduced_num_dim)``
:param thresh: The threshold that is used for compressing the signature
.. index:: RTreeClassifier::countNonZeroElements .. index:: RTreeClassifier::countNonZeroElements
...@@ -507,7 +523,7 @@ RTreeClassifier::countNonZeroElements ...@@ -507,7 +523,7 @@ RTreeClassifier::countNonZeroElements
:param n: Input vector size. :param n: Input vector size.
{The threshold used for counting elements. We take all elements are less than ``tol`` as zero elements}?? :param tol: The threshold used for counting elements. We take all elements are less than ``tol`` as zero elements
.. index:: RTreeClassifier::read .. index:: RTreeClassifier::read
...@@ -531,11 +547,11 @@ RTreeClassifier::write ...@@ -531,11 +547,11 @@ RTreeClassifier::write
Writes the current RTreeClassifier to a file or stream. Writes the current RTreeClassifier to a file or stream.
.. c:function:: void write(std::ostream \&os) const .. c:function:: void write(std::ostream &os) const
:param file_name: Name of the file where randomized tree data is stored. :param file_name: Name of the file where randomized tree data is stored.
:param is: Output stream associated with the file where randomized tree data is stored. :param os: Output stream associated with the file where randomized tree data is stored.
.. index:: RTreeClassifier::setQuantization .. index:: RTreeClassifier::setQuantization
...@@ -545,7 +561,7 @@ RTreeClassifier::setQuantization ...@@ -545,7 +561,7 @@ RTreeClassifier::setQuantization
Applies quantization to the current randomized tree. Applies quantization to the current randomized tree.
{Number of bits are used for quantization}?? :param num_quant_bits: Number of bits are used for quantization
The example below demonstrates the usage of ``RTreeClassifier`` for feature matching. There are test and train images and features are extracted from both with SURF. Output is The example below demonstrates the usage of ``RTreeClassifier`` for feature matching. There are test and train images and features are extracted from both with SURF. Output is
:math:`best\_corr` and :math:`best\_corr` and
......
...@@ -85,9 +85,9 @@ setWindowProperty ...@@ -85,9 +85,9 @@ setWindowProperty
* **CV_WINDOW_FULLSCREEN** Change the window to fullscreen. * **CV_WINDOW_FULLSCREEN** Change the window to fullscreen.
* **CV_WINDOW_FREERATIO** Make the image extendable (no ratio constraint).?? * **CV_WINDOW_FREERATIO** Make the window resizable without any ratio constraints.
* **CV_WINDOW_KEEPRATIO** Maintain the image ratio.?? * **CV_WINDOW_KEEPRATIO** Make the window resizable, but preserve the proportions of the displayed image.
The function ``setWindowProperty`` enables changing properties of a window. The function ``setWindowProperty`` enables changing properties of a window.
...@@ -200,19 +200,17 @@ displayOverlay ...@@ -200,19 +200,17 @@ displayOverlay
:param text: Overlay text to write on a window image. :param text: Overlay text to write on a window image.
:param delay: Duration (in milliseconds)? to display the overlay text. If this function is called before the previous overlay text timed out, the timer is restarted and the text is updated. If this value is zero, the text never disappears. :param delay: The period (in milliseconds), during which the overlay text is displayed. If this function is called before the previous overlay text timed out, the timer is restarted and the text is updated. If this value is zero, the text never disappears.
The function ``displayOverlay`` displays useful information/tips on top of the window for a certain amount of time The function ``displayOverlay`` displays useful information/tips on top of the window for a certain amount of time *delay*. The function does not modify the image, displayed in the window, that is, after the specified delay the original content of the window is restored.
*delay*
. This does not affect the image data.??
.. index:: displayStatusBar .. index:: displayStatusBar
displayStatusBar displayStatusBar
-------------------- --------------------
.. c:function:: void displayStatusBar(const string& name, const string& text, int delayms) .. c:function:: void displayStatusBar(const string& name, const string& text, int delay)
Displays a text on the window statusbar for a specified duration.?? Displays a text on the window statusbar during the specified period of time.
:param name: Name of the window. :param name: Name of the window.
...@@ -231,7 +229,7 @@ createOpenGLCallback ...@@ -231,7 +229,7 @@ createOpenGLCallback
.. c:function:: 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) .. c:function:: 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)
Creates a callback function called to draw OpenGL on top the the image display by ``windowname`` . Creates a callback function called to draw OpenGL on top the the image display by ``windowname``.
:param window_name: Name of the window. :param window_name: Name of the window.
...@@ -313,7 +311,7 @@ createButton ...@@ -313,7 +311,7 @@ createButton
Creates a callback function called to draw OpenGL on top of the image display by ``windowname`` . Creates a callback function called to draw OpenGL on top of the image display by ``windowname`` .
:param button_name: Name of the button. If NULL, the name is ``button <number of buttons>`` .?? :param button_name: Name of the button.
:param on_change: Pointer to the function to be called every time the button changes its state. This function should be prototyped as ``void Foo(int state,*void);`` . *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. :param on_change: Pointer to the function to be called every time the button changes its state. This function should be prototyped as ``void Foo(int state,*void);`` . *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.
......
...@@ -210,17 +210,15 @@ VideoCapture::VideoCapture ...@@ -210,17 +210,15 @@ VideoCapture::VideoCapture
------------------------------ ------------------------------
.. c:function:: VideoCapture::VideoCapture() .. c:function:: VideoCapture::VideoCapture()
.. c:function:: VideoCapture::VideoCapture(const string\& filename) .. c:function:: VideoCapture::VideoCapture(const string& filename)
.. c:function:: VideoCapture::VideoCapture(int device) .. c:function:: VideoCapture::VideoCapture(int device)
VideoCapture constructors.?? No desc here and further?? VideoCapture constructors.
:param filename: TOWRITE
:param device: TOWRITE
:param filename: name of the opened video file
:param device: id of the opened video capturing device (i.e. a camera index).
.. index:: VideoCapture::get .. index:: VideoCapture::get
...@@ -281,7 +279,7 @@ VideoCapture::set ...@@ -281,7 +279,7 @@ VideoCapture::set
--------------------- ---------------------
.. c:function:: bool VideoCapture::set(int property_id, double value) .. c:function:: bool VideoCapture::set(int property_id, double value)
Sets a property in the VideoCapture backend. Sets a property in the VideoCapture backend.
:param property_id: Property identifier. It can be one of the following: :param property_id: Property identifier. It can be one of the following:
......
...@@ -158,7 +158,7 @@ cornerSubPix ...@@ -158,7 +158,7 @@ cornerSubPix
:param 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 a size. :param 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 a size.
:param 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 ``criteria`` may specify either the maximum number of iteration or the required accuracy, or both of them.?? :param criteria: Criteria for termination of the iterative process of corner refinement. That is, the process of corner position refinement stops either after ``criteria.maxCount`` iterations or when the corner position moves by less than ``criteria.epsilon`` on some iteration.
The function iterates to find the sub-pixel accurate location of corners or radial saddle points, as shown on the picture below. The function iterates to find the sub-pixel accurate location of corners or radial saddle points, as shown on the picture below.
...@@ -223,11 +223,11 @@ goodFeaturesToTrack ...@@ -223,11 +223,11 @@ goodFeaturesToTrack
:param blockSize: Size of an average block for computing a derivative covariation matrix over each pixel neighborhood. See :func:`cornerEigenValsAndVecs` . :param blockSize: Size of an average block for computing a derivative covariation matrix over each pixel neighborhood. See :func:`cornerEigenValsAndVecs` .
:param useHarrisDetector: Parameter indicating whether to use an operator or :func:`cornerMinEigenVal` .?? :param useHarrisDetector: Parameter indicating whether to use a Harris detector (see :func:`cornerHarris`) or :func:`cornerMinEigenVal`.
:param k: Free parameter of the Harris detector. :param k: Free parameter of the Harris detector.
The function finds the most prominent corners in the image or in the specified image region, as described in Shi94: The function finds the most prominent corners in the image or in the specified image region, as described in [Shi94]:
#. #.
Function calculates the corner quality measure at every source image pixel using the Function calculates the corner quality measure at every source image pixel using the
......
...@@ -323,7 +323,7 @@ resize ...@@ -323,7 +323,7 @@ resize
* **INTER_LINEAR** - a bilinear interpolation (used by default) * **INTER_LINEAR** - a bilinear interpolation (used by default)
* **INTER_AREA** - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives freer?? results. But when the image is zoomed, it is similar to the ``INTER_NEAREST`` method. * **INTER_AREA** - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire'-free results. But when the image is zoomed, it is similar to the ``INTER_NEAREST`` method.
* **INTER_CUBIC** - a bicubic interpolation over 4x4 pixel neighborhood * **INTER_CUBIC** - a bicubic interpolation over 4x4 pixel neighborhood
......
...@@ -78,7 +78,7 @@ cvtColor ...@@ -78,7 +78,7 @@ cvtColor
:param dst: Destination image of the same size and depth as ``src`` . :param dst: Destination image of the same size and depth as ``src`` .
:param code: Color space conversion code. See the details below.??/formatting/ :param code: Color space conversion code. See the description below.
:param dstCn: Number of channels in the destination image. If the parameter is 0, the number of the channels is derived automatically from ``src`` and ``code`` . :param dstCn: Number of channels in the destination image. If the parameter is 0, the number of the channels is derived automatically from ``src`` and ``code`` .
...@@ -207,7 +207,7 @@ The function can do the following transformations: ...@@ -207,7 +207,7 @@ The function can do the following transformations:
If If
:math:`H<0` then :math:`H<0` then
:math:`H \leftarrow H+360` . On output :math:`H \leftarrow H+360` . On output
:math:`0 \leq V \leq 1`, :math:`0 \leq S \leq 1`, :math:`0 \leq H \leq 360` .?? :math:`0 \leq V \leq 1`, :math:`0 \leq S \leq 1`, :math:`0 \leq H \leq 360` .
The values are then converted to the destination data type: The values are then converted to the destination data type:
...@@ -414,7 +414,7 @@ distanceTransform ...@@ -414,7 +414,7 @@ distanceTransform
:param dst: Output image with calculated distances. It is a 32-bit floating-point, single-channel image of the same size as ``src`` . :param dst: Output image with calculated distances. It is a 32-bit floating-point, single-channel image of the same size as ``src`` .
:param distanceType: Type of distance. It can be ``CV_DIST_L1, CV_DIST_L2`` , or ``CV_DIST_C`` . :param distanceType: Type of distance. It can be ``CV_DIST_L1, CV_DIST_L2`` , or ``CV_DIST_C`` .
:param maskSize: Size of the distance transform mask. It can be 3, 5, or ``CV_DIST_MASK_PRECISE`` (the latter option is only supported by the first function??). In case of the ``CV_DIST_L1`` or ``CV_DIST_C`` distance type, the parameter is forced to 3 because a :math:`3\times 3` mask gives the same result as :math:`5\times 5` or any larger aperture. :param maskSize: Size of the distance transform mask. It can be 3, 5, or ``CV_DIST_MASK_PRECISE`` (the latter option is only supported by the first function). In case of the ``CV_DIST_L1`` or ``CV_DIST_C`` distance type, the parameter is forced to 3 because a :math:`3\times 3` mask gives the same result as :math:`5\times 5` or any larger aperture.
:param labels: Optional output 2D array of labels (the discrete Voronoi diagram). It has the type ``CV_32SC1`` and the same size as ``src`` . See the details below. :param labels: Optional output 2D array of labels (the discrete Voronoi diagram). It has the type ``CV_32SC1`` and the same size as ``src`` . See the details below.
...@@ -500,58 +500,70 @@ floodFill ...@@ -500,58 +500,70 @@ floodFill
* **FLOODFILL_MASK_ONLY** If set, the function does not change the image ( ``newVal`` is ignored), but fills the mask. The flag can be used for the second variant only. * **FLOODFILL_MASK_ONLY** If set, the function does not change the image ( ``newVal`` is ignored), but fills the mask. The flag can be used for the second variant only.
The functions ``floodFill`` fill a connected component starting from the seed point with the specified color. The connectivity is determined by the color/brightness closeness of the neighbor pixels. The pixel at The functions ``floodFill`` fill a connected component starting from the seed point with the specified color. The connectivity is determined by the color/brightness closeness of the neighbor pixels. The pixel at
:math:`(x,y)` is considered to belong to the repainted domain if??: :math:`(x,y)` is considered to belong to the repainted domain if:
* Grayscale image, floating range
*
.. math:: .. math::
\texttt{src} (x',y')- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} (x',y')+ \texttt{upDiff} \texttt{src} (x',y')- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} (x',y')+ \texttt{upDiff}
* Grayscale image, fixed range in the case of grayscale image and floating range
*
.. math:: .. math::
\texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)+ \texttt{upDiff} \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)- \texttt{loDiff} \leq \texttt{src} (x,y) \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)+ \texttt{upDiff}
* Color image, floating range in the case of grayscale image and fixed range
*
.. math:: .. math::
\texttt{src} (x',y')_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} (x',y')_r+ \texttt{upDiff} _r \texttt{src} (x',y')_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} (x',y')_r+ \texttt{upDiff} _r,
.. math:: .. math::
\texttt{src} (x',y')_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} (x',y')_g+ \texttt{upDiff} _g \texttt{src} (x',y')_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} (x',y')_g+ \texttt{upDiff} _g
and
.. math:: .. math::
\texttt{src} (x',y')_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} (x',y')_b+ \texttt{upDiff} _b \texttt{src} (x',y')_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} (x',y')_b+ \texttt{upDiff} _b
* Color image, fixed range in the case of color image and floating range
*
.. math:: .. math::
\texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_r+ \texttt{upDiff} _r \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_r- \texttt{loDiff} _r \leq \texttt{src} (x,y)_r \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_r+ \texttt{upDiff} _r,
.. math:: .. math::
\texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_g+ \texttt{upDiff} _g \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_g- \texttt{loDiff} _g \leq \texttt{src} (x,y)_g \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_g+ \texttt{upDiff} _g
and
.. math:: .. math::
\texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_b+ \texttt{upDiff} _b \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_b- \texttt{loDiff} _b \leq \texttt{src} (x,y)_b \leq \texttt{src} ( \texttt{seed} .x, \texttt{seed} .y)_b+ \texttt{upDiff} _b
in the case of color image and fixed range
where where
:math:`src(x',y')` is the value of one of pixel neighbors that is already known to belong to the component. That is, to be added to the connected component, a color/brightness of the pixel should be close enough to: :math:`src(x',y')` is the value of one of pixel neighbors that is already known to belong to the component. That is, to be added to the connected component, a color/brightness of the pixel should be close enough to:
* *
Color/brightness of one of its neighbors that are already referred to in?? the connected component in case of floating range. Color/brightness of one of its neighbors that already belong to the connected component in case of floating range.
* *
Color/brightness of the seed point in case of fixed range. Color/brightness of the seed point in case of fixed range.
Use these functions to either mark a connected component with the specified color in-place, or build a mask and then extract the contour, or copy the region to another image, and so on. Various modes of the function are demonstrated in the ``floodfill.c`` sample. Use these functions to either mark a connected component with the specified color in-place, or build a mask and then extract the contour, or copy the region to another image, and so on. Various modes of the function are demonstrated in the ``floodfill.cpp`` sample.
See Also: See Also:
:func:`findContours` :func:`findContours`
...@@ -564,7 +576,7 @@ inpaint ...@@ -564,7 +576,7 @@ inpaint
----------- -----------
.. c:function:: void inpaint( const Mat& src, const Mat& inpaintMask, Mat& dst, double inpaintRadius, int flags ) .. c:function:: void inpaint( const Mat& src, const Mat& inpaintMask, Mat& dst, double inpaintRadius, int flags )
Removes?? the selected region in an image. Restores the selected region in an image using the region neighborhood.
:param src: Input 8-bit 1-channel or 3-channel image. :param src: Input 8-bit 1-channel or 3-channel image.
...@@ -602,11 +614,11 @@ integral ...@@ -602,11 +614,11 @@ integral
:param sum: Integral image as :math:`(W+1)\times (H+1)` , 32-bit integer or floating-point (32f or 64f). :param sum: Integral image as :math:`(W+1)\times (H+1)` , 32-bit integer or floating-point (32f or 64f).
:param sqsum: Integral image for squared pixel values represented as?? :math:`(W+1)\times (H+1)` , double precision floating-point (64f). :param sqsum: Integral image for squared pixel values. It will be :math:`(W+1)\times (H+1)`, double-precision floating-point (64f) array.
:param tilted: Integral for the image rotated by 45 degrees represented as :math:`(W+1)\times (H+1)` , with the same data type as ``sum`` . :param tilted: Integral for the image rotated by 45 degrees. It will be :math:`(W+1)\times (H+1)` array with the same data type as ``sum``.
:param sdepth: Desired depth of the integral and the tilted integral images, ``CV_32S`` , ``CV_32F`` , or ``CV_64F`` . :param sdepth: Desired depth of the integral and the tilted integral images, ``CV_32S``, ``CV_32F``, or ``CV_64F``.
The functions calculate one or more integral images for the source image as following: The functions calculate one or more integral images for the source image as following:
...@@ -644,7 +656,7 @@ As a practical example, the next figure shows the calculation of the integral of ...@@ -644,7 +656,7 @@ As a practical example, the next figure shows the calculation of the integral of
threshold threshold
------------- -------------
.. c:function:: double threshold( const Mat& src, Mat& dst, double thresh, double maxVal, int thresholdType ) .. c:function:: double threshold( const Mat& src, Mat& dst, double thresh, double maxVal, int thresholdType )
Applies a fixed-level threshold to each array element. Applies a fixed-level threshold to each array element.
...@@ -727,9 +739,7 @@ watershed ...@@ -727,9 +739,7 @@ watershed
The function implements one of the variants The function implements one of the variants
of watershed, non-parametric marker-based segmentation algorithm, of watershed, non-parametric marker-based segmentation algorithm,
described in described in [Meyer92]. Before passing the image to the
Meyer92??
. Before passing the image to the
function, you have to roughly outline the desired regions in the image ``markers`` with positive ( function, you have to roughly outline the desired regions in the image ``markers`` with positive (
:math:`>0` ) indices. So, every region is :math:`>0` ) indices. So, every region is
represented as one or more connected components with the pixel values represented as one or more connected components with the pixel values
...@@ -766,9 +776,9 @@ grabCut ...@@ -766,9 +776,9 @@ grabCut
:param image: Input 8-bit 3-channel image. :param image: Input 8-bit 3-channel image.
:param mask: Input/output 8-bit single-channel mask. Its elements may have one of four values. The mask is initialized when ``mode==GC_INIT_WITH_RECT`` . :param mask: Input/output 8-bit single-channel mask. The mask is initialized by the function when ``mode`` is set to ``GC_INIT_WITH_RECT``. Its elements may have one of following values:
* **GC_BGD** defines an obvious background pixel.?? * **GC_BGD** defines an obvious background pixels.
* **GC_FGD** defines an obvious foreground (object) pixel. * **GC_FGD** defines an obvious foreground (object) pixel.
...@@ -776,7 +786,7 @@ grabCut ...@@ -776,7 +786,7 @@ grabCut
* **GC_PR_BGD** defines a possible foreground pixel. * **GC_PR_BGD** defines a possible foreground pixel.
:param rect: ROI containing a segmented object. The pixels outside of the ROI are marked as "obvious background"??. The parameter is only used when ``mode==GC_INIT_WITH_RECT`` . :param rect: ROI containing a segmented object. The pixels outside of the ROI are marked as "obvious background". The parameter is only used when ``mode==GC_INIT_WITH_RECT`` .
:param bgdModel, fgdModel: Temporary arrays used for segmentation. Do not modify them while you are processing the same image. :param bgdModel, fgdModel: Temporary arrays used for segmentation. Do not modify them while you are processing the same image.
......
...@@ -10,7 +10,7 @@ moments ...@@ -10,7 +10,7 @@ moments
.. c:function:: Moments moments( const Mat& array, bool binaryImage=false ) .. c:function:: Moments moments( const Mat& array, bool binaryImage=false )
Calculates all of the moments up to the third order of a polygon or rasterized shape where the class ``Moments`` is defined as: :: Calculates all of the moments up to the third order of a polygon or rasterized shape where the class ``Moments`` is defined as: ::
class Moments class Moments
{ {
public: public:
...@@ -131,7 +131,7 @@ findContours ...@@ -131,7 +131,7 @@ findContours
:param method: Contour approximation method. :param method: Contour approximation method.
* **CV_CHAIN_APPROX_NONE** stores absolutely all contour points. That is, every 2 points of a contour stored with this method are 8?? connected neighbors of each other. * **CV_CHAIN_APPROX_NONE** stores absolutely all the contour points. That is, any 2 subsequent points ``(x1,y1)`` and ``(x2,y2)`` of the contour will be either horizontal, vertical or diagonal neighbors, that is, ``max(abs(x1-x2),abs(y2-y1))==1``.
* **CV_CHAIN_APPROX_SIMPLE** compresses horizontal, vertical, and diagonal segments and leaves only their end points. For example, an up-right rectangular contour is encoded with 4 points. * **CV_CHAIN_APPROX_SIMPLE** compresses horizontal, vertical, and diagonal segments and leaves only their end points. For example, an up-right rectangular contour is encoded with 4 points.
...@@ -227,7 +227,7 @@ approxPolyDP ...@@ -227,7 +227,7 @@ approxPolyDP
Approximates a polygonal curve(s) with the specified precision. Approximates a polygonal curve(s) with the specified precision.
:param curve: Polygon or curve to approximate. It must be :math:`1 \times N` or :math:`N \times 1` matrix of type ``CV_32SC2`` or ``CV_32FC2`` . You can also convert ``vector<Point>`` or ``vector<Point2f`` >?? to the matrix by calling the ``Mat(const vector<T>&)`` constructor. :param curve: Polygon or curve to approximate. It must be :math:`1 \times N` or :math:`N \times 1` matrix of type ``CV_32SC2`` or ``CV_32FC2`` . You can also convert ``vector<Point>`` or ``vector<Point2f>`` to the matrix by calling the ``Mat(const vector<T>&)`` constructor.
:param approxCurve: Result of the approximation. The type should match the type of the input curve. :param approxCurve: Result of the approximation. The type should match the type of the input curve.
...@@ -306,7 +306,7 @@ See Also: ...@@ -306,7 +306,7 @@ See Also:
estimateAffine3D estimateAffine3D
-------------------- --------------------
.. c:function:: int estimateAffine3D(const Mat& srcpt, const Mat& dstpt, Mat& out, vector<uchar>& outliers, double ransacThreshold = 3.0, double confidence = 0.99) .. c:function:: int estimateAffine3D(const Mat& srcpt, const Mat& dstpt, Mat& out, vector<uchar>& outliers, double ransacThreshold = 3.0, double confidence = 0.99)
Computes an optimal affine transformation between two 3D point sets. Computes an optimal affine transformation between two 3D point sets.
...@@ -315,12 +315,12 @@ estimateAffine3D ...@@ -315,12 +315,12 @@ estimateAffine3D
:param dstpt: The second input 3D point set. :param dstpt: The second input 3D point set.
:param out: Output 3D affine transformation matrix :math:`3 \times 4` . :param out: Output 3D affine transformation matrix :math:`3 \times 4` .
:param outliers: Output vector indicating which points are outliers. :param outliers: Output vector indicating which points are outliers.
:param ransacThreshold: Maximum reprojection error in the RANSAC algorithm to consider a point as an inlier. :param ransacThreshold: Maximum reprojection error in the RANSAC algorithm to consider a point as an inlier.
:param confidence: Confidence level, between 0 and 1, to estimate a matrix.?? :param confidence: The confidence level, between 0 and 1, that the estimated transformation will have. Anything between 0.95 and 0.99 is usually good enough. Too close to 1 values can slow down the estimation too much, lower than 0.8-0.9 confidence values can result in an incorrectly estimated transformation.
The function estimates an optimal 3D affine transformation between two 3D point sets using the RANSAC algorithm. The function estimates an optimal 3D affine transformation between two 3D point sets using the RANSAC algorithm.
...@@ -385,11 +385,11 @@ that has ...@@ -385,11 +385,11 @@ that has
fitEllipse fitEllipse
-------------- --------------
.. c:function:: RotatedRect fitEllipse( const Mat& points ) .. c:function:: RotatedRect fitEllipse( const InputArray& points )
Fits an ellipse around a set of 2D points. Fits an ellipse around a set of 2D points.
:param points: Input 2D point set represented either by ``CV_32SC2`` or ``CV_32FC2`` matrix, or by ``vector<Point>`` /``vector<Point2f>`` converted to a matrix using the ``Mat(const vector<T>&)`` constructor. :param points: Input 2D point set represented either by ``CV_32SC2`` or ``CV_32FC2`` matrix, or by ``vector<Point>`` or ``vector<Point2f>``.
The function calculates the ellipse that fits (in least-squares sense) a set of 2D points best of all. It returns the rotated rectangle in which the ellipse is inscribed. The function calculates the ellipse that fits (in least-squares sense) a set of 2D points best of all. It returns the rotated rectangle in which the ellipse is inscribed.
...@@ -397,18 +397,13 @@ The function calculates the ellipse that fits (in least-squares sense) a set of ...@@ -397,18 +397,13 @@ The function calculates the ellipse that fits (in least-squares sense) a set of
fitLine fitLine
----------- -----------
.. c:function:: void fitLine( const Mat& points, Vec4f& line, int distType, double param, double reps, double aeps ) .. c:function:: void fitLine( const InputArray& points, OutputArray& line, int distType, double param, double reps, double aeps )
.. c:function:: void fitLine( const Mat& points, Vec6f& line, int distType, double param, double reps, double aeps )
Fits a line to a 2D or 3D point set. Fits a line to a 2D or 3D point set.
:param points: Input 2D point set represented either by ``CV_32SC2`` or ``CV_32FC2`` matrix, or by ``vector<Point>`` /``vector<Point2f>`` / ``vector<Point3i>`` /``vector<Point3f>`` converted to a matrix by the ``Mat(const vector<T>&)`` constructor. :param points: Input 2D or 3D point set represented either by ``CV_32SC2`` or ``CV_32FC2`` matrix, or by ``vector<Point>``, ``vector<Point2f>``, ``vector<Point3i>`` or ``vector<Point3f>``.
:param line: Output line parameters. In case of 2D fitting, :param line: Output line parameters. In case of 2D fitting it should be ``Vec4f``, a vector of 4 floats ``(vx, vy, x0, y0)``, where ``(vx, vy)`` is a normalized vector collinear to the line and ``(x0, y0)`` is a point on the line. In case of 3D fitting, it should be ``Vec6f``, a vector of 6 floats ``(vx, vy, vz, x0, y0, z0)``, where ``(vx, vy, vz)`` is a normalized vector collinear to the line and ``(x0, y0, z0)`` is a point on the line.
it is a vector of 4 floats ``(vx, vy, x0, y0)`` where ``(vx, vy)`` is a normalized vector collinear to the
line and ``(x0, y0)`` is a point on the line. In case of
3D fitting, it is a vector of 6 floats ``(vx, vy, vz, x0, y0, z0)`` where ``(vx, vy, vz)`` is a normalized vector collinear to the line and ``(x0, y0, z0)`` is a point on the line.
:param distType: Distance used by the M-estimator (see the discussion). :param distType: Distance used by the M-estimator (see the discussion).
...@@ -416,7 +411,7 @@ fitLine ...@@ -416,7 +411,7 @@ fitLine
:param reps, aeps: Sufficient accuracy for the radius (distance between the coordinate origin and the line) and angle, respectively. 0.01 would be a good default value for both. :param reps, aeps: Sufficient accuracy for the radius (distance between the coordinate origin and the line) and angle, respectively. 0.01 would be a good default value for both.
The functions ``fitLine`` fit a line to a 2D or 3D point set by minimizing The function ``fitLine`` fits a line to a 2D or 3D point set by minimizing
:math:`\sum_i \rho(r_i)` where :math:`\sum_i \rho(r_i)` where
:math:`r_i` is a distance between the :math:`r_i` is a distance between the
:math:`i^{th}` point, the line and :math:`i^{th}` point, the line and
...@@ -468,11 +463,11 @@ http://en.wikipedia.org/wiki/M-estimator ...@@ -468,11 +463,11 @@ http://en.wikipedia.org/wiki/M-estimator
isContourConvex isContourConvex
------------------- -------------------
.. c:function:: bool isContourConvex( const Mat& contour ) .. c:function:: bool isContourConvex( const InputArray& contour )
Tests a contour convexity. Tests a contour convexity.
:param contour: Tested contour, a matrix of type ``CV_32SC2`` or ``CV_32FC2`` , or ``vector<Point>`` /``vector<Point2f>`` converted to the matrix using the ``Mat(const vector<T>&)`` constructor.?? :param contour: Tested contour, a matrix of type ``CV_32SC2`` or ``CV_32FC2`` , or ``vector<Point>`` or ``vector<Point2f>``.
The function tests whether the input contour is convex or not. The contour must be simple, that is, without self-intersections. Otherwise, the function output is undefined. The function tests whether the input contour is convex or not. The contour must be simple, that is, without self-intersections. Otherwise, the function output is undefined.
...@@ -480,35 +475,35 @@ The function tests whether the input contour is convex or not. The contour must ...@@ -480,35 +475,35 @@ The function tests whether the input contour is convex or not. The contour must
minAreaRect minAreaRect
--------------- ---------------
.. c:function:: RotatedRect minAreaRect( const Mat& points ) .. c:function:: RotatedRect minAreaRect( const InputArray& points )
Finds a rotated rectangle of the minimum area enclosing a 2D point set.?? Finds a rotated rectangle of the minimum area enclosing the input 2D point set.
:param points: Input 2D point set represented either by ``CV_32SC2`` or ``CV_32FC2`` matrix, or by ``vector<Point>`` /``vector<Point2f>`` converted to the matrix using the ``Mat(const vector<T>&)`` constructor. :param points: Input 2D point set represented either by ``CV_32SC2`` or ``CV_32FC2`` matrix, or by ``vector<Point>`` or ``vector<Point2f>``.
The function calculates and returns the minimum-area bounding rectangle (possibly rotated) for a specified point set. See the OpenCV sample ``minarea.c`` . The function calculates and returns the minimum-area bounding rectangle (possibly rotated) for a specified point set. See the OpenCV sample ``minarea.cpp`` .
.. index:: minEnclosingCircle .. index:: minEnclosingCircle
minEnclosingCircle minEnclosingCircle
---------------------- ----------------------
.. c:function:: void minEnclosingCircle( const Mat& points, Point2f& center, float& radius ) .. c:function:: void minEnclosingCircle( const InputArray& points, Point2f& center, float& radius )
Finds a circle of the minimum area enclosing a 2D point set. Finds a circle of the minimum area enclosing a 2D point set.
:param points: Input 2D point set represented either by ``CV_32SC2`` or ``CV_32FC2`` matrix, or by ``vector<Point>`` /``vector<Point2f>`` converted to the matrix using the ``Mat(const vector<T>&)`` constructor. :param points: Input 2D point set represented either by ``CV_32SC2`` or ``CV_32FC2`` matrix, or by ``vector<Point>`` or ``vector<Point2f>``.
:param center: Output center of the circle. :param center: Output center of the circle.
:param radius: Output radius of the circle. :param radius: Output radius of the circle.
The function finds the minimal enclosing circle of a 2D point set using an iterative algorithm. See the OpenCV sample ``minarea.c`` . The function finds the minimal enclosing circle of a 2D point set using an iterative algorithm. See the OpenCV sample ``minarea.cpp`` .
.. index:: matchShapes .. index:: matchShapes
matchShapes matchShapes
--------------- ---------------
.. c:function:: double matchShapes( const Mat& object1, const Mat& object2, int method, double parameter=0 ) .. c:function:: double matchShapes( const InputArray& object1, const InputArray& object2, int method, double parameter=0 )
Compares two shapes. Compares two shapes.
...@@ -558,7 +553,7 @@ and ...@@ -558,7 +553,7 @@ and
pointPolygonTest pointPolygonTest
-------------------- --------------------
.. c:function:: double pointPolygonTest( const Mat& contour, Point2f pt, bool measureDist ) .. c:function:: double pointPolygonTest( const InputArray& contour, Point2f pt, bool measureDist )
Performs a point-in-contour test. Performs a point-in-contour test.
......
#include "test_precomp.hpp" #include "test_precomp.hpp"
CV_TEST_MAIN("cv") //CV_TEST_MAIN("cv")
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
int
main(int argc, char *argv[])
{
cv::Mat src_img = cv::imread("/Users/vp/Downloads/lenna.png", 1);
if(!src_img.data) return -1;
cv::Point2f pts1[] = {cv::Point2f(150,150.),cv::Point2f(150,300.),cv::Point2f(350,300.),cv::Point2f(350,150.)};
cv::Point2f pts2[] = {cv::Point2f(200,200.),cv::Point2f(150,300.),cv::Point2f(350,300.),cv::Point2f(300,200.)};
cv::Mat perspective_matrix = cv::getPerspectiveTransform(pts1, pts2);
cv::Mat dst_img;
dst_img = cv::Scalar::all(0);
cv::warpPerspective(src_img, dst_img, perspective_matrix, src_img.size(), cv::INTER_LANCZOS4);
cv::namedWindow("src", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
cv::namedWindow("dst", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
cv::imshow("src", src_img);
cv::imshow("dst", dst_img);
cv::waitKey(0);
}
...@@ -33,7 +33,7 @@ calcOpticalFlowPyrLK ...@@ -33,7 +33,7 @@ calcOpticalFlowPyrLK
:param flags: Operation flags: :param flags: Operation flags:
* **OPTFLOW_USE_INITIAL_FLOW** Use initial estimations stored in ``nextPts`` . If the flag is not set, then initially?? :math:`\texttt{nextPts}\leftarrow\texttt{prevPts}` . * **OPTFLOW_USE_INITIAL_FLOW** Use initial estimations stored in ``nextPts`` . If the flag is not set, then ``prevPts`` is copied to ``nextPts`` and is considered as the initial estimate.
The function implements a sparse iterative version of the Lucas-Kanade optical flow in pyramids. See The function implements a sparse iterative version of the Lucas-Kanade optical flow in pyramids. See
Bouguet00 Bouguet00
...@@ -122,7 +122,7 @@ calcMotionGradient ...@@ -122,7 +122,7 @@ calcMotionGradient
:param mask: Output mask image that has the type ``CV_8UC1`` and the same size as ``mhi`` . Its non-zero elements mark pixels where the motion gradient data is correct. :param mask: Output mask image that has the type ``CV_8UC1`` and the same size as ``mhi`` . Its non-zero elements mark pixels where the motion gradient data is correct.
:param orientation: Output motion gradient orientation image that has the same type and the same size as ``mhi`` . Each pixel of the image is a motion orientation in degrees, from 0 to 360.?? :param orientation: Output motion gradient orientation image that has the same type and the same size as ``mhi`` . Each pixel of the image is a motion orientation, from 0 to 360 degrees.
:param delta1, delta2: Minimum and maximum allowed difference between ``mhi`` values within a pixel neighorhood. That is, the function finds the minimum ( :math:`m(x,y)` ) and maximum ( :math:`M(x,y)` ) ``mhi`` values over :math:`3 \times 3` neighborhood of each pixel and marks the motion orientation at :math:`(x, y)` as valid only if :param delta1, delta2: Minimum and maximum allowed difference between ``mhi`` values within a pixel neighorhood. That is, the function finds the minimum ( :math:`m(x,y)` ) and maximum ( :math:`M(x,y)` ) ``mhi`` values over :math:`3 \times 3` neighborhood of each pixel and marks the motion orientation at :math:`(x, y)` as valid only if
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment