File: adding_images.rst

package info (click to toggle)
opencv 2.4.9.1%2Bdfsg-1%2Bdeb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 126,800 kB
  • ctags: 62,729
  • sloc: xml: 509,055; cpp: 490,794; lisp: 23,208; python: 21,174; java: 19,317; ansic: 1,038; sh: 128; makefile: 72
file content (121 lines) | stat: -rw-r--r-- 3,203 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
.. _Adding_Images:

Adding (blending) two images using OpenCV
*******************************************

Goal
=====

In this tutorial you will learn:

.. container:: enumeratevisibleitemswithsquare

   * what is *linear blending* and why it is useful;
   * how to add two images using :add_weighted:`addWeighted <>`

Theory
=======

.. note::

   The explanation below belongs to the book `Computer Vision: Algorithms and Applications <http://szeliski.org/Book/>`_  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 productions (cool, eh?)

Code
=====

As usual, after the not-so-lengthy explanation, let's go to the code:

.. code-block:: cpp

   #include <cv.h>
   #include <highgui.h>
   #include <iostream>

   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 "<<std::endl;
    std::cout<<"-----------------------"<<std::endl;
    std::cout<<"* Enter alpha [0-1]: ";
    std::cin>>input;

    /// We use the alpha provided by the user if it is between 0 and 1
    if( input >= 0.0 && input <= 1.0 )
      { 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.jpg
   :alt: Blending Images Tutorial - Final Result
   :align: center