一、建立感興趣域
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
當
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的改變。
原因是什麼呢?
- 因爲使用“=”時,並沒有複製新的數據,而只是讓result指向image。它們指向的是內存中的同一份數據。等號操作以後,image的引用計數+1而已。這就是所謂的“淺拷貝”;
- 而copyTo則是把矩陣的每個元素都重新拷貝給了result。
- 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;
}