《OpenCV3学习笔记》2.1 core模块 :ROI、addWeighted、split、merge

一:内容介绍

本节主要介绍

1、定义感兴趣区域ROI

2、addWeighted函数进行图像线性混合。

3、RGB三通道分别显示,split函数

4、合并成一个多通道的数组,merge函数

二、具体介绍

1、ROI区域定义的两种方法

cv::Rect表示一个矩形区域。指定矩形的左上角坐标(构造函数的前两个参数)和矩形的长宽(构造函数的后两个参数)就可以定义一个矩形区域。

另一种定义ROI的方式是指定感兴趣行或列的范围(Range)

Mat imageROI;
//方法一
imageROI=image(Rect(500,250,logo.cols,logo.rows));
//方法二
imageROI=srcImage3(Range(250,250+logoImage.rows),Range(200,200+logoImage.cols));
#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int main() 
{
	Mat srcImage = imread("dota.png");
	Mat logoImage = imread("logo.png");
	//ROI区域
	Mat imageROI = srcImage(Rect(200, 250, logoImage.cols, logoImage.rows));
	//掩摸为单通道即可
	Mat mask = imread("logo.png",0);
	//将掩膜拷贝到ROI
	logoImage.copyTo(imageROI, mask);
	imshow("【利用ROI实现图像叠加示例窗口】", srcImage);

	waitKey();
	return 0;
}

2、addWeighted函数

     dst = src1[I]*alpha+ src2[I]*beta + gamma;

    其中,src1和src2有相同的尺寸和通道数。

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

	double alphaValue = 0.5;
	double betaValue = (1.0 - alphaValue);
	Mat srcImage2, srcImage3, dstImage;

	//【1】读取图像 ( 两幅图片需为同样的类型和尺寸 )
	srcImage2 = imread("dota.png");
	srcImage3 = imread("logo.png");
	//【2】进行图像混合加权操作
	addWeighted(srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);
	//【3】创建并显示原图窗口
	imshow("<3>线性混合示例窗口【效果图】 by浅墨", dstImage);

3、split函数

将一个多通道数组分离成几个单通道数组。有两种形式。

C++: void split(const Mat& src, Mat*mvbegin);
C++: void split(InputArray m,OutputArrayOfArrays mv);
  • 第一个参数,InputArray类型的m或者const Mat&类型的src,填我们需要进行分离的多通道数组
  • 第二个参数,输出数组,必须与src.channels()相匹配。
 char d[] = {1,2,3,4,5,6,7,8,9,10,11,12};
 Mat m(2, 2, CV_8UC3, d);

 Mat imageBlueChannel;
 Mat imageGreenChannel;
 Mat imageRedChannel;
//或者vector<Mat> channels;
      Mat channels[3]; 
 //第一个参数是Mat数组,第二个参数是指针数组
 split(m, channels);

 imageBlueChannel = channels.at(0);
 imageGreenChannel = channels.at(1);
 imageRedChannel = channels.at(2);

 /*
    channels[0] =
    [  1,   4;
       7,  10]
    channels[1] =
    [  2,   5;
       8,  11]
    channels[2] =
    [  3,   6;
       9,  12]
    */

4、merge函数

创建出一个由多个单通道阵列组成的多通道阵列

C++: void merge(const Mat* mv, size_tcount, OutputArray dst)
C++: void merge(InputArrayOfArrays mv,OutputArray dst)
  • 第一个参数,mv,填需要被合并的输入矩阵,这个mv参数中所有的矩阵必须有着一样的尺寸和深度。
  • 第二个参数,count,当mv为一个空白的C数组时,代表输入矩阵的个数
  • 第三个参数,dst,即输出矩阵,和mv[0]拥有一样的尺寸和深度,并且通道的数量是矩阵阵列中的通道的总数。
    Mat m1 = (Mat_<uchar>(2,2) << 1,4,7,10);
    Mat m2 = (Mat_<uchar>(2,2) << 2,5,8,11);
    Mat m3 = (Mat_<uchar>(2,2) << 3,6,9,12);
    Mat channels[3] = {m1, m2, m3};
    Mat m;

    merge(channels, 3, m);
   /*
    m =
    [  1,   2,   3,   4,   5,   6;
       7,   8,   9,  10,  11,  12]
    m.channels() = 3
    */

综合实例

先用split()分离通道,然后在单通道上使用addWeighted()叠加,最后再使用merge()将各通道合并。

#include<opencv2/opencv.hpp>
#include<iostream>
#include <vector>

using namespace cv;
using namespace std;

bool multichannelblending();

int main() 
{

	if (multichannelblending())
	{
		cout << endl << "得出了你需要混合的图像了";
	}

	waitKey();
	return 0;

}

bool multichannelblending()
{
	//声明变量
	Mat image;
	Mat logo;
	Mat imagebluechannel;
	vector<Mat> channels;//!!!!通道
	//读入图像
	image = imread("dota.png");
	logo = imread("logo.png", 0);
	//3通道图像转换成3个单通道图像split
	split(image, channels);
	//蓝色通道
	imagebluechannel = channels.at(0);
	//addweight
	addWeighted(imagebluechannel(Rect(500, 250, logo.cols, logo.rows)), 1.0,
		logo, 0.5, 0., imagebluechannel(Rect(500, 250, logo.cols, logo.rows)));

	//合并成一个通道merge
	merge(channels, image);
	//显示
	imshow("<1>游戏原画+logo蓝色通道 by浅墨", image);

	return true;

}

猜你喜欢

转载自blog.csdn.net/try_again_later/article/details/81477364