diff --git a/doc/tutorials/Adding_Images.rst b/doc/tutorials/Adding_Images.rst new file mode 100644 index 000000000..701d5734a --- /dev/null +++ b/doc/tutorials/Adding_Images.rst @@ -0,0 +1,119 @@ +.. _Adding_Images: + +Adding (blending) two images using OpenCV +******************************************* + +Goal +===== + +In this tutorial you will learn how to: + +* What is *linear blending* and why it is useful. +* Add two images using :add_weighted:`addWeighted <>` + +Cool Theory +================= + +.. note:: + + The explanation below belongs to the book `Computer Vision: Algorithms and Applications `_ by Richard Szeliski + +From our previous tutorial, we know already a bit of *Pixel operators*. An interesting dyadic (two-input) operator is the *linear blend operator*: + +.. math:: + + g(x) = (1 - \alpha)f_{0}(x) + \alpha f_{1}(x) + +By varying :math:`\alpha` from :math:`0 \rightarrow 1` this operator can be used to perform a temporal *cross-disolve* between two images or videos, as seen in slide shows and film production (cool, eh?) + +Code +===== + +As usual, after the not-so-lengthy explanation, let's go to the code. Here it is: + +.. code-block:: cpp + + #include + #include + #include + + using namespace cv; + + int main( int argc, char** argv ) + { + double alpha = 0.5; double beta; double input; + + Mat src1, src2, dst; + + /// Ask the user enter alpha + std::cout<<" Simple Linear Blender "<>input; + + /// We use the alpha provided by the user iff it is between 0 and 1 + if( alpha >= 0 && alpha <= 1 ) + { alpha = input; } + + /// Read image ( same size, same type ) + src1 = imread("../../images/LinuxLogo.jpg"); + src2 = imread("../../images/WindowsLogo.jpg"); + + if( !src1.data ) { printf("Error loading src1 \n"); return -1; } + if( !src2.data ) { printf("Error loading src2 \n"); return -1; } + + /// Create Windows + namedWindow("Linear Blend", 1); + + beta = ( 1.0 - alpha ); + addWeighted( src1, alpha, src2, beta, 0.0, dst); + + imshow( "Linear Blend", dst ); + + waitKey(0); + return 0; + } + +Explanation +============ + +#. Since we are going to perform: + + .. math:: + + g(x) = (1 - \alpha)f_{0}(x) + \alpha f_{1}(x) + + We need two source images (:math:`f_{0}(x)` and :math:`f_{1}(x)`). So, we load them in the usual way: + + .. code-block:: cpp + + src1 = imread("../../images/LinuxLogo.jpg"); + src2 = imread("../../images/WindowsLogo.jpg"); + + .. warning:: + + Since we are *adding* *src1* and *src2*, they both have to be of the same size (width and height) and type. + +#. Now we need to generate the :math:`g(x)` image. For this, the function :add_weighted:`addWeighted <>` comes quite handy: + + .. code-block:: cpp + + beta = ( 1.0 - alpha ); + addWeighted( src1, alpha, src2, beta, 0.0, dst); + + since :add_weighted:`addWeighted <>` produces: + + .. math:: + + dst = \alpha \cdot src1 + \beta \cdot src2 + \gamma + + In this case, :math:`\gamma` is the argument :math:`0.0` in the code above. + +#. Create windows, show the images and wait for the user to end the program. + +Result +======= + +.. image:: images/Adding_Images_Tutorial_Result_0.png + :alt: Blending Images Tutorial - Final Result + :align: center diff --git a/doc/tutorials/Adding_Trackbars.rst b/doc/tutorials/Adding_Trackbars.rst new file mode 100644 index 000000000..c5b77abed --- /dev/null +++ b/doc/tutorials/Adding_Trackbars.rst @@ -0,0 +1,162 @@ +.. _Adding_Trackbars: + +Adding a Trackbar to our applications! +*************************************** + +* In the previous tutorials (about *linear blending* and the *brightness and contrast adjustments*) you might have noted that we needed to give some **input** to our programs, such as :math:`\alpha` and :math:`beta`. We accomplished that by entering this data using the Terminal + +* Well, it is time to use some fancy GUI tools. OpenCV provides some GUI utilities (*highgui.h*) for you. An example of this is a **Trackbar** + + .. image:: images/Adding_Trackbars_Tutorial_Trackbar.png + :alt: Trackbar example + :align: center + +* In this tutorial we will just modify our two previous programs so that they get the input information from the trackbar. + + +Goals +====== + +In this tutorial you will learn how to: + +* Add a Trackbar in an OpenCV window by using :create_trackbar:`createTrackbar <>` + +Code +===== + +Let's modify the program made in the tutorial :ref:`Adding_Images`. We will let the user enter the :math:`\alpha` value by using the Trackbar. + +.. code-block:: cpp + + #include + #include + + using namespace cv; + + /// Global Variables + const int alpha_slider_max = 100; + int alpha_slider; + double alpha; + double beta; + + /// Matrices to store images + Mat src1; + Mat src2; + Mat dst; + + /** + * @function on_trackbar + * @brief Callback for trackbar + */ + void on_trackbar( int, void* ) + { + alpha = (double) alpha_slider/alpha_slider_max ; + beta = ( 1.0 - alpha ); + + addWeighted( src1, alpha, src2, beta, 0.0, dst); + + imshow( "Linear Blend", dst ); + } + + int main( int argc, char** argv ) + { + /// Read image ( same size, same type ) + src1 = imread("../../images/LinuxLogo.jpg"); + src2 = imread("../../images/WindowsLogo.jpg"); + + if( !src1.data ) { printf("Error loading src1 \n"); return -1; } + if( !src2.data ) { printf("Error loading src2 \n"); return -1; } + + /// Initialize values + alpha_slider = 0; + + /// Create Windows + namedWindow("Linear Blend", 1); + + /// Create Trackbars + char TrackbarName[50]; + sprintf( TrackbarName, "Alpha x %d", alpha_slider_max ); + + createTrackbar( TrackbarName, "Linear Blend", &alpha_slider, alpha_slider_max, on_trackbar ); + + /// Show some stuff + on_trackbar( alpha_slider, 0 ); + + /// Wait until user press some key + waitKey(0); + return 0; + } + + +Explanation +============ + +We only analyze the code that is related to Trackbar: + +#. First, we load 02 images, which are going to be blended. + + .. code-block:: cpp + + src1 = imread("../../images/LinuxLogo.jpg"); + src2 = imread("../../images/WindowsLogo.jpg"); + +#. To create a trackbar, first we have to create the window in which it is going to be located. So: + + .. code-block:: cpp + + namedWindow("Linear Blend", 1); + +#. Now we can create the Trackbar: + + .. code-block:: cpp + + createTrackbar( TrackbarName, "Linear Blend", &alpha_slider, alpha_slider_max, on_trackbar ); + + Note the following: + + * Our Trackbar has a label **TrackbarName** + * The Trackbar is located in the window named **"Linear Blend"** + * The Trackbar values will be in the range from :math:`0` to **alpha_slider_max** (the minimum limit is always **zero**). + * The numerical value of Trackbar is stored in **alpha_slider** + * Whenever the user moves the Trackbar, the callback function **on_trackbar** is called + +#. Finally, we have to define the callback function **on_trackbar** + + .. code-block:: cpp + + void on_trackbar( int, void* ) + { + alpha = (double) alpha_slider/alpha_slider_max ; + beta = ( 1.0 - alpha ); + + addWeighted( src1, alpha, src2, beta, 0.0, dst); + + imshow( "Linear Blend", dst ); + } + + Note that: + + * We use the value of **alpha_slider** (integer) to get a double value for **alpha**. + * **alpha_slider** is updated each time the trackbar is displaced by the user. + * We define *src1*, *src2*, *dist*, *alpha*, *alpha_slider* and *beta* as global variables, so they can be used everywhere. + +Result +======= + +* Our program produces the following output: + + .. image:: images/Adding_Trackbars_Tutorial_Result_0.png + :alt: Adding Trackbars - Windows Linux + :align: center + +* As a manner of practice, you can also add 02 trackbars for the program made in :ref:`Basic_Linear_Transform`. One trackbar to set :math:`\alpha` and another for :math:`\beta`. The output might look like: + + .. image:: images/Adding_Trackbars_Tutorial_Result_1.png + :alt: Adding Trackbars - Lena + :height: 500px + :align: center + + + + + diff --git a/doc/tutorials/Basic_Linear_Transform.rst b/doc/tutorials/Basic_Linear_Transform.rst new file mode 100644 index 000000000..f6b1bea77 --- /dev/null +++ b/doc/tutorials/Basic_Linear_Transform.rst @@ -0,0 +1,198 @@ +.. _Basic_Linear_Transform: + +Changing the contrast and brightness of an image! +*************************************************** + +Goal +===== + +In this tutorial you will learn how to: + +* Access pixel values + +* Initialize a matrix with zeros + +* Learn what :saturate_cast:`saturate_cast <>` does and why it is useful + +* Get some cool info about pixel transformations + +Cool Theory +================= + +.. note:: + The explanation below belongs to the book `Computer Vision: Algorithms and Applications `_ by Richard Szeliski + +Image Processing +-------------------- + +* A general image processing operator is a function that takes one or more input images and produces an output image. + +* Image transforms can be seen as: + + * Point operators (pixel transforms) + * Neighborhood (area-based) operators + + +Pixel Transforms +^^^^^^^^^^^^^^^^^ + +* In this kind of image processing transform, each output pixel's value depends on only the corresponding input pixel value (plus, potentially, some globally collected information or parameters). + +* Examples of such operators include *brightness and contrast adjustments* as well as color correction and transformations. + +Brightness and contrast adjustments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* Two commonly used point processes are *multiplication* and *addition* with a constant: + + .. math:: + + g(x) = \alpha f(x) + \beta + +* The parameters :math:`\alpha > 0` and :math:`\beta` are often called the *gain* and *bias* parameters; sometimes these parameters are said to control *contrast* and *brightness* respectively. + +* You can think of :math:`f(x)` as the source image pixels and :math:`g(x)` as the output image pixels. Then, more conveniently we can write the expression as: + + .. math:: + + g(i,j) = \alpha \cdot f(i,j) + \beta + where :math:`i` and :math:`j` indicates that the pixel is located in the *i-th* row and *j-th* column. + +Code +===== + +* The following code performs the operation :math:`g(i,j) = \alpha \cdot f(i,j) + \beta` +* Here it is: + +.. code-block:: cpp + + #include + #include + #include + + using namespace cv; + + double alpha; /**< Simple contrast control */ + int beta; /**< Simple brightness control */ + + int main( int argc, char** argv ) + { + /// Read image given by user + Mat image = imread( argv[1] ); + Mat new_image = Mat::zeros( image.size(), image.type() ); + + /// Initialize values + std::cout<<" Basic Linear Transforms "<>alpha; + std::cout<<"* Enter the beta value [0-100]: "; std::cin>>beta; + + /// Do the operation new_image(i,j) = alpha*image(i,j) + beta + for( int y = 0; y < image.rows; y++ ) + { for( int x = 0; x < image.cols; x++ ) + { for( int c = 0; c < 3; c++ ) + { + new_image.at(y,x)[c] = saturate_cast( alpha*( image.at(y,x)[c] ) + beta ); + } + } + } + + /// Create Windows + namedWindow("Original Image", 1); + namedWindow("New Image", 1); + + /// Show stuff + imshow("Original Image", image); + imshow("New Image", new_image); + + /// Wait until user press some key + waitKey(); + return 0; + } + +Explanation +============ + +#. We begin by creating parameters to save :math:`\alpha` and :math:`\beta` to be entered by the user: + + .. code-block:: cpp + + double alpha; + int beta; + + +#. We load an image using :imread:`imread <>` and save it in a Mat object: + + .. code-block:: cpp + + Mat image = imread( argv[1] ); + +#. 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 + + .. code-block:: cpp + + Mat new_image = Mat::zeros( image.size(), image.type() ); + + We observe that :mat_zeros:`Mat::zeros <>` returns a Matlab-style zero initializer based on *image.size()* and *image.type()* + +#. Now, to perform the operation :math:`g(i,j) = \alpha \cdot f(i,j) + \beta` we will access to each pixel in image. Since we are operating with RGB images, we will have three values per pixel (R, G and B), so we will also access them separately. Here is the piece of code: + + .. code-block:: cpp + + for( int y = 0; y < image.rows; y++ ) + { for( int x = 0; x < image.cols; x++ ) + { for( int c = 0; c < 3; c++ ) + { new_image.at(y,x)[c] = saturate_cast( alpha*( image.at(y,x)[c] ) + beta ); } + } + } + + Notice the following: + + * To access each pixel in the images we are using this syntax: *image.at(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 :math:`\alpha \cdot p(i,j) + \beta` can give values out of range or not integers (if :math:`\alpha` is float), we use :saturate_cast:`saturate_cast <>` to make sure the values are valid. + + +#. Finally, we create windows and show the images, the usual way. + + .. code-block:: cpp + + namedWindow("Original Image", 1); + namedWindow("New Image", 1); + + imshow("Original Image", image); + imshow("New Image", new_image); + + waitKey(0); + +.. note:: + + Instead of using the **for** loops to access each pixel, we could have simply used this command: + + .. code-block:: cpp + + image.convertTo(new_image, -1, alpha, beta); + + where :convert_to:`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. + +Result +======= + +* Running our code and using :math:`\alpha = 2.2` and :math:`\beta = 50` + + .. code-block:: bash + + $ ./BasicLinearTransforms lena.png + Basic Linear Transforms + ------------------------- + * Enter the alpha value [1.0-3.0]: 2.2 + * Enter the beta value [0-100]: 50 + +* We get this: + +.. image:: images/Basic_Linear_Transform_Tutorial_Result_0.png + :height: 400px + :alt: Basic Linear Transform - Final Result + :align: center diff --git a/doc/tutorials/Display_Image.rst b/doc/tutorials/Display_Image.rst new file mode 100644 index 000000000..72fe5c176 --- /dev/null +++ b/doc/tutorials/Display_Image.rst @@ -0,0 +1,112 @@ +.. _Display_Image: + +Display an Image +***************** + +Goal +===== + +In this tutorial you will learn how to: + +* Load an image using :imread:`imread <>` +* Create a named window (using :named_window:`namedWindow <>`) +* Display an image in an OpenCV window (using :imshow:`imshow <>`) + +Code +===== + +Here it is: + +.. code-block:: cpp + + #include + #include + + using namespace cv; + + int main( int argc, char** argv ) + { + Mat image; + image = imread( argv[1], 1 ); + + if( argc != 2 || !image.data ) + { + printf( "No image data \n" ); + return -1; + } + + namedWindow( "Display Image", CV_WINDOW_AUTOSIZE ); + imshow( "Display Image", image ); + + waitKey(0); + + return 0; + } + + +Explanation +============ + +#. .. code-block:: cpp + + #include + #include + + using namespace cv; + + These are OpenCV headers: + + * *cv.h* : Main OpenCV functions + * *highgui.h* : Graphical User Interface (GUI) functions + + Now, let's analyze the *main* function: + +#. .. code-block:: cpp + + Mat image; + + We create a Mat object to store the data of the image to load. + +#. .. code-block:: cpp + + image = imread( argv[1], 1 ); + + Here, we called the function :imread:`imread <>` which basically loads the image specified by the first argument (in this case *argv[1]*). The second argument is by default. + +#. After checking that the image data was loaded correctly, we want to display our image, so we create a window: + + .. code-block:: cpp + + namedWindow( "Display Image", CV_WINDOW_AUTOSIZE ); + + + :named_window:`namedWindow <>` receives as arguments the window name ("Display Image") and an additional argument that defines windows properties. In this case **CV_WINDOW_AUTOSIZE** indicates that the window will adopt the size of the image to be displayed. + +#. Finally, it is time to show the image, for this we use :imshow:`imshow <>` + + .. code-block:: cpp + + imshow( "Display Image", image ) + +#. Finally, we want our window to be displayed until the user presses a key (otherwise the program would end far too quickly): + + .. code-block:: cpp + + waitKey(0); + + We use the :wait_key:`waitKey <>` function, which allow us to wait for a keystroke during a number of milliseconds (determined by the argument). If the argument is zero, then it will wait indefinitely. + +Result +======= + +* Compile your code and then run the executable giving a image path as argument: + + .. code-block:: bash + + ./DisplayImage HappyFish.jpg + +* You should get a nice window as the one shown below: + + .. image:: images/Display_Image_Tutorial_Result.png + :alt: Display Image Tutorial - Final Result + :align: center diff --git a/doc/tutorials/Drawing_1.rst b/doc/tutorials/Drawing_1.rst new file mode 100644 index 000000000..791f239fd --- /dev/null +++ b/doc/tutorials/Drawing_1.rst @@ -0,0 +1,12 @@ +.. _Drawing_1: + +Basic Drawing +**************** + + +Result +======= + +.. image:: images/Adding_Images_Tutorial_Result_0.png + :alt: Blending Images Tutorial - Final Result + :align: center diff --git a/doc/tutorials/Drawing_2.rst b/doc/tutorials/Drawing_2.rst new file mode 100644 index 000000000..015254440 --- /dev/null +++ b/doc/tutorials/Drawing_2.rst @@ -0,0 +1,7 @@ +.. _Drawing_2: + +Fancy Drawing! +**************** + +Result +======== diff --git a/doc/tutorials/Linux_Eclipse_Usage.rst b/doc/tutorials/Linux_Eclipse_Usage.rst new file mode 100644 index 000000000..97df60967 --- /dev/null +++ b/doc/tutorials/Linux_Eclipse_Usage.rst @@ -0,0 +1,243 @@ +.. _Linux_Eclipse_Usage: + +Using OpenCV with Eclipse (plugin CDT) +**************************************** + +.. note:: + For me at least, this works, is simple and quick. Suggestions are welcome + +Prerequisites +=============== + +#. Having installed `Eclipse `_ in your workstation (only the CDT plugin for C/C++ is needed). You can follow the following steps: + + * Go to the Eclipse site + + * Download `Eclipse IDE for C/C++ Developers `_ . Choose the link according to your workstation. + +#. Having installed OpenCV. If not yet, go :ref:`here ` + +Making a project +================= + +#. Start Eclipse. Just run the executable that comes in the folder. + +#. Go to **File -> New -> C/C++ Project** + + .. image:: images/Eclipse_Tutorial_Screenshot-0.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 0 + :align: center + +#. Choose a name for your project (i.e. DisplayImage). An **Empty Project** should be okay for this example. + + .. image:: images/Eclipse_Tutorial_Screenshot-1.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 1 + :align: center + +#. Leave everything else by default. Press **Finish**. + + .. image:: images/Eclipse_Tutorial_Screenshot-2.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 2 + :align: center + +#. Your project (in this case DisplayImage) should appear in the **Project Navigator** (usually at the left side of your window). + + .. image:: images/Eclipse_Tutorial_Screenshot-3.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 3 + :align: center + + +#. Now, let's add a source file using OpenCV: + + * Right click on **DisplayImage** (in the Navigator). **New -> Folder** . + + .. image:: images/Eclipse_Tutorial_Screenshot-4.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 4 + :align: center + + * Name your folder **src** and then hit **Finish** + + .. image:: images/Eclipse_Tutorial_Screenshot-5.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 5 + :align: center + + * Right click on your newly created **src** folder. Choose **New source file**: + + .. image:: images/Eclipse_Tutorial_Screenshot-6.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 6 + :align: center + + * Call it **DisplayImage.cpp**. Hit **Finish** + + .. image:: images/Eclipse_Tutorial_Screenshot-7.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 7 + :align: center + +#. So, now you have a project with a empty .cpp file. Let's fill it with some sample code (in other words, copy and paste the snippet below): + + .. code-block:: cpp + + #include + #include + + using namespace cv; + + int main( int argc, char** argv ) + { + Mat image; + image = imread( argv[1], 1 ); + + if( argc != 2 || !image.data ) + { + printf( "No image data \n" ); + return -1; + } + + namedWindow( "Display Image", CV_WINDOW_AUTOSIZE ); + imshow( "Display Image", image ); + + waitKey(0); + + return 0; + } + +#. We are only missing one final step: To tell OpenCV where the OpenCV headers and libraries are. For this, do the following: + + * Go to **Project-->Properties** + + .. image:: images/Eclipse_Tutorial_Screenshot-8.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 8 + :align: center + + * In **C/C++ Build**, click on **Settings**. At the right, choose the **Tool Settings** Tab. Here we will enter the headers and libraries info: + + a. In **GCC C++ Compiler**, go to **Includes**. In **Include paths(-l)** you should include the path of the folder where opencv was installed. In our example, this is: + :: + + /usr/local/include/opencv + + .. image:: images/Eclipse_Tutorial_Screenshot-9.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 9 + :align: center + + .. note:: + If you do not know where your opencv files are, open the **Terminal** and type: + + .. code-block:: bash + + pkg-config --cflags opencv + + For instance, that command gave me this output: + + .. code-block:: bash + + -I/usr/local/include/opencv -I/usr/local/include + + + b. Now go to **GCC C++ Linker**,there you have to fill two spaces: + + * In **Library search path (-L)** you have to write the path to where the opencv libraries reside, in my case the path is: + :: + + /usr/local/lib + + * In **Libraries(-l)** add the OpenCV libraries that you may need. Usually just the 3 first on the list below are enough (for simple applications) . In my case, I am putting all of them since I plan to use the whole bunch: + + + * opencv_core + * opencv_imgproc + * opencv_highgui + * opencv_ml + * opencv_video + * opencv_features2d + * opencv_calib3d + * opencv_objdetect + * opencv_contrib + * opencv_legacy + * opencv_flann + + .. image:: images/Eclipse_Tutorial_Screenshot-10.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 10 + :align: center + + .. note:: + + If you don't know where your libraries are (or you are just psychotic and want to make sure the path is fine), type in **Terminal**: + + .. code-block:: bash + + pkg-config --libs opencv + + My output (in case you want to check) was: + + .. code-block:: bash + + -L/usr/local/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann + + Now you are done. Click **OK** + + * Your project should be ready to be built. For this, go to **Project->Build all** + + .. image:: images/Eclipse_Tutorial_Screenshot-11.png + :height: 400px + :alt: Eclipse Tutorial Screenshot 11 + :align: center + + In the Console you should get something like + + .. image:: images/Eclipse_Tutorial_Screenshot-12.png + :height: 200px + :alt: Eclipse Tutorial Screenshot 12 + :align: center + + If you check in your folder, there should be an executable there. + +Running the executable +======================== + +So, now we have an executable ready to run. If we were to use the Terminal, we would probably do something like: + +.. code-block:: bash + + cd + cd src + ./DisplayImage ../images/HappyLittleFish.jpg + +Assuming that the image to use as the argument would be located in /images/HappyLittleFish.jpg. We can still do this, but let's do it from Eclipse: + + +#. Go to **Run->Run Configurations** + + .. image:: images/Eclipse_Tutorial_Screenshot-13.png + :height: 300px + :alt: Eclipse Tutorial Screenshot 13 + :align: center + +#. Under C/C++ Application you will see the name of your executable + Debug (if not, click over C/C++ Application a couple of times). Select the name (in this case **DisplayImage Debug**). + +#. Now, in the right side of the window, choose the **Arguments** Tab. Write the path of the image file we want to open (path relative to the workspace/DisplayImage folder). Let's use **HappyLittleFish.jpg**: + + .. image:: images/Eclipse_Tutorial_Screenshot-14.png + :height: 300px + :alt: Eclipse Tutorial Screenshot 14 + :align: center + +#. Click on the **Apply** button and then in Run. An OpenCV window should pop up with the fish image (or whatever you used). + + .. image:: images/Eclipse_Tutorial_Screenshot-15.png + :alt: Eclipse Tutorial Screenshot 15 + :align: center + + +#. Congratulations! You are ready to have fun with OpenCV using Eclipse. diff --git a/doc/tutorials/Linux_GCC_Usage.rst b/doc/tutorials/Linux_GCC_Usage.rst new file mode 100644 index 000000000..7b9d5ed3c --- /dev/null +++ b/doc/tutorials/Linux_GCC_Usage.rst @@ -0,0 +1,84 @@ +.. _Linux_GCC_Usage: + +Using OpenCV with gcc and CMake +********************************* + +.. note:: + We assume that you have successfully installed OpenCV in your workstation. + +The easiest way of using OpenCV in your code is to use `CMake `_. A few advantages (taken from the Wiki): + +* No need to change anything when porting between Linux and Windows +* Can easily be combined with other tools by CMake( i.e. Qt, ITK and VTK ) + +If you are not familiar with CMake, checkout the `tutorial `_ on its website. + +Steps +====== + +Create a program using OpenCV +------------------------------- + +Let's use a simple program such as DisplayImage.cpp shown below. + +.. code-block:: cpp + + #include + #include + + using namespace cv; + + int main( int argc, char** argv ) + { + Mat image; + image = imread( argv[1], 1 ); + + if( argc != 2 || !image.data ) + { + printf( "No image data \n" ); + return -1; + } + + namedWindow( "Display Image", CV_WINDOW_AUTOSIZE ); + imshow( "Display Image", image ); + + waitKey(0); + + return 0; + } + +Create a CMake file +--------------------- +Now you have to create your CMakeLists.txt file. It should look like this: + +.. code-block:: cmake + + project( DisplayImage ) + find_package( OpenCV REQUIRED ) + add_executable( DisplayImage DisplayImage ) + target_link_libraries( DisplayImage ${OpenCV_LIBS} ) + +Generate the executable +------------------------- +This part is easy, just proceed as with any other project using CMake: + +.. code-block:: bash + + cd + cmake . + make + +Result +-------- +By now you should have an executable (called DisplayImage in this case). You just have to run it giving an image location as an argument, i.e.: + +.. code-block:: bash + + ./DisplayImage lena.jpg + +You should get a nice window as the one shown below: + +.. image:: images/GCC_CMake_Example_Tutorial.png + :alt: Display Image - Lena + :align: center + diff --git a/doc/tutorials/Linux_Installation.rst b/doc/tutorials/Linux_Installation.rst new file mode 100644 index 000000000..a9f147785 --- /dev/null +++ b/doc/tutorials/Linux_Installation.rst @@ -0,0 +1,85 @@ +.. _Linux_Installation: + +Installation in Linux +*********************** +These steps have been tested for Ubuntu 10.04 but should work with other distros. + +Required packages +================== + + * GCC 4.x or later. This can be installed with + + .. code-block:: bash + + sudo apt-get install build-essential + + * CMake 2.6 or higher + * Subversion (SVN) client + * GTK+2.x or higher, including headers + * pkgconfig + * libpng, zlib, libjpeg, libtiff, libjasper with development files (e.g. libpjeg-dev) + * Python 2.3 or later with developer packages (e.g. python-dev) + * SWIG 1.3.30 or later + * libavcodec + * libdc1394 2.x + +All the libraries above can be installed via Terminal or by using Synaptic Manager + +Getting OpenCV source code +============================ + +You can use the latest stable OpenCV version available in *sourceforge* or you can grab the latest snapshot from the SVN repository: + +Getting the latest stable OpenCV version +------------------------------------------ + +* Go to http://sourceforge.net/projects/opencvlibrary + +* Download the source tarball and unpack it + + +Getting the cutting-edge OpenCV from SourceForge SVN repository +----------------------------------------------------------------- + +Launch SVN client and checkout either + +a. the current OpenCV snapshot from here: https://code.ros.org/svn/opencv/trunk + +#. or the latest tested OpenCV snapshot from here: http://code.ros.org/svn/opencv/tags/latest_tested_snapshot + +In Ubuntu it can be done using the following command, e.g.: + +.. code-block:: bash + + cd ~/ + svn co https://code.ros.org/svn/opencv/trunk + + +Building OpenCV from source using CMake, using the command line +================================================================ + +#. Create a temporary directory, which we denote as , where you want to put the generated Makefiles, project files as well the object filees and output binaries + +#. Enter the and type + + .. code-block:: bash + + cmake [] + + For example + + .. code-block:: bash + + cd ~/opencv + mkdir release + cd release + cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX= /usr/local + +#. Enter the created temporary directory () and proceed with: + + .. code-block:: bash + + make + sudo make install + + diff --git a/doc/tutorials/Load_Save_Image.rst b/doc/tutorials/Load_Save_Image.rst new file mode 100644 index 000000000..8afdf0c2d --- /dev/null +++ b/doc/tutorials/Load_Save_Image.rst @@ -0,0 +1,122 @@ +.. _Load_Save_Image: + +Load and Save an Image +*********************** + +.. note:: + + We assume that by now you know: + + * Load an image using :imread:`imread <>` + * Display an image in an OpenCV window (using :imshow:`imshow <>`) + +Goals +====== + +In this tutorial you will learn how to: + +* Transform an image from RGB to Grayscale format by using :cvt_color:`cvtColor <>` +* Save your transformed image in a file on disk (using :imwrite:`imwrite <>`) + +Code +====== + +Here it is: + +.. code-block:: cpp + :linenos: + + #include + #include + + using namespace cv; + + int main( int argc, char** argv ) + { + char* imageName = argv[1]; + + Mat image; + image = imread( imageName, 1 ); + + if( argc != 2 || !image.data ) + { + printf( " No image data \n " ); + return -1; + } + + Mat gray_image; + cvtColor( image, gray_image, CV_RGB2GRAY ); + + imwrite( "../../images/Gray_Image.png", gray_image ); + + namedWindow( imageName, CV_WINDOW_AUTOSIZE ); + namedWindow( "Gray image", CV_WINDOW_AUTOSIZE ); + + imshow( imageName, image ); + imshow( "Gray image", gray_image ); + + waitKey(0); + + return 0; + } + +Explanation +============ + +#. We begin by: + + * Creating a Mat object to store the image information + * Load an image using :imread:`imread <>`, located in the path given by *imageName*. Fort this example, assume you are loading a RGB image. + +#. Now we are going to convert our image from RGB to Grayscale format. OpenCV has a really nice function to do this kind of transformations: + + .. code-block:: cpp + + cvtColor( image, gray_image, CV_RGB2GRAY ); + + As you can see, :cvt_color:`cvtColor <>` takes as arguments: + + * a source image (*image*) + * a destination image (*gray_image*), in which we will save the converted image. + + And an additional parameter that indicates what kind of transformation will be performed. In this case we use **CV_RGB2GRAY** (self-explanatory). + +#. So now we have our new *gray_image* and want to save it on disk (otherwise it will get lost after the program ends). To save it, we will use a function analagous to :imread:`imread <>`: :imwrite:`imwrite <>` + + .. code-block:: cpp + + imwrite( "../../images/Gray_Image.png", gray_image ); + + Which will save our *gray_image* as *Gray_Image.png* in the folder *images* located two levels up of my current location. + +#. Finally, let's check out the images. We create 02 windows and use them to show the original image as well as the new one: + + .. code-block:: cpp + + namedWindow( imageName, CV_WINDOW_AUTOSIZE ); + namedWindow( "Gray image", CV_WINDOW_AUTOSIZE ); + + imshow( imageName, image ); + imshow( "Gray image", gray_image ); + +#. Add the usual *waitKey(0)* for the program to wait forever until the user presses a key. + + +Result +======= + +When you run your program you should get something like this: + + .. image:: images/Load_Save_Image_Result_1.png + :alt: Load Save Image Result 1 + :height: 400px + :align: center + +And if you check in your folder (in my case *images*), you should have a newly .png file named *Gray_Image.png*: + + .. image:: images/Load_Save_Image_Result_2.png + :alt: Load Save Image Result 2 + :height: 250px + :align: center + +Congratulations, you are done with this tutorial! diff --git a/doc/tutorials/images/Adding_Images_Tutorial_Result_0.png b/doc/tutorials/images/Adding_Images_Tutorial_Result_0.png new file mode 100644 index 000000000..dd3c542f2 Binary files /dev/null and b/doc/tutorials/images/Adding_Images_Tutorial_Result_0.png differ diff --git a/doc/tutorials/images/Adding_Trackbars_Tutorial_Cover.png b/doc/tutorials/images/Adding_Trackbars_Tutorial_Cover.png new file mode 100644 index 000000000..7095a25e4 Binary files /dev/null and b/doc/tutorials/images/Adding_Trackbars_Tutorial_Cover.png differ diff --git a/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_0.png b/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_0.png new file mode 100644 index 000000000..df0de17ea Binary files /dev/null and b/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_0.png differ diff --git a/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_1.png b/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_1.png new file mode 100644 index 000000000..28c3d75cc Binary files /dev/null and b/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_1.png differ diff --git a/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_1a.png b/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_1a.png new file mode 100644 index 000000000..a8d98f5c5 Binary files /dev/null and b/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_1a.png differ diff --git a/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_1b.png b/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_1b.png new file mode 100644 index 000000000..cce25e620 Binary files /dev/null and b/doc/tutorials/images/Adding_Trackbars_Tutorial_Result_1b.png differ diff --git a/doc/tutorials/images/Adding_Trackbars_Tutorial_Trackbar.png b/doc/tutorials/images/Adding_Trackbars_Tutorial_Trackbar.png new file mode 100644 index 000000000..d6d02541d Binary files /dev/null and b/doc/tutorials/images/Adding_Trackbars_Tutorial_Trackbar.png differ diff --git a/doc/tutorials/images/Basic_Linear_Transform_Tutorial_Result_0.png b/doc/tutorials/images/Basic_Linear_Transform_Tutorial_Result_0.png new file mode 100644 index 000000000..ccc7850aa Binary files /dev/null and b/doc/tutorials/images/Basic_Linear_Transform_Tutorial_Result_0.png differ diff --git a/doc/tutorials/images/Basic_Linear_Transform_a.png b/doc/tutorials/images/Basic_Linear_Transform_a.png new file mode 100644 index 000000000..978df3f66 Binary files /dev/null and b/doc/tutorials/images/Basic_Linear_Transform_a.png differ diff --git a/doc/tutorials/images/Basic_Linear_Transform_b.png b/doc/tutorials/images/Basic_Linear_Transform_b.png new file mode 100644 index 000000000..d99041aad Binary files /dev/null and b/doc/tutorials/images/Basic_Linear_Transform_b.png differ diff --git a/doc/tutorials/images/Display_Image_Tutorial_Result.png b/doc/tutorials/images/Display_Image_Tutorial_Result.png new file mode 100644 index 000000000..5ce6577d9 Binary files /dev/null and b/doc/tutorials/images/Display_Image_Tutorial_Result.png differ diff --git a/doc/tutorials/images/Drawing_1_Tutorial_Result_0.png b/doc/tutorials/images/Drawing_1_Tutorial_Result_0.png new file mode 100644 index 000000000..8e24096aa Binary files /dev/null and b/doc/tutorials/images/Drawing_1_Tutorial_Result_0.png differ diff --git a/doc/tutorials/images/Drawing_1_Tutorial_Result_0a.png b/doc/tutorials/images/Drawing_1_Tutorial_Result_0a.png new file mode 100644 index 000000000..3125d38ec Binary files /dev/null and b/doc/tutorials/images/Drawing_1_Tutorial_Result_0a.png differ diff --git a/doc/tutorials/images/Drawing_1_Tutorial_Result_0b.png b/doc/tutorials/images/Drawing_1_Tutorial_Result_0b.png new file mode 100644 index 000000000..56ba38b8b Binary files /dev/null and b/doc/tutorials/images/Drawing_1_Tutorial_Result_0b.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-0.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-0.png new file mode 100644 index 000000000..4183cbda2 Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-0.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-1.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-1.png new file mode 100644 index 000000000..e37c40aaf Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-1.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-10.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-10.png new file mode 100644 index 000000000..b2237f846 Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-10.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-11.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-11.png new file mode 100644 index 000000000..8e29605f6 Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-11.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-12.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-12.png new file mode 100644 index 000000000..d1a75ec48 Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-12.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-13.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-13.png new file mode 100644 index 000000000..0667a2915 Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-13.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-14.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-14.png new file mode 100644 index 000000000..c11c293ed Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-14.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-15.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-15.png new file mode 100644 index 000000000..a2617fb85 Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-15.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-2.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-2.png new file mode 100644 index 000000000..e88d5eb7d Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-2.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-3.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-3.png new file mode 100644 index 000000000..3cc590d02 Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-3.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-4.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-4.png new file mode 100644 index 000000000..c34de2d67 Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-4.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-5.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-5.png new file mode 100644 index 000000000..85dab17d2 Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-5.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-6.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-6.png new file mode 100644 index 000000000..a82a87dd7 Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-6.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-7.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-7.png new file mode 100644 index 000000000..2dcc65aac Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-7.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-8.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-8.png new file mode 100644 index 000000000..612c542da Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-8.png differ diff --git a/doc/tutorials/images/Eclipse_Tutorial_Screenshot-9.png b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-9.png new file mode 100644 index 000000000..79969c975 Binary files /dev/null and b/doc/tutorials/images/Eclipse_Tutorial_Screenshot-9.png differ diff --git a/doc/tutorials/images/GCC_CMake_Example_Tutorial.png b/doc/tutorials/images/GCC_CMake_Example_Tutorial.png new file mode 100644 index 000000000..96a1e2e22 Binary files /dev/null and b/doc/tutorials/images/GCC_CMake_Example_Tutorial.png differ diff --git a/doc/tutorials/images/Load_Save_Image_Result_1.png b/doc/tutorials/images/Load_Save_Image_Result_1.png new file mode 100644 index 000000000..7e02ae97f Binary files /dev/null and b/doc/tutorials/images/Load_Save_Image_Result_1.png differ diff --git a/doc/tutorials/images/Load_Save_Image_Result_2.png b/doc/tutorials/images/Load_Save_Image_Result_2.png new file mode 100644 index 000000000..effd99151 Binary files /dev/null and b/doc/tutorials/images/Load_Save_Image_Result_2.png differ diff --git a/doc/tutorials/images/Load_Save_Image_Result_a.png b/doc/tutorials/images/Load_Save_Image_Result_a.png new file mode 100644 index 000000000..d50bc2bbe Binary files /dev/null and b/doc/tutorials/images/Load_Save_Image_Result_a.png differ diff --git a/doc/tutorials/images/Load_Save_Image_Result_b.png b/doc/tutorials/images/Load_Save_Image_Result_b.png new file mode 100644 index 000000000..d1f9f90f8 Binary files /dev/null and b/doc/tutorials/images/Load_Save_Image_Result_b.png differ diff --git a/doc/tutorials/images/eclipse_cpp_logo.jpeg b/doc/tutorials/images/eclipse_cpp_logo.jpeg new file mode 100644 index 000000000..f1aecfe85 Binary files /dev/null and b/doc/tutorials/images/eclipse_cpp_logo.jpeg differ diff --git a/doc/tutorials/images/gccegg-65-2.png b/doc/tutorials/images/gccegg-65-2.png new file mode 100644 index 000000000..6a74485f2 Binary files /dev/null and b/doc/tutorials/images/gccegg-65-2.png differ diff --git a/doc/tutorials/images/gccegg-65.png b/doc/tutorials/images/gccegg-65.png new file mode 100644 index 000000000..cd5902937 Binary files /dev/null and b/doc/tutorials/images/gccegg-65.png differ diff --git a/doc/tutorials/images/ubuntu_logo.jpeg b/doc/tutorials/images/ubuntu_logo.jpeg new file mode 100644 index 000000000..50544c119 Binary files /dev/null and b/doc/tutorials/images/ubuntu_logo.jpeg differ diff --git a/doc/tutorials/tutorials.rst b/doc/tutorials/tutorials.rst index 7f648069d..dc76ef10d 100644 --- a/doc/tutorials/tutorials.rst +++ b/doc/tutorials/tutorials.rst @@ -3,8 +3,162 @@ OpenCV Tutorials ################# .. toctree:: - :maxdepth: 2 - prerequisites.rst - features2d.rst - calib3d.rst +The following links describe a set of basic OpenCV tutorials. All the source code mentioned here is provide as part of the OpenCV regular releases, so check before you start copy & pasting the code. The list of tutorials below is automatically generated from reST files located in our SVN repository. + +.. note:: + YouTube videos yet to come...we have to think about them! + +As always, we would be happy to hear your comments and receive your contributions on any tutorial. + +* **INSTALLATION** + + * :ref:`Linux_Installation` + + =========== ====================================================== + |Install_1| *Title:* **Installation steps in Linux** + + *Compatibility:* > OpenCV 2.0 + + We will learn how to setup OpenCV in your computer! + + =========== ====================================================== + + .. |Install_1| image:: images/ubuntu_logo.jpeg + :height: 120px + + + +* **USAGE AND COMPILATION** + + * :ref:`Linux_GCC_Usage` + + =========== ====================================================== + |Usage_1| *Title:* **Using OpenCV with gcc (and CMake)** + + *Compatibility:* > OpenCV 2.0 + + We will learn how to compile your first project using gcc and CMake + + =========== ====================================================== + + .. |Usage_1| image:: images/gccegg-65-2.png + :height: 120px + + + * :ref:`Linux_Eclipse_Usage` + + =========== ====================================================== + |Usage_2| *Title:* **Using OpenCV with Eclipse (CDT plugin)** + + *Compatibility:* > OpenCV 2.0 + + We will learn how to compile your first project using the Eclipse environment + + =========== ====================================================== + + .. |Usage_2| image:: images/eclipse_cpp_logo.jpeg + :height: 120px + +* **BEGINNERS SECTION** + + * :ref:`Display_Image` + + =============== ====================================================== + |Beginners_1| *Title:* **Display an Image** + + *Compatibility:* > OpenCV 2.0 + + We will learn how to display an image using OpenCV + + =============== ====================================================== + + .. |Beginners_1| image:: images/Display_Image_Tutorial_Result.png + :height: 150px + + + * :ref:`Load_Save_Image` + + =============== ====================================================== + |Beginners_2| *Title:* **Load and save an Image** + + *Compatibility:* > OpenCV 2.0 + + We will learn how to save an Image in OpenCV...plus a small conversion to grayscale + + =============== ====================================================== + + .. |Beginners_2| image:: images/Load_Save_Image_Result_1.png + :height: 150px + + * :ref:`Basic_Linear_Transform` + + =============== ====================================================== + |Beginners_3| *Title:* **Changing the contrast and brightness of an image** + + *Compatibility:* > OpenCV 2.0 + + We will learn how to change our image appearance! + + =============== ====================================================== + + .. |Beginners_3| image:: images/Basic_Linear_Transform_Tutorial_Result_0.png + :height: 200px + + + * :ref:`Adding_Images` + + =============== ====================================================== + |Beginners_4| *Title:* **Linear Blending** + + *Compatibility:* > OpenCV 2.0 + + We will learn how to blend two images! + + =============== ====================================================== + + .. |Beginners_4| image:: images/Adding_Images_Tutorial_Result_0.png + :height: 200px + + + * :ref:`Adding_Trackbars` + + =============== ====================================================== + |Beginners_5| *Title:* **Creating Trackbars** + + *Compatibility:* > OpenCV 2.0 + + We will learn how to add a Trackbar to our applications + + =============== ====================================================== + + .. |Beginners_5| image:: images/Adding_Trackbars_Tutorial_Cover.png + :height: 200px + + * :ref:`Drawing_1` + + =============== ====================================================== + |Beginners_6| *Title:* **Basic Drawing** + + *Compatibility:* > OpenCV 2.0 + + We will learn how to draw simple geometry with OpenCV! + + =============== ====================================================== + + .. |Beginners_6| image:: images/Drawing_1_Tutorial_Result_0.png + :height: 200px + + * :ref:`Drawing_2` + + =============== ====================================================== + |Beginners_7| *Title:* **Cool Drawing** + + *Compatibility:* > OpenCV 2.0 + + We will draw some *fancy-looking* stuff using OpenCV! + + =============== ====================================================== + + .. |Beginners_7| image:: images/Drawing_1_Tutorial_Result_0.png + :height: 200px