【OpenCV学习笔记】2.1图像混合和叠加

一、建立感兴趣域

ROI = Region of Interest

从图像中选择一个图像区域,这个区域是我们图像分析所关注的重点。我们圈定这个区域,以便进行进一步处理。

  • 方法一:  Mat imageROI = image(Range(行的范围),Range(列的范围))
  • 方法二:  Mat imageROI = image(Rect(y,x,列距,行距))   注意是列位置在前!

由于Mat的内存机制,我们改变该ROI域,也就改变了原来的图片image


二、基本图像混合

函数 addWeighted

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

各参数解释:

alpha (α) 表示scr1的权值
beta  (β) 表示scr2的权值
gamma (γ) 一个加到权重总和上的标量值

dst=src1α+src2β+γ

dtype,输出阵列的可选深度,默认值-1

α+β=1 时,为线性混合:

g(x)=(1α)f0(x)+αf1(x)


三、图像拷贝

1、函数copyTo

  • src.copyTo(dst)
  • src.copyTo(dst, mask)

    将src复制到dst中

掩码mask的作用:

mask必须为单通道图像

函数会检测mask中相应位置是否为0,如果不为0是会把输入Mat相应位置的值直接复制到输出中的,但是,如果mask中相应位置为0,copyMask函数会不理它,让它维持原值输出。

对于透明图像的叠加很有用处

2、函数clone

对比三种图像拷贝方法的效果

借鉴于http://blog.csdn.net/thefutureisour/article/details/7472104

Mat result = image;  
//result = image.clone();     
//image.copyTo(result);  

使用三种方法将result与图像image关联:
第一种是是用“=”,第二种是用copyTo,第三种使用clone

对image的滤波后可以发现:

  • 当使用“=”时,会导致result的图像改变;
  • 而使用clone或者copyTo不会引起result的改变。

原因是什么呢?

  1. 因为使用“=”时,并没有复制新的数据,而只是让result指向image。它们指向的是内存中的同一份数据。等号操作以后,image的引用计数+1而已。这就是所谓的“浅拷贝”;
  2. 而copyTo则是把矩阵的每个元素都重新拷贝给了result。
  3. clone不仅拷贝了矩阵元素值,还复制了矩阵的一些其他信息。它们是所谓的“深拷贝”。

四、实例

借鉴于http://blog.csdn.net/poem_qianmo/article/details/20911629

#include <opencv2\opencv.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>

using namespace cv;

int main(){
    Mat img = imread("20140224111440937.jpg");
    namedWindow("【1】游戏原画");
    // 在窗口中显示游戏原画  
    imshow("【1】游戏原画", img);

    Mat image = imread("dota.jpg", 199);
    Mat logo = imread("dota_logo.jpg");
    namedWindow("【2】原画图");
    imshow("【2】原画图", image);
    namedWindow("【3】logo图");
    imshow("【3】logo图", logo);

    Mat imageROI;
    //imageROI = image(Range(350, 350 + logo.rows), Range(800, 800 + logo.cols));//行的范围,列的范围
    imageROI = image(Rect(800, 350, logo.cols, logo.rows));

    //三种方法的试验:
    //imageROI=logo;            //不成功,指向了logo
    logo.copyTo(imageROI);      //成功
    //imageROI = logo.clone();  //不成功,重新开辟内存对logo拷贝了矩阵元素值,还复制了矩阵的一些其他信息

    //addWeighted(imageROI, 0.7, logo,0.1,0.0,imageROI);     //图像加权混合
    imshow("【4】图像混合", image);

    waitKey(6000);
    return 0;
}


五、多通道混合

函数:split(),merge()

#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<vector>

using namespace cv;
using namespace std;

int main(){
    Mat logo = imread("20140305153622171.png", 0);//灰度图像
    Mat img = imread("20140310123950218.png");
    namedWindow("[1]原图");
    imshow("[1]原图",img);
    namedWindow("[2]logo");
    imshow("[2]logo", logo);

    vector<Mat> channels;
    split(img, channels);//将img分成3通道
    Mat Green = channels.at(1);//取绿色分量 Green指向channels
    Mat imgROI = Green(Rect(0, 0, logo.cols, logo.rows));   //imgROI也指向channels
    addWeighted(imgROI, 1.0, logo, 0.5, 0.0, imgROI);//2张图片通道数一定要一样

    merge(channels, img);   //merge回来,否则所做的改变并不在img上
    namedWindow("[2]绿色logo");
    imshow("[2]绿色logo", img);
    waitKey(6000);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章