Prev Tutorial: Operations with images
Next Tutorial: Changing the contrast and brightness of an image!
Original author Ana Huamán
Compatibility OpenCV >= 3.0
We will learn how to blend two images!
Goal
In this tutorial you will learn:
what is linear blending and why it is useful;
how to add two images using addWeighted()
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 :
g(x) = (1 - \alpha)f_{0}(x) + \alpha f_{1}(x)
By varying \alpha from 0 \rightarrow 1 this operator can be used to perform a temporal cross-dissolve between two images or videos, as seen in slide shows and film productions (cool, eh?)
Source Code C++ Java Python
C++
Download the source code from here .
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main( void )
{
double alpha = 0.5; double beta; double input;
cout << " Simple Linear Blender " << endl;
cout << "-----------------------" << endl;
cout << "* Enter alpha [0.0-1.0]: " ;
cin >> input;
if ( input >= 0 && input <= 1 )
{ alpha = input; }
if ( src1.
empty () ) { cout <<
"Error loading src1" << endl;
return EXIT_FAILURE; }
if ( src2.
empty () ) { cout <<
"Error loading src2" << endl;
return EXIT_FAILURE; }
beta = ( 1.0 - alpha );
imshow (
"Linear Blend" , dst );
return 0;
}
Java
Download the source code from here .
import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import java.util.Locale;
import java.util.Scanner;
class AddingImagesRun{
public void run() {
double alpha = 0.5; double beta; double input;
Mat src1, src2, dst = new Mat();
System.out.println(" Simple Linear Blender " );
System.out.println("-----------------------" );
System.out.println("* Enter alpha [0.0-1.0]: " );
Scanner scan = new Scanner( System.in ).useLocale(Locale.US);
input = scan.nextDouble();
if ( input >= 0.0 && input <= 1.0 )
alpha = input;
src1 = Imgcodecs.imread("../../images/LinuxLogo.jpg" );
src2 = Imgcodecs.imread("../../images/WindowsLogo.jpg" );
if ( src1.empty() == true ){ System.out.println("Error loading src1" ); return ;}
if ( src2.empty() == true ){ System.out.println("Error loading src2" ); return ;}
beta = ( 1.0 - alpha );
Core.addWeighted( src1, alpha, src2, beta, 0.0, dst);
HighGui.imshow("Linear Blend" , dst);
HighGui.waitKey(0);
System.exit(0);
}
}
public class AddingImages {
public static void main(
String [] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new AddingImagesRun().run();
}
}
Python
Download the source code from here .
from __future__ import print_function
import cv2 as cv
alpha = 0.5
try :
raw_input
except NameError:
raw_input = input
print (
''' Simple Linear Blender -----------------------
* Enter alpha [0.0-1.0]: ''' )
input_alpha = float(raw_input().
strip ())
if 0 <= alpha <= 1:
alpha = input_alpha
if src1 is None :
print (
"Error loading src1" )
exit(-1)
elif src2 is None :
print (
"Error loading src2" )
exit(-1)
beta = (1.0 - alpha)
Explanation C++ Java Python
Since we are going to perform:
g(x) = (1 - \alpha)f_{0}(x) + \alpha f_{1}(x)
We need two source images ( f_{0}(x) and f_{1}(x) ). So, we load them in the usual way:
C++
Java
src1 = Imgcodecs.imread("../../images/LinuxLogo.jpg" );
src2 = Imgcodecs.imread("../../images/WindowsLogo.jpg" );
Python
We used the following images: LinuxLogo.jpg and 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 g(x)
image. For this, the function addWeighted() comes quite handy:
C++
Java
beta = ( 1.0 - alpha );
Core.addWeighted( src1, alpha, src2, beta, 0.0, dst);
Python
Numpy version of above line (but cv function is around 2x faster):
dst = np.uint8(alpha*(img1)+beta*(img2))
since addWeighted() produces:
dst = \alpha \cdot src1 + \beta \cdot src2 + \gamma
In this case, gamma
is the argument 0.0 in the code above.
Create windows, show the images and wait for the user to end the program.
C++
imshow (
"Linear Blend" , dst );
Java
HighGui.imshow("Linear Blend" , dst);
HighGui.waitKey(0);
Python
Result