mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
@@ -53,48 +53,143 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp)
|
||||
|
||||
- The following code performs the operation \f$g(i,j) = \alpha \cdot f(i,j) + \beta\f$ :
|
||||
@include BasicLinearTransforms.cpp
|
||||
@include samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java)
|
||||
|
||||
- The following code performs the operation \f$g(i,j) = \alpha \cdot f(i,j) + \beta\f$ :
|
||||
@include samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py)
|
||||
|
||||
- The following code performs the operation \f$g(i,j) = \alpha \cdot f(i,j) + \beta\f$ :
|
||||
@include samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
-# We begin by creating parameters to save \f$\alpha\f$ and \f$\beta\f$ to be entered by the user:
|
||||
@snippet BasicLinearTransforms.cpp basic-linear-transform-parameters
|
||||
- We load an image using @ref cv::imread and save it in a Mat object:
|
||||
|
||||
-# We load an image using @ref cv::imread and save it in a Mat object:
|
||||
@snippet BasicLinearTransforms.cpp basic-linear-transform-load
|
||||
-# Now, since we will make some transformations to this image, we need a new Mat object to store
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp basic-linear-transform-load
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java basic-linear-transform-load
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py basic-linear-transform-load
|
||||
@end_toggle
|
||||
|
||||
- Now, since we will make some transformations to this image, we need a new Mat object to store
|
||||
it. Also, we want this to have the following features:
|
||||
|
||||
- Initial pixel values equal to zero
|
||||
- Same size and type as the original image
|
||||
@snippet BasicLinearTransforms.cpp basic-linear-transform-output
|
||||
We observe that @ref cv::Mat::zeros returns a Matlab-style zero initializer based on
|
||||
*image.size()* and *image.type()*
|
||||
|
||||
-# Now, to perform the operation \f$g(i,j) = \alpha \cdot f(i,j) + \beta\f$ we will access to each
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp basic-linear-transform-output
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java basic-linear-transform-output
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py basic-linear-transform-output
|
||||
@end_toggle
|
||||
|
||||
We observe that @ref cv::Mat::zeros returns a Matlab-style zero initializer based on
|
||||
*image.size()* and *image.type()*
|
||||
|
||||
- We ask now the values of \f$\alpha\f$ and \f$\beta\f$ to be entered by the user:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp basic-linear-transform-parameters
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java basic-linear-transform-parameters
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py basic-linear-transform-parameters
|
||||
@end_toggle
|
||||
|
||||
- Now, to perform the operation \f$g(i,j) = \alpha \cdot f(i,j) + \beta\f$ we will access to each
|
||||
pixel in image. Since we are operating with BGR images, we will have three values per pixel (B,
|
||||
G and R), so we will also access them separately. Here is the piece of code:
|
||||
@snippet BasicLinearTransforms.cpp basic-linear-transform-operation
|
||||
Notice the following:
|
||||
- To access each pixel in the images we are using this syntax: *image.at\<Vec3b\>(y,x)[c]*
|
||||
where *y* is the row, *x* is the column and *c* is R, G or B (0, 1 or 2).
|
||||
- Since the operation \f$\alpha \cdot p(i,j) + \beta\f$ can give values out of range or not
|
||||
integers (if \f$\alpha\f$ is float), we use cv::saturate_cast to make sure the
|
||||
values are valid.
|
||||
|
||||
-# Finally, we create windows and show the images, the usual way.
|
||||
@snippet BasicLinearTransforms.cpp basic-linear-transform-display
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp basic-linear-transform-operation
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java basic-linear-transform-operation
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py basic-linear-transform-operation
|
||||
@end_toggle
|
||||
|
||||
Notice the following (**C++ code only**):
|
||||
- To access each pixel in the images we are using this syntax: *image.at\<Vec3b\>(y,x)[c]*
|
||||
where *y* is the row, *x* is the column and *c* is R, G or B (0, 1 or 2).
|
||||
- Since the operation \f$\alpha \cdot p(i,j) + \beta\f$ can give values out of range or not
|
||||
integers (if \f$\alpha\f$ is float), we use cv::saturate_cast to make sure the
|
||||
values are valid.
|
||||
|
||||
- Finally, we create windows and show the images, the usual way.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp basic-linear-transform-display
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java basic-linear-transform-display
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py basic-linear-transform-display
|
||||
@end_toggle
|
||||
|
||||
@note
|
||||
Instead of using the **for** loops to access each pixel, we could have simply used this command:
|
||||
@code{.cpp}
|
||||
image.convertTo(new_image, -1, alpha, beta);
|
||||
@endcode
|
||||
where @ref cv::Mat::convertTo would effectively perform *new_image = a*image + beta\*. However, we
|
||||
wanted to show you how to access each pixel. In any case, both methods give the same result but
|
||||
convertTo is more optimized and works a lot faster.
|
||||
|
||||
@add_toggle_cpp
|
||||
@code{.cpp}
|
||||
image.convertTo(new_image, -1, alpha, beta);
|
||||
@endcode
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@code{.java}
|
||||
image.convertTo(newImage, -1, alpha, beta);
|
||||
@endcode
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@code{.py}
|
||||
new_image = cv.convertScaleAbs(image, alpha=alpha, beta=beta)
|
||||
@endcode
|
||||
@end_toggle
|
||||
|
||||
where @ref cv::Mat::convertTo would effectively perform *new_image = a*image + beta\*. However, we
|
||||
wanted to show you how to access each pixel. In any case, both methods give the same result but
|
||||
convertTo is more optimized and works a lot faster.
|
||||
|
||||
Result
|
||||
------
|
||||
@@ -185,10 +280,31 @@ and are not intended to be used as a replacement of a raster graphics editor!**
|
||||
|
||||
### Code
|
||||
|
||||
@add_toggle_cpp
|
||||
Code for the tutorial is [here](https://github.com/opencv/opencv/blob/master/samples/cpp/tutorial_code/ImgProc/changing_contrast_brightness_image/changing_contrast_brightness_image.cpp).
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
Code for the tutorial is [here](https://github.com/opencv/opencv/blob/master/samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/ChangingContrastBrightnessImageDemo.java).
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
Code for the tutorial is [here](https://github.com/opencv/opencv/blob/master/samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/changing_contrast_brightness_image.py).
|
||||
@end_toggle
|
||||
|
||||
Code for the gamma correction:
|
||||
|
||||
@snippet changing_contrast_brightness_image.cpp changing-contrast-brightness-gamma-correction
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/changing_contrast_brightness_image/changing_contrast_brightness_image.cpp changing-contrast-brightness-gamma-correction
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/ChangingContrastBrightnessImageDemo.java changing-contrast-brightness-gamma-correction
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/changing_contrast_brightness_image.py changing-contrast-brightness-gamma-correction
|
||||
@end_toggle
|
||||
|
||||
A look-up table is used to improve the performance of the computation as only 256 values needs to be calculated once.
|
||||
|
||||
|
||||
@@ -7,25 +7,50 @@ Input/Output
|
||||
### Images
|
||||
|
||||
Load an image from a file:
|
||||
@code{.cpp}
|
||||
Mat img = imread(filename)
|
||||
@endcode
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Load an image from a file
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Load an image from a file
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Load an image from a file
|
||||
@end_toggle
|
||||
|
||||
If you read a jpg file, a 3 channel image is created by default. If you need a grayscale image, use:
|
||||
|
||||
@code{.cpp}
|
||||
Mat img = imread(filename, IMREAD_GRAYSCALE);
|
||||
@endcode
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Load an image from a file in grayscale
|
||||
@end_toggle
|
||||
|
||||
@note format of the file is determined by its content (first few bytes) Save an image to a file:
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Load an image from a file in grayscale
|
||||
@end_toggle
|
||||
|
||||
@code{.cpp}
|
||||
imwrite(filename, img);
|
||||
@endcode
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Load an image from a file in grayscale
|
||||
@end_toggle
|
||||
|
||||
@note format of the file is determined by its extension.
|
||||
@note Format of the file is determined by its content (first few bytes). To save an image to a file:
|
||||
|
||||
@note use imdecode and imencode to read and write image from/to memory rather than a file.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Save image
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Save image
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Save image
|
||||
@end_toggle
|
||||
|
||||
@note Format of the file is determined by its extension.
|
||||
|
||||
@note Use cv::imdecode and cv::imencode to read and write an image from/to memory rather than a file.
|
||||
|
||||
Basic operations with images
|
||||
----------------------------
|
||||
@@ -35,49 +60,65 @@ Basic operations with images
|
||||
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:
|
||||
@code{.cpp}
|
||||
Scalar intensity = img.at<uchar>(y, x);
|
||||
@endcode
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Pixel access 1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Pixel access 1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Pixel access 1
|
||||
@end_toggle
|
||||
|
||||
C++ version only:
|
||||
intensity.val[0] contains a value from 0 to 255. Note the ordering of x and y. Since in OpenCV
|
||||
images are represented by the same structure as matrices, we use the same convention for both
|
||||
cases - the 0-based row index (or y-coordinate) goes first and the 0-based column index (or
|
||||
x-coordinate) follows it. Alternatively, you can use the following notation:
|
||||
@code{.cpp}
|
||||
Scalar intensity = img.at<uchar>(Point(x, y));
|
||||
@endcode
|
||||
x-coordinate) follows it. Alternatively, you can use the following notation (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Pixel access 2
|
||||
|
||||
Now let us consider a 3 channel image with BGR color ordering (the default format returned by
|
||||
imread):
|
||||
@code{.cpp}
|
||||
Vec3b intensity = img.at<Vec3b>(y, x);
|
||||
uchar blue = intensity.val[0];
|
||||
uchar green = intensity.val[1];
|
||||
uchar red = intensity.val[2];
|
||||
@endcode
|
||||
|
||||
**C++ code**
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Pixel access 3
|
||||
|
||||
**Python Python**
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Pixel access 3
|
||||
|
||||
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):
|
||||
@code{.cpp}
|
||||
Vec3f intensity = img.at<Vec3f>(y, x);
|
||||
float blue = intensity.val[0];
|
||||
float green = intensity.val[1];
|
||||
float red = intensity.val[2];
|
||||
@endcode
|
||||
running Sobel on a 3 channel image) (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Pixel access 4
|
||||
|
||||
The same method can be used to change pixel intensities:
|
||||
@code{.cpp}
|
||||
img.at<uchar>(y, x) = 128;
|
||||
@endcode
|
||||
There are functions in OpenCV, especially from calib3d module, such as projectPoints, that take an
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Pixel access 5
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Pixel access 5
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Pixel access 5
|
||||
@end_toggle
|
||||
|
||||
There are functions in OpenCV, especially from calib3d module, such as cv::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`:
|
||||
@code{.cpp}
|
||||
vector<Point2f> points;
|
||||
//... fill the array
|
||||
Mat pointsMat = Mat(points);
|
||||
@endcode
|
||||
One can access a point in this matrix using the same method Mat::at :
|
||||
@code{.cpp}
|
||||
Point2f point = pointsMat.at<Point2f>(i, 0);
|
||||
@endcode
|
||||
easily constructed from `std::vector` (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Mat from points vector
|
||||
|
||||
One can access a point in this matrix using the same method `Mat::at` (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Point access
|
||||
|
||||
### Memory management and reference counting
|
||||
|
||||
@@ -85,91 +126,141 @@ Mat is a structure that keeps matrix/image characteristics (rows and columns num
|
||||
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:
|
||||
@code{.cpp}
|
||||
std::vector<Point3f> points;
|
||||
// .. fill the array
|
||||
Mat pointsMat = Mat(points).reshape(1);
|
||||
@endcode
|
||||
As a result we get a 32FC1 matrix with 3 columns instead of 32FC3 matrix with 1 column. pointsMat
|
||||
data (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Reference counting 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.
|
||||
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, cv::Mat::copyTo or cv::Mat::clone:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg");
|
||||
Mat img1 = img.clone();
|
||||
@endcode
|
||||
To the contrary with C API where an output image had to be created by developer, an empty output Mat
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Reference counting 2
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Reference counting 2
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Reference counting 2
|
||||
@end_toggle
|
||||
|
||||
To the contrary with C API where an output image had to be created by the 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
|
||||
and type, the method does nothing. If however, size or type are different from the input arguments, the
|
||||
data is deallocated (and lost) and a new data is allocated. For example:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg");
|
||||
Mat sobelx;
|
||||
Sobel(img, sobelx, CV_32F, 1, 0);
|
||||
@endcode
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Reference counting 3
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Reference counting 3
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Reference counting 3
|
||||
@end_toggle
|
||||
|
||||
### 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\`:
|
||||
@code{.cpp}
|
||||
img = Scalar(0);
|
||||
@endcode
|
||||
a black image from an existing greyscale image `img`
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Set image to black
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Set image to black
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Set image to black
|
||||
@end_toggle
|
||||
|
||||
Selecting a region of interest:
|
||||
@code{.cpp}
|
||||
Rect r(10, 10, 100, 100);
|
||||
Mat smallImg = img(r);
|
||||
@endcode
|
||||
A conversion from Mat to C API data structures:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg");
|
||||
IplImage img1 = img;
|
||||
CvMat m = img;
|
||||
@endcode
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Select ROI
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Select ROI
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Select ROI
|
||||
@end_toggle
|
||||
|
||||
A conversion from Mat to C API data structures (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp C-API conversion
|
||||
|
||||
Note that there is no data copying here.
|
||||
|
||||
Conversion from color to grey scale:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg"); // loading a 8UC3 image
|
||||
Mat grey;
|
||||
cvtColor(img, grey, COLOR_BGR2GRAY);
|
||||
@endcode
|
||||
Conversion from color to greyscale:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp BGR to Gray
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java BGR to Gray
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py BGR to Gray
|
||||
@end_toggle
|
||||
|
||||
Change image type from 8UC1 to 32FC1:
|
||||
@code{.cpp}
|
||||
src.convertTo(dst, CV_32F);
|
||||
@endcode
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Convert to CV_32F
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Convert to CV_32F
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Convert to CV_32F
|
||||
@end_toggle
|
||||
|
||||
### 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:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg");
|
||||
|
||||
namedWindow("image", WINDOW_AUTOSIZE);
|
||||
imshow("image", img);
|
||||
waitKey();
|
||||
@endcode
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp imshow 1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java imshow 1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py imshow 1
|
||||
@end_toggle
|
||||
|
||||
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:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg");
|
||||
Mat grey;
|
||||
cvtColor(img, grey, COLOR_BGR2GRAY);
|
||||
|
||||
Mat sobelx;
|
||||
Sobel(grey, sobelx, CV_32F, 1, 0);
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp imshow 2
|
||||
@end_toggle
|
||||
|
||||
double minVal, maxVal;
|
||||
minMaxLoc(sobelx, &minVal, &maxVal); //find minimum and maximum intensities
|
||||
Mat draw;
|
||||
sobelx.convertTo(draw, CV_8U, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal));
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java imshow 2
|
||||
@end_toggle
|
||||
|
||||
namedWindow("image", WINDOW_AUTOSIZE);
|
||||
imshow("image", draw);
|
||||
waitKey();
|
||||
@endcode
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py imshow 2
|
||||
@end_toggle
|
||||
|
||||
@note Here cv::namedWindow is not necessary since it is immediately followed by cv::imshow.
|
||||
Nevertheless, it can be used to change the window properties or when using cv::createTrackbar
|
||||
|
||||
@@ -36,6 +36,10 @@ understanding how to manipulate the images on a pixel level.
|
||||
|
||||
- @subpage tutorial_mat_operations
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
Reading/writing images from file, accessing pixels, primitive operations, visualizing images.
|
||||
|
||||
- @subpage tutorial_adding_images
|
||||
@@ -50,6 +54,8 @@ understanding how to manipulate the images on a pixel level.
|
||||
|
||||
- @subpage tutorial_basic_linear_transform
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
|
||||
@@ -91,37 +91,112 @@ __Find the eigenvectors and eigenvalues of the covariance matrix__
|
||||
Source Code
|
||||
-----------
|
||||
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp).
|
||||
@include cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp
|
||||
@add_toggle_cpp
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py
|
||||
@end_toggle
|
||||
|
||||
@note Another example using PCA for dimensionality reduction while maintaining an amount of variance can be found at [opencv_source_code/samples/cpp/pca.cpp](https://github.com/opencv/opencv/tree/master/samples/cpp/pca.cpp)
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
-# __Read image and convert it to binary__
|
||||
- __Read image and convert it to binary__
|
||||
|
||||
Here we apply the necessary pre-processing procedures in order to be able to detect the objects of interest.
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp pre-process
|
||||
Here we apply the necessary pre-processing procedures in order to be able to detect the objects of interest.
|
||||
|
||||
-# __Extract objects of interest__
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp pre-process
|
||||
@end_toggle
|
||||
|
||||
Then find and filter contours by size and obtain the orientation of the remaining ones.
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp contours
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java pre-process
|
||||
@end_toggle
|
||||
|
||||
-# __Extract orientation__
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py pre-process
|
||||
@end_toggle
|
||||
|
||||
Orientation is extracted by the call of getOrientation() function, which performs all the PCA procedure.
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp pca
|
||||
- __Extract objects of interest__
|
||||
|
||||
First the data need to be arranged in a matrix with size n x 2, where n is the number of data points we have. Then we can perform that PCA analysis. The calculated mean (i.e. center of mass) is stored in the _cntr_ variable and the eigenvectors and eigenvalues are stored in the corresponding std::vector’s.
|
||||
Then find and filter contours by size and obtain the orientation of the remaining ones.
|
||||
|
||||
-# __Visualize result__
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp contours
|
||||
@end_toggle
|
||||
|
||||
The final result is visualized through the drawAxis() function, where the principal components are drawn in lines, and each eigenvector is multiplied by its eigenvalue and translated to the mean position.
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp visualization
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp visualization1
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java contours
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py contours
|
||||
@end_toggle
|
||||
|
||||
- __Extract orientation__
|
||||
|
||||
Orientation is extracted by the call of getOrientation() function, which performs all the PCA procedure.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp pca
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java pca
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py pca
|
||||
@end_toggle
|
||||
|
||||
First the data need to be arranged in a matrix with size n x 2, where n is the number of data points we have. Then we can perform that PCA analysis. The calculated mean (i.e. center of mass) is stored in the _cntr_ variable and the eigenvectors and eigenvalues are stored in the corresponding std::vector’s.
|
||||
|
||||
- __Visualize result__
|
||||
|
||||
The final result is visualized through the drawAxis() function, where the principal components are drawn in lines, and each eigenvector is multiplied by its eigenvalue and translated to the mean position.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp visualization
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java visualization
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py visualization
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp visualization1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java visualization1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py visualization1
|
||||
@end_toggle
|
||||
|
||||
Results
|
||||
-------
|
||||
|
||||
@@ -96,25 +96,67 @@ Source Code
|
||||
|
||||
@note The following code has been implemented with OpenCV 3.0 classes and functions. An equivalent version of the code using OpenCV 2.4 can be found in [this page.](http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html#introductiontosvms)
|
||||
|
||||
@include cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp
|
||||
@add_toggle_cpp
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
-# **Set up the training data**
|
||||
- **Set up the training data**
|
||||
|
||||
The training data of this exercise is formed by a set of labeled 2D-points that belong to one of
|
||||
two different classes; one of the classes consists of one point and the other of three points.
|
||||
The training data of this exercise is formed by a set of labeled 2D-points that belong to one of
|
||||
two different classes; one of the classes consists of one point and the other of three points.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp setup1
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp setup1
|
||||
@end_toggle
|
||||
|
||||
The function @ref cv::ml::SVM::train that will be used afterwards requires the training data to be
|
||||
stored as @ref cv::Mat objects of floats. Therefore, we create these objects from the arrays
|
||||
defined above:
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java setup1
|
||||
@end_toggle
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp setup2
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py setup1
|
||||
@end_toggle
|
||||
|
||||
-# **Set up SVM's parameters**
|
||||
The function @ref cv::ml::SVM::train that will be used afterwards requires the training data to be
|
||||
stored as @ref cv::Mat objects of floats. Therefore, we create these objects from the arrays
|
||||
defined above:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp setup2
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java setup2
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py setup1
|
||||
@end_toggle
|
||||
|
||||
- **Set up SVM's parameters**
|
||||
|
||||
In this tutorial we have introduced the theory of SVMs in the most simple case, when the
|
||||
training examples are spread into two classes that are linearly separable. However, SVMs can be
|
||||
@@ -123,35 +165,55 @@ Explanation
|
||||
we have to define some parameters before training the SVM. These parameters are stored in an
|
||||
object of the class @ref cv::ml::SVM.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp init
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp init
|
||||
@end_toggle
|
||||
|
||||
Here:
|
||||
- *Type of SVM*. We choose here the type @ref cv::ml::SVM::C_SVC "C_SVC" that can be used for
|
||||
n-class classification (n \f$\geq\f$ 2). The important feature of this type is that it deals
|
||||
with imperfect separation of classes (i.e. when the training data is non-linearly separable).
|
||||
This feature is not important here since the data is linearly separable and we chose this SVM
|
||||
type only for being the most commonly used.
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java init
|
||||
@end_toggle
|
||||
|
||||
- *Type of SVM kernel*. We have not talked about kernel functions since they are not
|
||||
interesting for the training data we are dealing with. Nevertheless, let's explain briefly now
|
||||
the main idea behind a kernel function. It is a mapping done to the training data to improve
|
||||
its resemblance to a linearly separable set of data. This mapping consists of increasing the
|
||||
dimensionality of the data and is done efficiently using a kernel function. We choose here the
|
||||
type @ref cv::ml::SVM::LINEAR "LINEAR" which means that no mapping is done. This parameter is
|
||||
defined using cv::ml::SVM::setKernel.
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py init
|
||||
@end_toggle
|
||||
|
||||
- *Termination criteria of the algorithm*. The SVM training procedure is implemented solving a
|
||||
constrained quadratic optimization problem in an **iterative** fashion. Here we specify a
|
||||
maximum number of iterations and a tolerance error so we allow the algorithm to finish in
|
||||
less number of steps even if the optimal hyperplane has not been computed yet. This
|
||||
parameter is defined in a structure @ref cv::TermCriteria .
|
||||
Here:
|
||||
- *Type of SVM*. We choose here the type @ref cv::ml::SVM::C_SVC "C_SVC" that can be used for
|
||||
n-class classification (n \f$\geq\f$ 2). The important feature of this type is that it deals
|
||||
with imperfect separation of classes (i.e. when the training data is non-linearly separable).
|
||||
This feature is not important here since the data is linearly separable and we chose this SVM
|
||||
type only for being the most commonly used.
|
||||
|
||||
-# **Train the SVM**
|
||||
- *Type of SVM kernel*. We have not talked about kernel functions since they are not
|
||||
interesting for the training data we are dealing with. Nevertheless, let's explain briefly now
|
||||
the main idea behind a kernel function. It is a mapping done to the training data to improve
|
||||
its resemblance to a linearly separable set of data. This mapping consists of increasing the
|
||||
dimensionality of the data and is done efficiently using a kernel function. We choose here the
|
||||
type @ref cv::ml::SVM::LINEAR "LINEAR" which means that no mapping is done. This parameter is
|
||||
defined using cv::ml::SVM::setKernel.
|
||||
|
||||
- *Termination criteria of the algorithm*. The SVM training procedure is implemented solving a
|
||||
constrained quadratic optimization problem in an **iterative** fashion. Here we specify a
|
||||
maximum number of iterations and a tolerance error so we allow the algorithm to finish in
|
||||
less number of steps even if the optimal hyperplane has not been computed yet. This
|
||||
parameter is defined in a structure @ref cv::TermCriteria .
|
||||
|
||||
- **Train the SVM**
|
||||
We call the method @ref cv::ml::SVM::train to build the SVM model.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp train
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp train
|
||||
@end_toggle
|
||||
|
||||
-# **Regions classified by the SVM**
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java train
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py train
|
||||
@end_toggle
|
||||
|
||||
- **Regions classified by the SVM**
|
||||
|
||||
The method @ref cv::ml::SVM::predict is used to classify an input sample using a trained SVM. In
|
||||
this example we have used this method in order to color the space depending on the prediction done
|
||||
@@ -159,16 +221,36 @@ Explanation
|
||||
Cartesian plane. Each of the points is colored depending on the class predicted by the SVM; in
|
||||
green if it is the class with label 1 and in blue if it is the class with label -1.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp show
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp show
|
||||
@end_toggle
|
||||
|
||||
-# **Support vectors**
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java show
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py show
|
||||
@end_toggle
|
||||
|
||||
- **Support vectors**
|
||||
|
||||
We use here a couple of methods to obtain information about the support vectors.
|
||||
The method @ref cv::ml::SVM::getSupportVectors obtain all of the support
|
||||
vectors. We have used this methods here to find the training examples that are
|
||||
support vectors and highlight them.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp show_vectors
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp show_vectors
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java show_vectors
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py show_vectors
|
||||
@end_toggle
|
||||
|
||||
Results
|
||||
-------
|
||||
|
||||
@@ -92,81 +92,175 @@ You may also find the source code in `samples/cpp/tutorial_code/ml/non_linear_sv
|
||||
@note The following code has been implemented with OpenCV 3.0 classes and functions. An equivalent version of the code
|
||||
using OpenCV 2.4 can be found in [this page.](http://docs.opencv.org/2.4/doc/tutorials/ml/non_linear_svms/non_linear_svms.html#nonlinearsvms)
|
||||
|
||||
@include cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp
|
||||
@add_toggle_cpp
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
-# __Set up the training data__
|
||||
- __Set up the training data__
|
||||
|
||||
The training data of this exercise is formed by a set of labeled 2D-points that belong to one of
|
||||
two different classes. To make the exercise more appealing, the training data is generated
|
||||
randomly using a uniform probability density functions (PDFs).
|
||||
The training data of this exercise is formed by a set of labeled 2D-points that belong to one of
|
||||
two different classes. To make the exercise more appealing, the training data is generated
|
||||
randomly using a uniform probability density functions (PDFs).
|
||||
|
||||
We have divided the generation of the training data into two main parts.
|
||||
We have divided the generation of the training data into two main parts.
|
||||
|
||||
In the first part we generate data for both classes that is linearly separable.
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp setup1
|
||||
In the first part we generate data for both classes that is linearly separable.
|
||||
|
||||
In the second part we create data for both classes that is non-linearly separable, data that
|
||||
overlaps.
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp setup2
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp setup1
|
||||
@end_toggle
|
||||
|
||||
-# __Set up SVM's parameters__
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java setup1
|
||||
@end_toggle
|
||||
|
||||
@note In the previous tutorial @ref tutorial_introduction_to_svm there is an explanation of the
|
||||
attributes of the class @ref cv::ml::SVM that we configure here before training the SVM.
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py setup1
|
||||
@end_toggle
|
||||
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp init
|
||||
In the second part we create data for both classes that is non-linearly separable, data that
|
||||
overlaps.
|
||||
|
||||
There are just two differences between the configuration we do here and the one that was done in
|
||||
the previous tutorial (@ref tutorial_introduction_to_svm) that we use as reference.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp setup2
|
||||
@end_toggle
|
||||
|
||||
- _C_. We chose here a small value of this parameter in order not to punish too much the
|
||||
misclassification errors in the optimization. The idea of doing this stems from the will of
|
||||
obtaining a solution close to the one intuitively expected. However, we recommend to get a
|
||||
better insight of the problem by making adjustments to this parameter.
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java setup2
|
||||
@end_toggle
|
||||
|
||||
@note In this case there are just very few points in the overlapping region between classes.
|
||||
By giving a smaller value to __FRAC_LINEAR_SEP__ the density of points can be incremented and the
|
||||
impact of the parameter _C_ explored deeply.
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py setup2
|
||||
@end_toggle
|
||||
|
||||
- _Termination Criteria of the algorithm_. The maximum number of iterations has to be
|
||||
increased considerably in order to solve correctly a problem with non-linearly separable
|
||||
training data. In particular, we have increased in five orders of magnitude this value.
|
||||
- __Set up SVM's parameters__
|
||||
|
||||
-# __Train the SVM__
|
||||
@note In the previous tutorial @ref tutorial_introduction_to_svm there is an explanation of the
|
||||
attributes of the class @ref cv::ml::SVM that we configure here before training the SVM.
|
||||
|
||||
We call the method @ref cv::ml::SVM::train to build the SVM model. Watch out that the training
|
||||
process may take a quite long time. Have patiance when your run the program.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp init
|
||||
@end_toggle
|
||||
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp train
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java init
|
||||
@end_toggle
|
||||
|
||||
-# __Show the Decision Regions__
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py init
|
||||
@end_toggle
|
||||
|
||||
The method @ref cv::ml::SVM::predict is used to classify an input sample using a trained SVM. In
|
||||
this example we have used this method in order to color the space depending on the prediction done
|
||||
by the SVM. In other words, an image is traversed interpreting its pixels as points of the
|
||||
Cartesian plane. Each of the points is colored depending on the class predicted by the SVM; in
|
||||
dark green if it is the class with label 1 and in dark blue if it is the class with label 2.
|
||||
There are just two differences between the configuration we do here and the one that was done in
|
||||
the previous tutorial (@ref tutorial_introduction_to_svm) that we use as reference.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show
|
||||
- _C_. We chose here a small value of this parameter in order not to punish too much the
|
||||
misclassification errors in the optimization. The idea of doing this stems from the will of
|
||||
obtaining a solution close to the one intuitively expected. However, we recommend to get a
|
||||
better insight of the problem by making adjustments to this parameter.
|
||||
|
||||
-# __Show the training data__
|
||||
@note In this case there are just very few points in the overlapping region between classes.
|
||||
By giving a smaller value to __FRAC_LINEAR_SEP__ the density of points can be incremented and the
|
||||
impact of the parameter _C_ explored deeply.
|
||||
|
||||
The method @ref cv::circle is used to show the samples that compose the training data. The samples
|
||||
of the class labeled with 1 are shown in light green and in light blue the samples of the class
|
||||
labeled with 2.
|
||||
- _Termination Criteria of the algorithm_. The maximum number of iterations has to be
|
||||
increased considerably in order to solve correctly a problem with non-linearly separable
|
||||
training data. In particular, we have increased in five orders of magnitude this value.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show_data
|
||||
- __Train the SVM__
|
||||
|
||||
-# __Support vectors__
|
||||
We call the method @ref cv::ml::SVM::train to build the SVM model. Watch out that the training
|
||||
process may take a quite long time. Have patiance when your run the program.
|
||||
|
||||
We use here a couple of methods to obtain information about the support vectors. The method
|
||||
@ref cv::ml::SVM::getSupportVectors obtain all support vectors. We have used this methods here
|
||||
to find the training examples that are support vectors and highlight them.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp train
|
||||
@end_toggle
|
||||
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show_vectors
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java train
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py train
|
||||
@end_toggle
|
||||
|
||||
- __Show the Decision Regions__
|
||||
|
||||
The method @ref cv::ml::SVM::predict is used to classify an input sample using a trained SVM. In
|
||||
this example we have used this method in order to color the space depending on the prediction done
|
||||
by the SVM. In other words, an image is traversed interpreting its pixels as points of the
|
||||
Cartesian plane. Each of the points is colored depending on the class predicted by the SVM; in
|
||||
dark green if it is the class with label 1 and in dark blue if it is the class with label 2.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java show
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py show
|
||||
@end_toggle
|
||||
|
||||
- __Show the training data__
|
||||
|
||||
The method @ref cv::circle is used to show the samples that compose the training data. The samples
|
||||
of the class labeled with 1 are shown in light green and in light blue the samples of the class
|
||||
labeled with 2.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show_data
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java show_data
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py show_data
|
||||
@end_toggle
|
||||
|
||||
- __Support vectors__
|
||||
|
||||
We use here a couple of methods to obtain information about the support vectors. The method
|
||||
@ref cv::ml::SVM::getSupportVectors obtain all support vectors. We have used this methods here
|
||||
to find the training examples that are support vectors and highlight them.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show_vectors
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java show_vectors
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py show_vectors
|
||||
@end_toggle
|
||||
|
||||
Results
|
||||
-------
|
||||
|
||||
@@ -6,6 +6,8 @@ of data.
|
||||
|
||||
- @subpage tutorial_introduction_to_svm
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Fernando Iglesias García
|
||||
@@ -14,6 +16,8 @@ of data.
|
||||
|
||||
- @subpage tutorial_non_linear_svms
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Fernando Iglesias García
|
||||
@@ -23,6 +27,8 @@ of data.
|
||||
|
||||
- @subpage tutorial_introduction_to_pca
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Theodore Tsesmelis
|
||||
|
||||
Reference in New Issue
Block a user