opencv學習(八)之ROI區域和影象混合疊加
阿新 • • 發佈:2019-02-16
1.影象線性混合疊加
在進行影象處理時,opencv中提供了addWeighted()實現對兩幅影象的疊加。這是一種線性混合操作,其公式如下:
通過改變a的值,可以實現兩幅影象或視訊進行混合時出現不同的效果。
其函式定義如下:
CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2,
double beta, double gamma, OutputArray dst, int dtype=-1);
詳細引數說明如下:
src1: 第一幅輸入影象
alpha: 線性混合時第一幅影象的權重
src2: 第二幅輸入影象
beta: 第二幅輸入影象的權重
dst: 影象線性混合後的目標影象
gamma: 新增到每一個線性疊加總和的gamma值
dtype: 目標影象深度,當兩幅影象深度相同時可以將dtype置為-1,這樣目標影象的深度將與輸入影象相同
其中beta - (1.0 - alpha);
對於每個畫素點其計算公式如下:
示例程式碼如下:
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage1 = imread("forest.jpg");
Mat srcImage2 = imread("rain.jpg");
Mat dstImage;
//檢查檔案是否載入成功
if(srcImage1.empty() || srcImage2.empty())
{
cout << "影象載入失敗!" << endl << endl;
return -1;
}
else
cout << "影象載入成功!" << endl << endl;
double alpha = 0.5;
double beta;
double input;
cout << "Please Input alpha[0-1]: " ;
cin >> input;
//判斷輸入的alpha是否符合要求
if(input >= 0.0 && input <= 1.0)
{
alpha = input;
}
namedWindow("線性混合", WINDOW_NORMAL);
beta = (1.0 - alpha);
addWeighted(srcImage1, alpha, srcImage2, beta, 0.0, dstImage);
imshow("線性混合", dstImage);
namedWindow("srcImage1",WINDOW_NORMAL);
imshow("srcImage1",srcImage1);
namedWindow("srcImage2",WINDOW_NORMAL);
imshow("srcImage2",srcImage2);
waitKey(0);
return 0;
}
執行結果如下所示:
該執行結果輸入值為0.5.
注意:兩幅影象混合時必須要求兩幅影象的尺寸和型別完全相同。
通過對影象設定ROI區域可以實現不同尺寸影象的混合。
在進行影象處理時,常常需要設定感興趣區域(ROI, region of interest),可以在影象任意位置建立ROI區域,設定ROI區域後可以更有針對性的進行下一步處理。
定義ROI有兩種方法(假定都從影象左上角(100,100)的位置劃定ROI):
第一種是使用表示矩形區域的Rect。它指定矩形的左上角座標和矩形的長寬來劃定ROI區域。
ROIImage = srcImage(Rect(100,100,smallImage.cols,smallImage.rows));
第二種方法是使用Range()指定感興趣區域的行或列的範圍。Range()指定的區域是一個連續的儲存序列。
ROIImage = srcImage(Range(100,smallImage.rows),Range(100,smallImage.cols));
示例程式碼如下:
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage = imread("space.jpg");
Mat addImage = imread("astronautB.jpg");
//判斷檔案是否載入成功
if(srcImage.data && addImage.data)
cout << "影象載入成功!" << endl << endl;
else
{
cout << "影象載入失敗!" << endl << endl;
return -1;
}
imshow("srcImage",srcImage);
imshow("astronaut",addImage);
//設定srcImage感興趣區域
//第一種方式,使用Rect()函式設定ROI
Mat imageROI = srcImage(Rect(50,50,addImage.cols,addImage.rows));
addWeighted(imageROI,0.7,addImage,0.3,0,imageROI);
imshow("混合後圖像",srcImage);
waitKey(0);
return 0;
}
其執行結果如下所示:
還可以利用copyTo()通過影象掩模板直接將影象複製到ROI區域。但是這種方法要求maskImage必須是灰度圖。示例程式碼如下:
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage = imread("space.jpg");
Mat addImage = imread("astronautB.jpg");
Mat maskImage = imread("astronautB.jpg",IMREAD_GRAYSCALE); //載入其灰度圖
//判斷檔案是否載入成功
if(srcImage.data && addImage.data)
cout << "影象載入成功!" << endl << endl;
else
{
cout << "影象載入失敗!" << endl << endl;
return -1;
}
//以第二種方式Range()函式設定其ROI區域
Mat imageROI = srcImage(Range(50,50+maskImage.rows), Range(50,50+maskImage.cols));
addImage.copyTo(imageROI,maskImage);
imshow("混合後圖像",srcImage);
waitKey(0);
return 0;
}
執行結果如下: