1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

Update documentation and samples

This commit is contained in:
Suleyman TURKMEN
2018-08-02 21:22:58 +03:00
parent 1c73e66edf
commit c61bc3a0cb
63 changed files with 365 additions and 303 deletions
@@ -1,264 +0,0 @@
Basic Drawing {#tutorial_basic_geometric_drawing}
=============
@prev_tutorial{tutorial_basic_linear_transform}
@next_tutorial{tutorial_random_generator_and_text}
Goals
-----
In this tutorial you will learn how to:
- Draw a **line** by using the OpenCV function **line()**
- Draw an **ellipse** by using the OpenCV function **ellipse()**
- Draw a **rectangle** by using the OpenCV function **rectangle()**
- Draw a **circle** by using the OpenCV function **circle()**
- Draw a **filled polygon** by using the OpenCV function **fillPoly()**
@add_toggle_cpp
OpenCV Theory
-------------
For this tutorial, we will heavily use two structures: @ref cv::Point and @ref cv::Scalar :
### Point
It represents a 2D point, specified by its image coordinates \f$x\f$ and \f$y\f$. We can define it as:
@code{.cpp}
Point pt;
pt.x = 10;
pt.y = 8;
@endcode
or
@code{.cpp}
Point pt = Point(10, 8);
@endcode
### Scalar
- Represents a 4-element vector. The type Scalar is widely used in OpenCV for passing pixel
values.
- In this tutorial, we will use it extensively to represent BGR color values (3 parameters). It is
not necessary to define the last argument if it is not going to be used.
- Let's see an example, if we are asked for a color argument and we give:
@code{.cpp}
Scalar( a, b, c )
@endcode
We would be defining a BGR color such as: *Blue = a*, *Green = b* and *Red = c*
@end_toggle
@add_toggle_java
OpenCV Theory
-------------
For this tutorial, we will heavily use two structures: @ref cv::Point and @ref cv::Scalar :
### Point
It represents a 2D point, specified by its image coordinates \f$x\f$ and \f$y\f$. We can define it as:
@code{.java}
Point pt = new Point();
pt.x = 10;
pt.y = 8;
@endcode
or
@code{.java}
Point pt = new Point(10, 8);
@endcode
### Scalar
- Represents a 4-element vector. The type Scalar is widely used in OpenCV for passing pixel
values.
- In this tutorial, we will use it extensively to represent BGR color values (3 parameters). It is
not necessary to define the last argument if it is not going to be used.
- Let's see an example, if we are asked for a color argument and we give:
@code{.java}
Scalar( a, b, c )
@endcode
We would be defining a BGR color such as: *Blue = a*, *Green = b* and *Red = c*
@end_toggle
Code
----
@add_toggle_cpp
- This code is in your OpenCV sample folder. Otherwise you can grab it from
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp)
@include samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp
@end_toggle
@add_toggle_java
- This code is in your OpenCV sample folder. Otherwise you can grab it from
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java)
@include samples/java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java
@end_toggle
@add_toggle_python
- This code is in your OpenCV sample folder. Otherwise you can grab it from
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py)
@include samples/python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py
@end_toggle
Explanation
-----------
Since we plan to draw two examples (an atom and a rook), we have to create two images and two
windows to display them.
@add_toggle_cpp
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp create_images
@end_toggle
@add_toggle_java
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java create_images
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py create_images
@end_toggle
We created functions to draw different geometric shapes. For instance, to draw the atom we used
**MyEllipse** and **MyFilledCircle**:
@add_toggle_cpp
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_atom
@end_toggle
@add_toggle_java
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java draw_atom
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py draw_atom
@end_toggle
And to draw the rook we employed **MyLine**, **rectangle** and a **MyPolygon**:
@add_toggle_cpp
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_rook
@end_toggle
@add_toggle_java
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java draw_rook
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py draw_rook
@end_toggle
Let's check what is inside each of these functions:
@add_toggle_cpp
@end_toggle
<H4>MyLine</H4>
@add_toggle_cpp
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_line
@end_toggle
@add_toggle_java
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_line
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_line
@end_toggle
- As we can see, **MyLine** just call the function **line()** , which does the following:
- Draw a line from Point **start** to Point **end**
- The line is displayed in the image **img**
- The line color is defined by <B>( 0, 0, 0 )</B> which is the RGB value correspondent
to **Black**
- The line thickness is set to **thickness** (in this case 2)
- The line is a 8-connected one (**lineType** = 8)
<H4>MyEllipse</H4>
@add_toggle_cpp
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_ellipse
@end_toggle
@add_toggle_java
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_ellipse
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_ellipse
@end_toggle
- From the code above, we can observe that the function **ellipse()** draws an ellipse such
that:
- The ellipse is displayed in the image **img**
- The ellipse center is located in the point <B>(w/2, w/2)</B> and is enclosed in a box
of size <B>(w/4, w/16)</B>
- The ellipse is rotated **angle** degrees
- The ellipse extends an arc between **0** and **360** degrees
- The color of the figure will be <B>( 255, 0, 0 )</B> which means blue in BGR value.
- The ellipse's **thickness** is 2.
<H4>MyFilledCircle</H4>
@add_toggle_cpp
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_filled_circle
@end_toggle
@add_toggle_java
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_filled_circle
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_filled_circle
@end_toggle
- Similar to the ellipse function, we can observe that *circle* receives as arguments:
- The image where the circle will be displayed (**img**)
- The center of the circle denoted as the point **center**
- The radius of the circle: **w/32**
- The color of the circle: <B>( 0, 0, 255 )</B> which means *Red* in BGR
- Since **thickness** = -1, the circle will be drawn filled.
<H4>MyPolygon</H4>
@add_toggle_cpp
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_polygon
@end_toggle
@add_toggle_java
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_polygon
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_polygon
@end_toggle
- To draw a filled polygon we use the function **fillPoly()** . We note that:
- The polygon will be drawn on **img**
- The vertices of the polygon are the set of points in **ppt**
- The color of the polygon is defined by <B>( 255, 255, 255 )</B>, which is the BGR
value for *white*
<H4>rectangle</H4>
@add_toggle_cpp
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp rectangle
@end_toggle
@add_toggle_java
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java rectangle
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py rectangle
@end_toggle
- Finally we have the @ref cv::rectangle function (we did not create a special function for
this guy). We note that:
- The rectangle will be drawn on **rook_image**
- Two opposite vertices of the rectangle are defined by <B>( 0, 7*w/8 )</B>
and <B>( w, w )</B>
- The color of the rectangle is given by <B>( 0, 255, 255 )</B> which is the BGR value
for *yellow*
- Since the thickness value is given by **FILLED (-1)**, the rectangle will be filled.
Result
------
Compiling and running your program should give you a result like this:
![](images/Drawing_1_Tutorial_Result_0.png)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

@@ -1,6 +1,9 @@
Changing the contrast and brightness of an image! {#tutorial_basic_linear_transform}
=================================================
@prev_tutorial{tutorial_adding_images}
@next_tutorial{tutorial_discrete_fourier_transform}
Goal
----
@@ -1,7 +1,7 @@
Discrete Fourier Transform {#tutorial_discrete_fourier_transform}
==========================
@prev_tutorial{tutorial_random_generator_and_text}
@prev_tutorial{tutorial_basic_linear_transform}
@next_tutorial{tutorial_file_input_output_with_xml_yml}
Goal
@@ -1,6 +1,9 @@
File Input and Output using XML and YAML files {#tutorial_file_input_output_with_xml_yml}
==============================================
@prev_tutorial{tutorial_discrete_fourier_transform}
@next_tutorial{tutorial_interoperability_with_OpenCV_1}
Goal
----
@@ -1,6 +1,9 @@
How to scan images, lookup tables and time measurement with OpenCV {#tutorial_how_to_scan_images}
==================================================================
@prev_tutorial{tutorial_mat_the_basic_image_container}
@next_tutorial{tutorial_mat_mask_operations}
Goal
----
@@ -1,6 +1,8 @@
How to use the OpenCV parallel_for_ to parallelize your code {#tutorial_how_to_use_OpenCV_parallel_for_}
==================================================================
@prev_tutorial{tutorial_how_to_use_ippa_conversion}
Goal
----
@@ -1,6 +1,9 @@
Intel® IPP Asynchronous C/C++ library in OpenCV {#tutorial_how_to_use_ippa_conversion}
===============================================
@prev_tutorial{tutorial_interoperability_with_OpenCV_1}
@next_tutorial{tutorial_how_to_use_OpenCV_parallel_for_}
Goal
----
@@ -1,6 +1,9 @@
Interoperability with OpenCV 1 {#tutorial_interoperability_with_OpenCV_1}
==============================
@prev_tutorial{tutorial_file_input_output_with_xml_yml}
@next_tutorial{tutorial_how_to_use_ippa_conversion}
Goal
----
@@ -1,6 +1,9 @@
Operations with images {#tutorial_mat_operations}
======================
@prev_tutorial{tutorial_mat_mask_operations}
@next_tutorial{tutorial_adding_images}
Input/Output
------------
@@ -1,6 +1,8 @@
Mat - The Basic Image Container {#tutorial_mat_the_basic_image_container}
===============================
@next_tutorial{tutorial_how_to_scan_images}
Goal
----
Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

@@ -1,249 +0,0 @@
Random generator and text with OpenCV {#tutorial_random_generator_and_text}
=====================================
Goals
-----
In this tutorial you will learn how to:
- Use the *Random Number generator class* (@ref cv::RNG ) and how to get a random number from a
uniform distribution.
- Display text on an OpenCV window by using the function @ref cv::putText
Code
----
- In the previous tutorial (@ref tutorial_basic_geometric_drawing) we drew diverse geometric figures, giving as input
parameters such as coordinates (in the form of @ref cv::Point), color, thickness, etc. You
might have noticed that we gave specific values for these arguments.
- In this tutorial, we intend to use *random* values for the drawing parameters. Also, we intend
to populate our image with a big number of geometric figures. Since we will be initializing them
in a random fashion, this process will be automatic and made by using *loops* .
- This code is in your OpenCV sample folder. Otherwise you can grab it from
[here](http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/core/Matrix/Drawing_2.cpp)
Explanation
-----------
-# Let's start by checking out the *main* function. We observe that first thing we do is creating a
*Random Number Generator* object (RNG):
@code{.cpp}
RNG rng( 0xFFFFFFFF );
@endcode
RNG implements a random number generator. In this example, *rng* is a RNG element initialized
with the value *0xFFFFFFFF*
-# Then we create a matrix initialized to *zeros* (which means that it will appear as black),
specifying its height, width and its type:
@code{.cpp}
/// Initialize a matrix filled with zeros
Mat image = Mat::zeros( window_height, window_width, CV_8UC3 );
/// Show it in a window during DELAY ms
imshow( window_name, image );
@endcode
-# Then we proceed to draw crazy stuff. After taking a look at the code, you can see that it is
mainly divided in 8 sections, defined as functions:
@code{.cpp}
/// Now, let's draw some lines
c = Drawing_Random_Lines(image, window_name, rng);
if( c != 0 ) return 0;
/// Go on drawing, this time nice rectangles
c = Drawing_Random_Rectangles(image, window_name, rng);
if( c != 0 ) return 0;
/// Draw some ellipses
c = Drawing_Random_Ellipses( image, window_name, rng );
if( c != 0 ) return 0;
/// Now some polylines
c = Drawing_Random_Polylines( image, window_name, rng );
if( c != 0 ) return 0;
/// Draw filled polygons
c = Drawing_Random_Filled_Polygons( image, window_name, rng );
if( c != 0 ) return 0;
/// Draw circles
c = Drawing_Random_Circles( image, window_name, rng );
if( c != 0 ) return 0;
/// Display text in random positions
c = Displaying_Random_Text( image, window_name, rng );
if( c != 0 ) return 0;
/// Displaying the big end!
c = Displaying_Big_End( image, window_name, rng );
@endcode
All of these functions follow the same pattern, so we will analyze only a couple of them, since
the same explanation applies for all.
-# Checking out the function **Drawing_Random_Lines**:
@code{.cpp}
int Drawing_Random_Lines( Mat image, char* window_name, RNG rng )
{
int lineType = 8;
Point pt1, pt2;
for( int i = 0; i < NUMBER; i++ )
{
pt1.x = rng.uniform( x_1, x_2 );
pt1.y = rng.uniform( y_1, y_2 );
pt2.x = rng.uniform( x_1, x_2 );
pt2.y = rng.uniform( y_1, y_2 );
line( image, pt1, pt2, randomColor(rng), rng.uniform(1, 10), 8 );
imshow( window_name, image );
if( waitKey( DELAY ) >= 0 )
{ return -1; }
}
return 0;
}
@endcode
We can observe the following:
- The *for* loop will repeat **NUMBER** times. Since the function @ref cv::line is inside this
loop, that means that **NUMBER** lines will be generated.
- The line extremes are given by *pt1* and *pt2*. For *pt1* we can see that:
@code{.cpp}
pt1.x = rng.uniform( x_1, x_2 );
pt1.y = rng.uniform( y_1, y_2 );
@endcode
- We know that **rng** is a *Random number generator* object. In the code above we are
calling **rng.uniform(a,b)**. This generates a randomly uniformed distribution between
the values **a** and **b** (inclusive in **a**, exclusive in **b**).
- From the explanation above, we deduce that the extremes *pt1* and *pt2* will be random
values, so the lines positions will be quite impredictable, giving a nice visual effect
(check out the Result section below).
- As another observation, we notice that in the @ref cv::line arguments, for the *color*
input we enter:
@code{.cpp}
randomColor(rng)
@endcode
Let's check the function implementation:
@code{.cpp}
static Scalar randomColor( RNG& rng )
{
int icolor = (unsigned) rng;
return Scalar( icolor&255, (icolor>>8)&255, (icolor>>16)&255 );
}
@endcode
As we can see, the return value is an *Scalar* with 3 randomly initialized values, which
are used as the *R*, *G* and *B* parameters for the line color. Hence, the color of the
lines will be random too!
-# The explanation above applies for the other functions generating circles, ellipses, polygons,
etc. The parameters such as *center* and *vertices* are also generated randomly.
-# Before finishing, we also should take a look at the functions *Display_Random_Text* and
*Displaying_Big_End*, since they both have a few interesting features:
-# **Display_Random_Text:**
@code{.cpp}
int Displaying_Random_Text( Mat image, char* window_name, RNG rng )
{
int lineType = 8;
for ( int i = 1; i < NUMBER; i++ )
{
Point org;
org.x = rng.uniform(x_1, x_2);
org.y = rng.uniform(y_1, y_2);
putText( image, "Testing text rendering", org, rng.uniform(0,8),
rng.uniform(0,100)*0.05+0.1, randomColor(rng), rng.uniform(1, 10), lineType);
imshow( window_name, image );
if( waitKey(DELAY) >= 0 )
{ return -1; }
}
return 0;
}
@endcode
Everything looks familiar but the expression:
@code{.cpp}
putText( image, "Testing text rendering", org, rng.uniform(0,8),
rng.uniform(0,100)*0.05+0.1, randomColor(rng), rng.uniform(1, 10), lineType);
@endcode
So, what does the function @ref cv::putText do? In our example:
- Draws the text **"Testing text rendering"** in **image**
- The bottom-left corner of the text will be located in the Point **org**
- The font type is a random integer value in the range: \f$[0, 8>\f$.
- The scale of the font is denoted by the expression **rng.uniform(0, 100)x0.05 + 0.1**
(meaning its range is: \f$[0.1, 5.1>\f$)
- The text color is random (denoted by **randomColor(rng)**)
- The text thickness ranges between 1 and 10, as specified by **rng.uniform(1,10)**
As a result, we will get (analagously to the other drawing functions) **NUMBER** texts over our
image, in random locations.
-# **Displaying_Big_End**
@code{.cpp}
int Displaying_Big_End( Mat image, char* window_name, RNG rng )
{
Size textsize = getTextSize("OpenCV forever!", FONT_HERSHEY_COMPLEX, 3, 5, 0);
Point org((window_width - textsize.width)/2, (window_height - textsize.height)/2);
int lineType = 8;
Mat image2;
for( int i = 0; i < 255; i += 2 )
{
image2 = image - Scalar::all(i);
putText( image2, "OpenCV forever!", org, FONT_HERSHEY_COMPLEX, 3,
Scalar(i, i, 255), 5, lineType );
imshow( window_name, image2 );
if( waitKey(DELAY) >= 0 )
{ return -1; }
}
return 0;
}
@endcode
Besides the function **getTextSize** (which gets the size of the argument text), the new
operation we can observe is inside the *foor* loop:
@code{.cpp}
image2 = image - Scalar::all(i)
@endcode
So, **image2** is the substraction of **image** and **Scalar::all(i)**. In fact, what happens
here is that every pixel of **image2** will be the result of substracting every pixel of
**image** minus the value of **i** (remember that for each pixel we are considering three values
such as R, G and B, so each of them will be affected)
Also remember that the substraction operation *always* performs internally a **saturate**
operation, which means that the result obtained will always be inside the allowed range (no
negative and between 0 and 255 for our example).
Result
------
As you just saw in the Code section, the program will sequentially execute diverse drawing
functions, which will produce:
-# First a random set of *NUMBER* lines will appear on screen such as it can be seen in this
screenshot:
![](images/Drawing_2_Tutorial_Result_0.jpg)
-# Then, a new set of figures, these time *rectangles* will follow.
-# Now some ellipses will appear, each of them with random position, size, thickness and arc
length:
![](images/Drawing_2_Tutorial_Result_2.jpg)
-# Now, *polylines* with 03 segments will appear on screen, again in random configurations.
![](images/Drawing_2_Tutorial_Result_3.jpg)
-# Filled polygons (in this example triangles) will follow.
-# The last geometric figure to appear: circles!
![](images/Drawing_2_Tutorial_Result_5.jpg)
-# Near the end, the text *"Testing Text Rendering"* will appear in a variety of fonts, sizes,
colors and positions.
-# And the big end (which by the way expresses a big truth too):
![](images/Drawing_2_Tutorial_Result_big.jpg)
@@ -62,24 +62,6 @@ understanding how to manipulate the images on a pixel level.
We will learn how to change our image appearance!
- @subpage tutorial_basic_geometric_drawing
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán
We will learn how to draw simple geometry with OpenCV!
- @subpage tutorial_random_generator_and_text
*Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán
We will draw some *fancy-looking* stuff using OpenCV!
- @subpage tutorial_discrete_fourier_transform
*Languages:* C++, Java, Python