1Operations with images {#tutorial_mat_operations}
2======================
3
4Input/Output
5------------
6
7### Images
8
9Load an image from a file:
10@code{.cpp}
11    Mat img = imread(filename)
12@endcode
13
14If you read a jpg file, a 3 channel image is created by default. If you need a grayscale image, use:
15
16@code{.cpp}
17    Mat img = imread(filename, 0);
18@endcode
19
20@note format of the file is determined by its content (first few bytes) Save an image to a file:
21
22@code{.cpp}
23    imwrite(filename, img);
24@endcode
25
26@note format of the file is determined by its extension.
27
28@note use imdecode and imencode to read and write image from/to memory rather than a file.
29
30Basic operations with images
31----------------------------
32
33### Accessing pixel intensity values
34
35In order to get pixel intensity value, you have to know the type of an image and the number of
36channels. Here is an example for a single channel grey scale image (type 8UC1) and pixel coordinates
37x and y:
38@code{.cpp}
39    Scalar intensity = img.at<uchar>(y, x);
40@endcode
41intensity.val[0] contains a value from 0 to 255. Note the ordering of x and y. Since in OpenCV
42images are represented by the same structure as matrices, we use the same convention for both
43cases - the 0-based row index (or y-coordinate) goes first and the 0-based column index (or
44x-coordinate) follows it. Alternatively, you can use the following notation:
45@code{.cpp}
46    Scalar intensity = img.at<uchar>(Point(x, y));
47@endcode
48Now let us consider a 3 channel image with BGR color ordering (the default format returned by
49imread):
50@code{.cpp}
51    Vec3b intensity = img.at<Vec3b>(y, x);
52    uchar blue = intensity.val[0];
53    uchar green = intensity.val[1];
54    uchar red = intensity.val[2];
55@endcode
56You can use the same method for floating-point images (for example, you can get such an image by
57running Sobel on a 3 channel image):
58@code{.cpp}
59    Vec3f intensity = img.at<Vec3f>(y, x);
60    float blue = intensity.val[0];
61    float green = intensity.val[1];
62    float red = intensity.val[2];
63@endcode
64The same method can be used to change pixel intensities:
65@code{.cpp}
66    img.at<uchar>(y, x) = 128;
67@endcode
68There are functions in OpenCV, especially from calib3d module, such as projectPoints, that take an
69array of 2D or 3D points in the form of Mat. Matrix should contain exactly one column, each row
70corresponds to a point, matrix type should be 32FC2 or 32FC3 correspondingly. Such a matrix can be
71easily constructed from `std::vector`:
72@code{.cpp}
73    vector<Point2f> points;
74    //... fill the array
75    Mat pointsMat = Mat(points);
76@endcode
77One can access a point in this matrix using the same method Mat::at :
78@code{.cpp}
79Point2f point = pointsMat.at<Point2f>(i, 0);
80@endcode
81
82### Memory management and reference counting
83
84Mat is a structure that keeps matrix/image characteristics (rows and columns number, data type etc)
85and a pointer to data. So nothing prevents us from having several instances of Mat corresponding to
86the same data. A Mat keeps a reference count that tells if data has to be deallocated when a
87particular instance of Mat is destroyed. Here is an example of creating two matrices without copying
88data:
89@code{.cpp}
90    std::vector<Point3f> points;
91    // .. fill the array
92    Mat pointsMat = Mat(points).reshape(1);
93@endcode
94As a result we get a 32FC1 matrix with 3 columns instead of 32FC3 matrix with 1 column. pointsMat
95uses data from points and will not deallocate the memory when destroyed. In this particular
96instance, however, developer has to make sure that lifetime of points is longer than of pointsMat.
97If we need to copy the data, this is done using, for example, cv::Mat::copyTo or cv::Mat::clone:
98@code{.cpp}
99    Mat img = imread("image.jpg");
100    Mat img1 = img.clone();
101@endcode
102To the contrary with C API where an output image had to be created by developer, an empty output Mat
103can be supplied to each function. Each implementation calls Mat::create for a destination matrix.
104This method allocates data for a matrix if it is empty. If it is not empty and has the correct size
105and type, the method does nothing. If, however, size or type are different from input arguments, the
106data is deallocated (and lost) and a new data is allocated. For example:
107@code{.cpp}
108    Mat img = imread("image.jpg");
109    Mat sobelx;
110    Sobel(img, sobelx, CV_32F, 1, 0);
111@endcode
112
113### Primitive operations
114
115There is a number of convenient operators defined on a matrix. For example, here is how we can make
116a black image from an existing greyscale image \`img\`:
117@code{.cpp}
118    img = Scalar(0);
119@endcode
120Selecting a region of interest:
121@code{.cpp}
122    Rect r(10, 10, 100, 100);
123    Mat smallImg = img(r);
124@endcode
125A convertion from Mat to C API data structures:
126@code{.cpp}
127    Mat img = imread("image.jpg");
128    IplImage img1 = img;
129    CvMat m = img;
130@endcode
131
132Note that there is no data copying here.
133
134Conversion from color to grey scale:
135@code{.cpp}
136    Mat img = imread("image.jpg"); // loading a 8UC3 image
137    Mat grey;
138    cvtColor(img, grey, COLOR_BGR2GRAY);
139@endcode
140Change image type from 8UC1 to 32FC1:
141@code{.cpp}
142    src.convertTo(dst, CV_32F);
143@endcode
144
145### Visualizing images
146
147It is very useful to see intermediate results of your algorithm during development process. OpenCV
148provides a convenient way of visualizing images. A 8U image can be shown using:
149@code{.cpp}
150    Mat img = imread("image.jpg");
151
152    namedWindow("image", WINDOW_AUTOSIZE);
153    imshow("image", img);
154    waitKey();
155@endcode
156
157A call to waitKey() starts a message passing cycle that waits for a key stroke in the "image"
158window. A 32F image needs to be converted to 8U type. For example:
159@code{.cpp}
160    Mat img = imread("image.jpg");
161    Mat grey;
162    cvtColor(img, grey, COLOR_BGR2GRAY);
163
164    Mat sobelx;
165    Sobel(grey, sobelx, CV_32F, 1, 0);
166
167    double minVal, maxVal;
168    minMaxLoc(sobelx, &minVal, &maxVal); //find minimum and maximum intensities
169    Mat draw;
170    sobelx.convertTo(draw, CV_8U, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal));
171
172    namedWindow("image", WINDOW_AUTOSIZE);
173    imshow("image", draw);
174    waitKey();
175@endcode
176