OpenCV C++ image overlay linear blending method summary


// Operating system: Windows 10 64bit
// Development language: C++
// IDE version: Visual Studio 2019
// OpenCV version: 4.20

1. Use the ROI of the region of interest to achieve image overlay

ROI (region of interest), region of interest. In machine vision and image processing, the area to be processed is outlined in the form of boxes, circles, ellipses, irregular polygons, etc. from the processed image, which is called a region of interest, ROI. Various operators and functions are commonly used in machine vision software such as Halcon, OpenCV, and Matlab to obtain the ROI of the region of interest, and perform the next step of processing the image.

1 Create ROI area

// 定义一个Mat类型,用于存放,图像的ROI
	Mat imageROI;
	//方法一
	imageROI= image(Rect(800,350,logo.cols,logo.rows));
	//方法二
	//imageROI= image(Range(350,350+logo.rows),Range(800,800+logo.cols));

//This is equivalent to using pointer knowledge to point the roi area to the corresponding area of ​​the image image
Rect(x,y,w,h)
x,y are the coordinates of the upper left corner of the ROI area of ​​the image; the coordinates of the upper left corner of the image (0, 0)

x+logo.cols cannot be greater than the width of the image object image
y+logo.rows cannot be greater than the height of the image object image

2 Constructing ROI area mask (basic of image overlay)

Mat ROI = image(Rect(200, 250, logo.cols, logo.rows));
Mat mask = imread("logo.jpg", 0);//掩膜必须为叠加图片的灰度图
logo.copyTo(ROI, mask);

3 Code implementation and effect

The following shows how to use ROI to add a picture to the specified position of another picture

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;

int main()
{
        //【1】读入图像  
        Mat srcImage1 = imread("49.jpg");
        Mat logoImage = imread("61.jpg");
       
        //显示原图
        namedWindow("【1】原图");
        imshow("【1】原图", srcImage1);
        namedWindow("【2】原图");
        imshow("【2】logo", logoImage);

        //【2】定义一个Mat类型并给其设定ROI区域  
        Mat imageROI = srcImage1(Rect(320, 120, logoImage.cols, logoImage.rows));

        //【3】加载掩模(必须是灰度图)  
        Mat mask = imread("61.jpg", 0);

        //【4】将掩膜拷贝到ROI  
        logoImage.copyTo(imageROI, mask);

        //【5】显示结果  
        namedWindow("【3】ROI图像叠加");
        imshow("【3】ROI图像叠加", srcImage1);

        waitKey();
	return 0;
}

This function first loads two jpg images into srcImage1 and logoImage, then defines a Mat type imageROI, and uses cv::Rect to set its region of interest to a region in srcImage1, and associate imageROI with srcImage1 . Then define a Mat type mask and read in dota_logo.jpg, use Mat:: copyTo to copy the contents of the mask to the imageROI, and then get the final rendering, namedWindow and imshow are used together to show the final the result of.

Picture 1 and Picture 2 Original picture
Insert picture description hereInsert picture description here
Below is the superposition effect
Insert picture description here

2. The addWeighted function realizes linear blending of images

Linear mixing means that two pictures or two videos are superimposed and presented in a certain functional relationship.

For the two input images A and B, take the pixel values ​​at the same position and linearly add them, and then assign the result to the pixel at the same position in the target image. The parameter α controls the weight of the two pictures in the target image.

                              g(x)=αA(x)+(1−α)B(x)

What is the effect of linear blending of images? In slideshow page turning or film production, it is often necessary to produce the effect of screen superimposition. In the above formula, as long as α is gradually reduced from 1 to 0, the superimposition effect when transitioning from image I0 to image I1 can be produced.

OpenCV provides an API for linear blending of two images. The calculation formula on which the API is based is as follows:

                     dst = src1[i] * α + src2[i] * β + γ;

addWeighted original function

void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1);**

The first parameter: the first image to be superimposed Mat

The second parameter: Identifies the weight of the superposition of the first parameter

The third parameter: represents the second superimposed image, it needs to have the same size and number of channels as the first array

The fourth parameter: represents the weight of the second superimposed image

The fifth parameter: the output parameter, which needs to have the same number of channels and size as the first two images

The sixth parameter: a scalar value added to the total weight (fill in 0 just fine)

The seventh parameter: the depth of the output array has a default value of -1, when the two superimposed images have the same depth, the parameter is -1

// 将logo加到原图上
//【3】将logo加到原图上,利用线性混合构建掩膜,其中logo权重是0.3,原图中的ROI区域图像是0.5
   addWeighted(imageROI, 0.5, logo, 0.5,0, imageROI);

It is worth noting that the
size and type of the two images must be the same. If the two images are inconsistent, first use the ROI to extract the smaller image and then superimpose it. Although it is not mandatory that the two weights must add up to 1, but it is usually that dry.

Code

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;

int main()
{
    //【0】定义一些局部变量  
    double α = 0.4;
    double β;
    Mat srcImage2, srcImage3, dstImage;

    //【1】读取图像 ( 两幅图片需为同样的类型和尺寸 )  
    srcImage2 = imread("67.jpg");
    srcImage3 = imread("68.jpg");

    //【2】做图像混合加权操作  
    β = (1.0 - α);
    addWeighted(srcImage2, α, srcImage3, β, 0., dstImage);

    //【3】创建并显示 
    namedWindow("<1>原图");
    imshow("<1>原图", srcImage2);
    namedWindow("<2>原图");
    imshow("<2>原图", srcImage3);

    namedWindow("<3>线性混合效果图");
    imshow("<3>线性混合示效果图", dstImage);

    waitKey();
	return 0;
}

Picture 1 and Picture 2 Original picture ( two pictures must be the same size)
here is a screenshot picture, the size may be different, it will not run

If you download less than two identical pictures, you can refer to this link to change any size
https://blog.csdn.net/m0_51233386/article/details/112393204 .
Insert picture description here
Insert picture description here

Figure 3 renderings
Insert picture description here

Three, ROI and addWeighted combined with image blending operation

ROI (region of interest) region of interest, in the image processing process, sometimes we want to process certain regions in the image, that is, only interested in certain regions, then the ROI and addWeighted function are used in combination. Specify the area to perform image blending operations.

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;

int main()
{
	//-----------------------------------【一、初级图像混合】--------------------------------------
	//	描述:二、初级图像混合
	//--------------------------------------------------------------------------------------------------
	//载入图片
	Mat image = imread("49.jpg");
	Mat logo = imread("61.jpg");

	// 定义一个Mat类型,用于存放,图像的ROI
	Mat imageROI;
	//方法一
	imageROI = image(Rect(300, 80, logo.cols, logo.rows));
	//方法二
	//imageROI= image(Range(320,320+logo.rows),Range(120,120+logo.cols));

	// 将logo加到原图上
	//【3】将logo加到原图上  ,利用线性混合构建掩膜,其中logo权重是0.8,原图中的ROI区域图像是0.2
	addWeighted(imageROI, 1, logo, 0.5, 0, imageROI);

	//显示结果
	namedWindow("【3】49");
	imshow("【3】49+61", image);

	//-----------------------------------【二、图像的输出】--------------------------------------
	//	描述:将一个Mat图像输出到图像文件
	//-----------------------------------------------------------------------------------------------
	//输出一张jpg图片到工程目录下
	imwrite("由imwrite生成的图片.jpg", image);

	waitKey();

	return 0;
}

The following is the overlay effect

On the basis of this method and method one ROI overlay method, the image overlay weight is added
Insert picture description here

Four, direct addition (non-linear)

函数为 add()
示例:add(src1, src2, dst_add);

Code implementation and effect

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;

int Add() {
Mat src1, src2, dst_add;

add(src1, src2, dst_add);
//叠加函数图像的函数
imshow("src1", src1);
imshow("src2", src2);
imshow("dst_add", dst_add);
waitKey();

return 0;

}

int main()
{ Add(); //Image overlay

return 0;

}
Insert picture description here
Insert picture description here
Superimposition effect
Insert picture description here
// method of reading in image

//Read in image method one

src1 = imread("67.jpg");
src2 = imread("68.jpg");

//Read in image method two

const char* filename1 = "67.jpg";
const char* filename2 = "68.jpg";

imread(filename1).copyTo(src1);
if (src1.empty()) {
    throw("Faild open file.");
}
imread(filename2).copyTo(src2);
if (src2.empty()) {
    throw("Faild open file.");
}

Guess you like

Origin blog.csdn.net/m0_51233386/article/details/113829240