converted user guide & tutorials from tex to rst; added them into the whole documentation tree; added html_docs target.

This commit is contained in:
Vadim Pisarevsky
2011-05-10 22:09:07 +00:00
parent 6facf8ba3b
commit b699e946b5
75 changed files with 1506 additions and 2120 deletions

View File

@@ -1,12 +0,0 @@
\chapter{cv::Mat. Operations with images.}
\renewcommand{\curModule}{cv::Mat. Operations with images.}
\input{user_guide/user_mat}
\chapter{Features2d.}
\renewcommand{\curModule}{Features2d}
\input{user_guide/user_features2d}
\chapter{Highgui.}
\renewcommand{\curModule}{Highgui.}
\input{user_guide/user_highgui}

View File

@@ -0,0 +1,97 @@
**********
Features2d
**********
.. highlight:: cpp
Detectors
=========
Descriptors
===========
Matching keypoints
==================
The code
-------
We will start with a short sample ``opencv/samples/cpp/matcher_simple.cpp``: ::
Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
Mat img2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
if(img1.empty() || img2.empty())
{
printf("Can't read one of the images\n");
return -1;
}
// detecting keypoints
SurfFeatureDetector detector(400);
vector<KeyPoint> keypoints1, keypoints2;
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);
// computing descriptors
SurfDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);
// matching descriptors
BruteForceMatcher<L2<float> > matcher;
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);
// drawing the results
namedWindow("matches", 1);
Mat img_matches;
drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
imshow("matches", img_matches);
waitKey(0);
The code explained
------------------
Let us break the code down. ::
Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
Mat img2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
if(img1.empty() || img2.empty())
{
printf("Can't read one of the images\n");
return -1;
}
We load two images and check if they are loaded correctly.::
// detecting keypoints
FastFeatureDetector detector(15);
vector<KeyPoint> keypoints1, keypoints2;
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);
First, we create an instance of a keypoint detector. All detectors inherit the abstract ``FeatureDetector`` interface, but the constructors are algorithm-dependent. The first argument to each detector usually controls the balance between the amount of keypoints and their stability. The range of values is different for different detectors (For instance, *FAST* threshold has the meaning of pixel intensity difference and usually varies in the region *[0,40]*. *SURF* threshold is applied to a Hessian of an image and usually takes on values larger than *100*), so use defaults in case of doubt. ::
// computing descriptors
SurfDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);
We create an instance of descriptor extractor. The most of OpenCV descriptors inherit ``DescriptorExtractor`` abstract interface. Then we compute descriptors for each of the keypoints. The output ``Mat`` of the ``DescriptorExtractor::compute`` method contains a descriptor in a row *i* for each *i*-th keypoint. Note that the method can modify the keypoints vector by removing the keypoints such that a descriptor for them is not defined (usually these are the keypoints near image border). The method makes sure that the ouptut keypoints and descriptors are consistent with each other (so that the number of keypoints is equal to the descriptors row count). ::
// matching descriptors
BruteForceMatcher<L2<float> > matcher;
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);
Now that we have descriptors for both images, we can match them. First, we create a matcher that for each descriptor from image 2 does exhaustive search for the nearest descriptor in image 1 using Euclidean metric. Manhattan distance is also implemented as well as a Hamming distance for Brief descriptor. The output vector ``matches`` contains pairs of corresponding points indices. ::
// drawing the results
namedWindow("matches", 1);
Mat img_matches;
drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
imshow("matches", img_matches);
waitKey(0);
The final part of the sample is about visualizing the matching results.

View File

@@ -0,0 +1,83 @@
*******
HighGUI
*******
.. highlight:: cpp
Using Kinect sensor
===================
Kinect sensor is supported through ``VideoCapture`` class. Depth map, RGB image and some other formats of Kinect output can be retrieved by using familiar interface of ``VideoCapture``.
In order to use Kinect with OpenCV you should do the following preliminary steps:
#.
Install OpenNI library and PrimeSensor Module for OpenNI from here \url{http://www.openni.org/downloadfiles}. The installation should be done to default folders listed in the instructions of these products:
.. code-block:: text
OpenNI:
Linux & MacOSX:
Libs into: /usr/lib
Includes into: /usr/include/ni
Windows:
Libs into: c:/Program Files/OpenNI/Lib
Includes into: c:/Program Files/OpenNI/Include
PrimeSensor Module:
Linux & MacOSX:
Bins into: /usr/bin
Windows:
Bins into: c:/Program Files/Prime Sense/Sensor/Bin
If one or both products were installed to the other folders, the user should change corresponding CMake variables ``OPENNI_LIB_DIR``, ``OPENNI_INCLUDE_DIR`` or/and ``OPENNI_PRIME_SENSOR_MODULE_BIN_DIR``.
#.
Configure OpenCV with OpenNI support by setting \texttt{WITH\_OPENNI} flag in CMake. If OpenNI is found in default install folders OpenCV will be built with OpenNI library regardless of whether PrimeSensor Module is found or not. If PrimeSensor Module was not found you will get a warning in CMake log. Without PrimeSensor module OpenCV will be successfully compiled with OpenNI library, but ``VideoCapture`` object will not grab data from Kinect sensor.
#.
Build OpenCV.
VideoCapture can retrieve the following Kinect data:
#.
data given from depth generator:
* ``OPENNI_DEPTH_MAP`` - depth values in mm (CV_16UC1)
* ``OPENNI_POINT_CLOUD_MAP`` - XYZ in meters (CV_32FC3)
* ``OPENNI_DISPARITY_MAP`` - disparity in pixels (CV_8UC1)
* ``OPENNI_DISPARITY_MAP_32F`` - disparity in pixels (CV_32FC1)
* ``OPENNI_VALID_DEPTH_MASK`` - mask of valid pixels (not ocluded, not shaded etc.) (CV_8UC1)
#.
data given from RGB image generator:
* ``OPENNI_BGR_IMAGE`` - color image (CV_8UC3)
* ``OPENNI_GRAY_IMAGE`` - gray image (CV_8UC1)
In order to get depth map from Kinect use ``VideoCapture::operator >>``, e. g. ::
VideoCapture capture(0); // or CV_CAP_OPENNI
for(;;)
{
Mat depthMap;
capture >> depthMap;
if( waitKey( 30 ) >= 0 )
break;
}
For getting several Kinect maps use ``VideoCapture::grab`` and ``VideoCapture::retrieve``, e.g. ::
VideoCapture capture(0); // or CV_CAP_OPENNI
for(;;)
{
Mat depthMap;
Mat rgbImage
capture.grab();
capture.retrieve( depthMap, OPENNI_DEPTH_MAP );
capture.retrieve( bgrImage, OPENNI_BGR_IMAGE );
if( waitKey( 30 ) >= 0 )
break;
}
For more information please refer to a Kinect example of usage ``kinect_maps.cpp`` in ``opencv/samples/cpp`` folder.

147
doc/user_guide/ug_mat.rst Normal file
View File

@@ -0,0 +1,147 @@
**********************
Operations with images
**********************
.. highlight:: cpp
Input/Output
============
Images
------
Load an image from a file: ::
Mat img = imread(filename)
If you read a jpg file, a 3 channel image is created by default. If you need a grayscale image, use: ::
Mat img = imread(filename, 0);
Save an image to a file: ::
Mat img = imwrite(filename);
XML/YAML
--------
TBD
Basic operations with images
============================
Accessing pixel intensity values
--------------------------------
In order to get pixel intensity value, you have to know the type of an image and the number of channels. Here is an example for a single channel grey scale image (type 8UC1) and pixel coordinates x and y: ::
Scalar intensity = img.at<uchar>(x, y);
``intensity.val[0]`` contains a value from 0 to 255. Now let us consider a 3 channel image with ``BGR`` color ordering (the default format returned by ``imread``): ::
Vec3b intensity = img.at<Vec3b>(x, y);
uchar blue = intensity.val[0];
uchar green = intensity.val[1];
uchar red = intensity.val[2];
You can use the same method for floating-point images (for example, you can get such an image by running Sobel on a 3 channel image): ::
Vec3f intensity = img.at<Vec3f>(x, y);
float blue = intensity.val[0];
float green = intensity.val[1];
float red = intensity.val[2];
The same method can be used to change pixel intensities: ::
img.at<uchar>(x, y) = 128;
There are functions in OpenCV, especially from calib3d module, such as ``projectPoints``, that take an array of 2D or 3D points in the form of ``Mat``. Matrix should contain exactly one column, each row corresponds to a point, matrix type should be 32FC2 or 32FC3 correspondingly. Such a matrix can be easily constructed from ``std::vector``: ::
vector<Point2f> points;
//... fill the array
Mat pointsMat = Mat(points);
One can access a point in this matrix using the same method \texttt{Mat::at}: ::
Point2f point = pointsMat.at<Point2f>(i, 0);
Memory management and reference counting
----------------------------------------
``Mat`` is a structure that keeps matrix/image characteristics (rows and columns number, data type etc) and a pointer to data. So nothing prevents us from having several instances of ``Mat`` corresponding to the same data. A ``Mat`` keeps a reference count that tells if data has to be deallocated when a particular instance of ``Mat`` is destroyed. Here is an example of creating two matrices without copying data: ::
std::vector<Point3f> points;
// .. fill the array
Mat pointsMat = Mat(points).reshape(1);
As a result we get a 32FC1 matrix with 3 columns instead of 32FC3 matrix with 1 column. ``pointsMat`` uses data from ``points`` and will not deallocate the memory when destroyed. In this particular instance, however, developer has to make sure that lifetime of ``points`` is longer than of ``pointsMat``.
If we need to copy the data, this is done using, for example, ``Mat::copyTo`` or ``Mat::clone``: ::
Mat img = imread("image.jpg");
Mat img1 = img.clone();
To the contrary with C API where an output image had to be created by developer, an empty output ``Mat`` can be supplied to each function. Each implementation calls ``Mat::create`` for a destination matrix. This method allocates data for a matrix if it is empty. If it is not empty and has the correct size and type, the method does nothing. If, however, size or type are different from input arguments, the data is deallocated (and lost) and a new data is allocated. For example: ::
Mat img = imread("image.jpg");
Mat sobelx;
Sobel(img, sobelx, CV_32F, 1, 0);
Primitive operations
--------------------
There is a number of convenient operators defined on a matrix. For example, here is how we can make a black image from an existing greyscale image ``img``: ::
img = Scalar(0);
Selecting a region of interest: ::
Rect r(10, 10, 100, 100);
Mat smallImg = img(r);
A convertion from \texttt{Mat} to C API data structures: ::
Mat img = imread("image.jpg");
IplImage img1 = img;
CvMat m = img;
Note that there is no data copying here.
Conversion from color to grey scale: ::
Mat img = imread("image.jpg"); // loading a 8UC3 image
Mat grey;
cvtColor(img, grey, CV_BGR2GRAY);
Change image type from 8UC1 to 32FC1: ::
src.convertTo(dst, CV_32F);
Visualizing images
------------------
It is very useful to see intermediate results of your algorithm during development process. OpenCV provides a convenient way of visualizing images. A 8U image can be shown using: ::
Mat img = imread("image.jpg");
namedWindow("image", CV_WINDOW_AUTOSIZE);
imshow("image", img);
waitKey();
A call to ``waitKey()`` starts a message passing cycle that waits for a key stroke in the ``"image"`` window. A ``32F`` image needs to be converted to ``8U`` type. For example: ::
Mat img = imread("image.jpg");
Mat grey;
cvtColor(img, grey, CV_BGR2GREY);
Mat sobelx;
Sobel(grey, sobelx, CV_32F, 1, 0);
double minVal, maxVal;
minMaxLoc(sobelx, &minVal, &maxVal); //find minimum and maximum intensities
Mat draw;
sobelx.convertTo(draw, CV_8U, 255.0/(maxVal - minVal), -minVal);
namedWindow("image", CV_WINDOW_AUTOSIZE);
imshow("image", draw);
waitKey();

View File

@@ -1,97 +0,0 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% C++ %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ifCpp
\section{Detectors}
\section{Descriptors}
\section{Matching keypoints}
\subsection{The code}
We will start with a short sample opencv/samples/cpp/matcher\_simple.cpp:
\begin{lstlisting}
Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
Mat img2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
if(img1.empty() || img2.empty())
{
printf("Can't read one of the images\n");
return -1;
}
// detecting keypoints
SurfFeatureDetector detector(400);
vector<KeyPoint> keypoints1, keypoints2;
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);
// computing descriptors
SurfDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);
// matching descriptors
BruteForceMatcher<L2<float> > matcher;
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);
// drawing the results
namedWindow("matches", 1);
Mat img_matches;
drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
imshow("matches", img_matches);
waitKey(0);
\end{lstlisting}
\subsection{The code explained}
Let us break the code down.
\begin{lstlisting}
Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
Mat img2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
if(img1.empty() || img2.empty())
{
printf("Can't read one of the images\n");
return -1;
}
\end{lstlisting}
We load two images and check if they are loaded correctly.
\begin{lstlisting}
// detecting keypoints
FastFeatureDetector detector(15);
vector<KeyPoint> keypoints1, keypoints2;
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);
\end{lstlisting}
First, we create an instance of a keypoint detector. All detectors inherit the abstract FeatureDetector interface, but the constructors are algorithm-dependent. The first argument to each detector usually controls the balance between the amount of keypoints and their stability. The range of values is different for different detectors \footnote{For instance, FAST threshold has the meaning of pixel intensity difference and usually varies in the region \([0,40]\). SURF threshold is applied to a Hessian of an image and usually takes on values larger than \(100\).} so use defaults in case of doubt.
\begin{lstlisting}
// computing descriptors
SurfDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);
\end{lstlisting}
We create an instance of descriptor extractor. The most of OpenCV descriptors inherit DescriptorExtractor abstract interface. Then we compute descriptors for each of the keypoints. The output \texttt{Mat} of the \texttt{DescriptorExtractor::compute} method contains a descriptor in a row \(i\) for each \(i\)-th keypoint. Note that the method can modify the keypoints vector by removing the keypoints such that a descriptor for them is not defined (usually these are the keypoints near image border). The method makes sure that the ouptut keypoints and descriptors are consistent with each other (so that the number of keypoints is equal to the descriptors row count).
\begin{lstlisting}
// matching descriptors
BruteForceMatcher<L2<float> > matcher;
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);
\end{lstlisting}
Now that we have descriptors for both images, we can match them. First, we create a matcher that for each descriptor from image 2 does exhaustive search for the nearest descriptor in image 1 using Eucledian metric. Manhattan distance is also implemented as well as a Hamming distance for Brief descriptor. The output vector \texttt{matches} contains pairs of corresponding points indices.
\begin{lstlisting}
// drawing the results
namedWindow("matches", 1);
Mat img_matches;
drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
imshow("matches", img_matches);
waitKey(0);
\end{lstlisting}
The final part of the sample is about visualizing the matching results.
\fi

View File

@@ -0,0 +1,10 @@
#################
OpenCV User Guide
#################
.. toctree::
:maxdepth: 2
ug_mat.rst
ug_features2d.rst
ug_highgui.rst

View File

@@ -1,89 +0,0 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% C++ %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ifCpp
\section{Using Kinect sensor.}
Kinect sensor is supported through \texttt{VideoCapture} class. Depth map, rgb image and some other formats of Kinect
output can be retrieved by using familiar interface of \texttt{VideoCapture}.\par
In order to use Kinect with OpenCV you should do the following preliminary steps:\newline
1) Install OpenNI library and PrimeSensor Module for OpenNI from here \url{http://www.openni.org/downloadfiles}.
The installation should be done to default folders listed in the instructions of these products:
\begin{lstlisting}
OpenNI:
Linux & MacOSX:
Libs into: /usr/lib
Includes into: /usr/include/ni
Windows:
Libs into: c:/Program Files/OpenNI/Lib
Includes into: c:/Program Files/OpenNI/Include
PrimeSensor Module:
Linux & MacOSX:
Bins into: /usr/bin
Windows:
Bins into: c:/Program Files/Prime Sense/Sensor/Bin
\end{lstlisting}
If one or both products were installed to the other folders, the user should change corresponding CMake variables
(\texttt{OPENNI\_LIB\_DIR}, \texttt{OPENNI\_INCLUDE\_DIR} or/and
\texttt{OPENNI\_PRIME\_SENSOR\_MODULE\_BIN\_DIR}).\newline
2) Configure OpenCV with OpenNI support by setting \texttt{WITH\_OPENNI} flag in CMake. If OpenNI
is found in default install folders OpenCV will be built with OpenNI library regardless of whether
PrimeSensor Module is found or not. If PrimeSensor Module was not found you will get a warning
in CMake log. Without PrimeSensor module OpenCV will be successfully compiled with OpenNI library,
but \texttt{VideoCapture} object will not grab data from Kinect sensor. \par
3) Build OpenCV.\par
VideoCapture can retrieve the following Kinect data:
\begin{lstlisting}
a.) data given from depth generator:
OPENNI_DEPTH_MAP - depth values in mm (CV_16UC1)
OPENNI_POINT_CLOUD_MAP - XYZ in meters (CV_32FC3)
OPENNI_DISPARITY_MAP - disparity in pixels (CV_8UC1)
OPENNI_DISPARITY_MAP_32F - disparity in pixels (CV_32FC1)
OPENNI_VALID_DEPTH_MASK - mask of valid pixels (not ocluded,
not shaded etc.) (CV_8UC1)
b.) data given from RGB image generator:
OPENNI_BGR_IMAGE - color image (CV_8UC3)
OPENNI_GRAY_IMAGE - gray image (CV_8UC1)
\end{lstlisting}
In order to get depth map from Kinect use \texttt{VideoCapture::operator >>}, e. g.
\begin{lstlisting}
VideoCapture capture(0); // or CV_CAP_OPENNI
for(;;)
{
Mat depthMap;
capture >> depthMap;
if( waitKey( 30 ) >= 0 )
break;
}
\end{lstlisting}
For getting several Kinect maps use \texttt{VideoCapture::grab + VideoCapture::retrieve}, e.g.
\begin{lstlisting}
VideoCapture capture(0); // or CV_CAP_OPENNI
for(;;)
{
Mat depthMap;
Mat rgbImage
capture.grab();
capture.retrieve( depthMap, OPENNI_DEPTH_MAP );
capture.retrieve( bgrImage, OPENNI_BGR_IMAGE );
if( waitKey( 30 ) >= 0 )
break;
}
\end{lstlisting}
For more information please refer to a kinect example of usage \texttt{kinect\_maps.cpp} in \texttt{sample} folder.
\fi

View File

@@ -1,141 +0,0 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% C++ %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ifCpp
\section{Input/Output}
\subsection{Images}
Load an image from a file:
\begin{lstlisting}
Mat img = imread(filename);
\end{lstlisting}
If you read a jpg file, a 3 channel image is created by default. If you need a grayscale image, use:
\begin{lstlisting}
Mat img = imread(filename, 0);
\end{lstlisting}
Save an image to a file:
\begin{lstlisting}
Mat img = imwrite(filename);
\end{lstlisting}
\subsection{XML/YAML}
\section{Basic operations with images}
\subsection{Accessing pixel intensity values}
In order to get pixel intensity value, you have to know the type of an image and the number of channels. Here is an example for a single channel grey scale image (type 8UC1) and pixel coordinates x and y:
\begin{lstlisting}
Scalar intensity = img.at<uchar>(x, y);
\end{lstlisting}
\texttt{intensity.val[0]} contains a value from 0 to 255.
Now let us consider a 3 channel image with \texttt{bgr} color ordering (the default format returned by imread):
\begin{lstlisting}
Vec3b intensity = img.at<Vec3b>(x, y);
uchar blue = intensity.val[0];
uchar green = intensity.val[1];
uchar red = intensity.val[2];
\end{lstlisting}
You can use the same method for floating-point images (for example, you can get such an image by running Sobel on a 3 channel image):
\begin{lstlisting}
Vec3f intensity = img.at<Vec3f>(x, y);
float blue = intensity.val[0];
float green = intensity.val[1];
float red = intensity.val[2];
\end{lstlisting}
The same method can be used to change pixel intensities:
\begin{lstlisting}
img.at<uchar>(x, y) = 128;
\end{lstlisting}
There are functions in OpenCV, especially from calib3d module, such as \texttt{projectPoints}, that take an array of 2D or 3D points in the form of \texttt{Mat}. Matrix should contain exactly one column, each row corresponds to a point, matrix type should be 32FC2 or 32FC3 correspondingly. Such a matrix can be easily constructed from std::vector:
\begin{lstlisting}
vector<Point2f> points;
//... fill the array
Mat pointsMat = Mat(points);
\end{lstlisting}
One can access a point in this matrix using the same method \texttt{Mat::at}:
\begin{lstlisting}
Point2f point = pointsMat.at<Point2f>(i, 0);
\end{lstlisting}
\subsection{Memory management and reference counting}
\texttt{Mat} is a structure that keeps matrix/image characteristics (rows and columns number, data type etc) and a pointer to data. So nothing prevents us from having several instances of \texttt{Mat} corresponding to the same data. A \texttt{Mat} keeps a reference count that tells if data has to be deallocated when a particular instance of \texttt{Mat} is destroyed. Here is an example of creating two matrices without copying data:
\begin{lstlisting}
std::vector<Point3f> points;
// .. fill the array
Mat pointsMat = Mat(points).reshape(1);
\end{lstlisting}
As a result we get a 32FC1 matrix with 3 columns instead of 32FC3 matrix with 1 column. \texttt{pointsMat} uses data from \texttt{points} and will not deallocate the memory when destroyed. In this particular instance, however, developer has to make sure that lifetime of \texttt{points} is longer than of \texttt{pointsMat}.
If we need to copy the data, this is done using, for example, \texttt{Mat::copyTo} or \texttt{Mat::clone}:
\begin{lstlisting}
Mat img = imread("image.jpg");
Mat img1 = img.clone();
\end{lstlisting}
To the contrary with C API where an output image had to be created by developer, an empty output \texttt{Mat} can be supplied to each function. Each implementation calls \texttt{Mat::create} for a destination matrix. This method allocates data for a matrix if it is empty. If it is not empty and has the correct size and type, the method does nothing. If, however, size or type are different from input arguments, the data is deallocated (and lost) and a new data is allocated. For example:
\begin{lstlisting}
Mat img = imread("image.jpg");
Mat sobelx;
Sobel(img, sobelx, CV_32F, 1, 0);
\end{lstlisting}
\subsection{Primitive operations}
There is a number of convenient operators defined on a matrix. For example, here is how we can make a black image from an existing greyscale image \texttt{img}:
\begin{lstlisting}
img = Scalar(0);
\end{lstlisting}
Selecting a region of interest:
\begin{lstlisting}
Rect r(10, 10, 100, 100);
Mat smallImg = img(r);
\end{lstlisting}
A convertion from \texttt{Mat} to C API data structures:
\begin{lstlisting}
Mat img = imread("image.jpg");
IplImage img1 = img;
CvMat m = img;
\end{lstlisting}
Note that there is no data copying here.
Conversion from color to grey scale:
\begin{lstlisting}
Mat img = imread("image.jpg"); // loading a 8UC3 image
Mat grey;
cvtColor(img, grey, CV_BGR2GRAY);
\end{lstlisting}
Change image type from 8UC1 to 32FC1:
\begin{lstlisting}
convertTo(src, dst, CV_32F);
\end{lstlisting}
\subsection{Visualizing images}
It is very useful to see indermediate results of your algorithm during development process. OpenCV provides a convenient way of visualizing images. A 8U image can be shown using:
\begin{lstlisting}
Mat img = imread("image.jpg");
namedWindow("image", CV_WINDOW_AUTOSIZE);
imshow("image", img);
waitKey();
\end{lstlisting}
A call to waitKey() starts a message passing cycle that waits for a key stroke in the \texttt{"image"} window. A 32F image needs to be converted to 8U type. For example:
\begin{lstlisting}
Mat img = imread("image.jpg");
Mat grey;
cvtColor(img, grey, CV_BGR2GREY);
Mat sobelx;
Sobel(grey, sobelx, CV_32F, 1, 0);
double minVal, maxVal;
minMaxLoc(sobelx, &minVal, &maxVal); //find minimum and maximum intensities
Mat draw;
sobelx.convertTo(draw, CV_8U, 255.0/(maxVal - minVal), -minVal);
namedWindow("image", CV_WINDOW_AUTOSIZE);
imshow("image", draw);
waitKey();
\end{lstlisting}
\fi