4 Use OpenCV to sum two images (blending)
Linear hybrid operation is also a typical binary (two inputs) pixel operation.
By changing alpha in range 0-1, this operation can be used to overlay two images or two videos in time.
#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 iff it is between 0 and 1 if( alpha >= 0 && alpha <= 1 ) { alpha = input; } /// To load an image, it must be of the same type and size. 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);//The calculation is as follows: 0.0 is gamma. imshow( "Linear Blend", dst ); waitKey(0); return 0; }
5. Change the contrast and brightness of the image
Image processing operator is a function that produces one or more input images and one output image. Image transformation can be divided into two types: point operator (pixel transformation) and neighborhood operator (region-based).
5.1 Pixel Transform
In this kind of image processing transformation, the corresponding output pixel values are calculated only according to the input pixel values (sometimes some global information or parameters can be added). These operators include brightness and contrast adjustment, as well as color correction and transformation.
5.2 Brightness and Contrast Adjustment
Two commonly used point processes (i.e. point operators) are the multiplication and addition of points by using constants:
Two parameters alpha > 0 and beta are commonly referred to as gain and bias parameters.
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace std; using namespace cv; double alpha; /**< Contrast Degree of Control */ int beta; /**< Controlling Brightness */ int main( int argc, char** argv ) { /// Read in the image provided by the user Mat image = imread( argv[1] ); Mat new_image = Mat::zeros( image.size(), image.type() );//Initialization of Matlab Style /// Initialization cout << " Basic Linear Transforms " << endl; cout << "-------------------------" << endl; cout << "* Enter the alpha value [1.0-3.0]: "; cin >> alpha; cout << "* Enter the beta value [0-100]: "; cin >> beta; /// Perform 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<Vec3b>(y,x)[c] = saturate_cast<uchar>( alpha*( image.at<Vec3b>(y,x)[c] ) + beta );//y is the row where the pixel is located and x is the column where the pixel is located. saturate_cast converts the result to ensure that it is a valid value. } } } /// Create windows namedWindow("Original Image", 1); namedWindow("New Image", 1); /// Display image imshow("Original Image", image); imshow("New Image", new_image); /// Waiting for user buttons waitKey(); return 0; }
Instead of using the for loop to access each pixel, you can use the following command directly
image.convertTo(new_image, -1, alpha, beta);
The second parameter is type, which is the type of output matrix needed, or more specifically, the depth of the output matrix. If it is negative (commonly used - 1), the type of output matrix and input matrix is the same.
6 Basic Drawing
The number of data structures represents the 2D points specified by their image coordinates x and y. It can be defined as:
Point pt; pt.x = 10; pt.y = 8; //perhaps Point pt = Point(10, 8);
Scalar represents an array with four elements. Subtypes are widely used in OpenCV to transfer pixel values. If you do not use the fourth parameter, you do not need to define it.
Scalar( a, b, c )
Then the RGB color values defined are: Red = c, Green = B and Blue = a
/// Window name char atom_window[] = "Drawing 1: Atom"; char rook_window[] = "Drawing 2: Rook"; /// Create empty images of empty, all-black pixels Mat atom_image = Mat::zeros( w, w, CV_8UC3 ); Mat rook_image = Mat::zeros( w, w, CV_8UC3 ); /// 1. Draw a simple atom. /// 1.a. Create ellipses. Draw atoms with MyEllipse and MyFilled Circle. MyEllipse( atom_image, 90 ); MyEllipse( atom_image, 0 ); MyEllipse( atom_image, 45 ); MyEllipse( atom_image, -45 ); /// 1.b. Create a circle MyFilledCircle( atom_image, Point( w/2.0, w/2.0) ); /// 2. Draw a gambler /// 2.a. Create a convex polygon MyPolygon( rook_image ); /// 2.b. Creating Rectangles rectangle( rook_image, Point( 0, 7*w/8.0 ), Point( w, w), Scalar( 0, 255, 255 ), -1, 8 ); /// 2.c. Draw a few straight lines MyLine( rook_image, Point( 0, 15*w/16 ), Point( w, 15*w/16 ) ); MyLine( rook_image, Point( w/4, 7*w/8 ), Point( w/4, w ) ); MyLine( rook_image, Point( w/2, 7*w/8 ), Point( w/2, w ) ); MyLine( rook_image, Point( 3*w/4, 7*w/8 ), Point( 3*w/4, w ) );
//Definition of function void MyLine( Mat img, Point start, Point end ) { int thickness = 2; int lineType = 8; line( img, //Written image start, //Starting point end, //End Scalar( 0, 0, 0 ), //colour thickness, //Line thickness lineType ); //The type of line can be taken as 8, 4, and CV_AA, representing 8 adjacent connection lines, 4 adjacent connection lines and anti-serrated connection lines, respectively. The default value is 8 adjacency. } void MyEllipse( Mat img, double angle ) { int thickness = 2; int lineType = 8; ellipse( img, Point( w/2.0, w/2.0 ), //Elliptic Center Size( w/4.0, w/16.0 ), //Size angle, //Elliptical rotation angle 0, 360, //The radian of ellipse extension ranges from 0 to 360 degrees Scalar( 255, 0, 0 ), thickness, lineType ); } void MyFilledCircle( Mat img, Point center ) { int thickness = -1; int lineType = 8; circle( img, center, w/32.0, //The radius of a circle Scalar( 0, 0, 255 ), thickness, //The circle is filled lineType ); } rectangle( rook_image, Point( 0, 7*w/8.0 ), //Two diagonal vertices of a rectangle Point( w, w), Scalar( 0, 255, 255 ), -1, 8 );