Home | History | Annotate | Download | only in core
      1 Operations with images {#tutorial_mat_operations}
      2 ======================
      3 
      4 Input/Output
      5 ------------
      6 
      7 ### Images
      8 
      9 Load an image from a file:
     10 @code{.cpp}
     11     Mat img = imread(filename)
     12 @endcode
     13 
     14 If 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 
     30 Basic operations with images
     31 ----------------------------
     32 
     33 ### Accessing pixel intensity values
     34 
     35 In order to get pixel intensity value, you have to know the type of an image and the number of
     36 channels. Here is an example for a single channel grey scale image (type 8UC1) and pixel coordinates
     37 x and y:
     38 @code{.cpp}
     39     Scalar intensity = img.at<uchar>(y, x);
     40 @endcode
     41 intensity.val[0] contains a value from 0 to 255. Note the ordering of x and y. Since in OpenCV
     42 images are represented by the same structure as matrices, we use the same convention for both
     43 cases - the 0-based row index (or y-coordinate) goes first and the 0-based column index (or
     44 x-coordinate) follows it. Alternatively, you can use the following notation:
     45 @code{.cpp}
     46     Scalar intensity = img.at<uchar>(Point(x, y));
     47 @endcode
     48 Now let us consider a 3 channel image with BGR color ordering (the default format returned by
     49 imread):
     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
     56 You can use the same method for floating-point images (for example, you can get such an image by
     57 running 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
     64 The same method can be used to change pixel intensities:
     65 @code{.cpp}
     66     img.at<uchar>(y, x) = 128;
     67 @endcode
     68 There are functions in OpenCV, especially from calib3d module, such as projectPoints, that take an
     69 array of 2D or 3D points in the form of Mat. Matrix should contain exactly one column, each row
     70 corresponds to a point, matrix type should be 32FC2 or 32FC3 correspondingly. Such a matrix can be
     71 easily constructed from `std::vector`:
     72 @code{.cpp}
     73     vector<Point2f> points;
     74     //... fill the array
     75     Mat pointsMat = Mat(points);
     76 @endcode
     77 One can access a point in this matrix using the same method Mat::at :
     78 @code{.cpp}
     79 Point2f point = pointsMat.at<Point2f>(i, 0);
     80 @endcode
     81 
     82 ### Memory management and reference counting
     83 
     84 Mat is a structure that keeps matrix/image characteristics (rows and columns number, data type etc)
     85 and a pointer to data. So nothing prevents us from having several instances of Mat corresponding to
     86 the same data. A Mat keeps a reference count that tells if data has to be deallocated when a
     87 particular instance of Mat is destroyed. Here is an example of creating two matrices without copying
     88 data:
     89 @code{.cpp}
     90     std::vector<Point3f> points;
     91     // .. fill the array
     92     Mat pointsMat = Mat(points).reshape(1);
     93 @endcode
     94 As a result we get a 32FC1 matrix with 3 columns instead of 32FC3 matrix with 1 column. pointsMat
     95 uses data from points and will not deallocate the memory when destroyed. In this particular
     96 instance, however, developer has to make sure that lifetime of points is longer than of pointsMat.
     97 If 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
    102 To the contrary with C API where an output image had to be created by developer, an empty output Mat
    103 can be supplied to each function. Each implementation calls Mat::create for a destination matrix.
    104 This method allocates data for a matrix if it is empty. If it is not empty and has the correct size
    105 and type, the method does nothing. If, however, size or type are different from input arguments, the
    106 data 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 
    115 There is a number of convenient operators defined on a matrix. For example, here is how we can make
    116 a black image from an existing greyscale image \`img\`:
    117 @code{.cpp}
    118     img = Scalar(0);
    119 @endcode
    120 Selecting a region of interest:
    121 @code{.cpp}
    122     Rect r(10, 10, 100, 100);
    123     Mat smallImg = img(r);
    124 @endcode
    125 A 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 
    132 Note that there is no data copying here.
    133 
    134 Conversion 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
    140 Change image type from 8UC1 to 32FC1:
    141 @code{.cpp}
    142     src.convertTo(dst, CV_32F);
    143 @endcode
    144 
    145 ### Visualizing images
    146 
    147 It is very useful to see intermediate results of your algorithm during development process. OpenCV
    148 provides 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 
    157 A call to waitKey() starts a message passing cycle that waits for a key stroke in the "image"
    158 window. 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