【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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章