文中內(nèi)容大多來(lái)自大神淺墨_毛星云 所著【OpenCV3編程入門】,在此基礎(chǔ)上加入了自己的理解和補(bǔ)充內(nèi)容。
本節(jié)中主要是ROI(region of interest) 感興趣區(qū)域以及 addWeighted函數(shù)實(shí)現(xiàn)圖像混合操作
ROI
從圖像中圈定一塊區(qū)域,作為圖像分析的重點(diǎn),節(jié)省處理時(shí)間增加精度。主要有兩種方式實(shí)現(xiàn):
/**
* ROI region of interest 感興趣區(qū)域
* 圖像混合操作
*/
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
void ROI_AddImage();
void LinearBlending();
void ROI_LinearBlending();
int main() {
ROI_AddImage();
LinearBlending();
ROI_LinearBlending();
waitKey(0);
return 0;
}
/**
*掩膜實(shí)現(xiàn)ROI圖像
*/
void ROI_AddImage() {
//讀入圖像
Mat srcImage = imread("/Users/*/Pictures/timg.jpeg");
Mat logoImage = imread("/Users/*/Pictures/img/OnePiece.png");
if (!srcImage.data) {
printf("讀取srcImage錯(cuò)誤\n");
return;
}
if (!logoImage.data) {
printf("讀取logoImage錯(cuò)誤\n");
return;
}
//定義一個(gè)Mat類型并給其設(shè)定ROI區(qū)域 矩形左上角坐標(biāo)+長(zhǎng)寬
//error:libc++abi.dylib: terminating with uncaught exception of type cv::Exception: OpenCV(4.3.0) /Users/ing/opencv-4.3.0/modules/core/src/matrix.cpp:466: error: (-215:Assertion failed) 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows in function 'Mat'
Mat imageROI = srcImage(Rect(10, 10, logoImage.cols, logoImage.rows));
//加載掩膜(0 表示必須是單通道灰度圖)
Mat mask = imread("/Users/*/Pictures/img/OnePiece.png", 0);
//將掩膜復(fù)制到ROI
logoImage.copyTo(imageROI, mask);
//顯示結(jié)果
namedWindow("利用ROI實(shí)現(xiàn)圖像疊加示例窗口");
imshow("利用ROI實(shí)現(xiàn)圖像疊加示例窗口", srcImage);
}
/**
* 線性混合
*/
void LinearBlending() {
//定義一些局部變量
double alphaValue = 0.5;
double betaValue;
Mat srcImage1, srcImage2, dstImage;
//讀取圖像--【兩幅圖片必須為同樣的類型和尺寸】
srcImage2 = imread("/Users/*/Pictures/sea.jpeg");
srcImage1 = imread("/Users/*/Pictures/flower.jpeg");
if (!srcImage1.data) {
printf("讀取srcImage3錯(cuò)誤\n");
return;
}
if (!srcImage2.data) {
printf("讀取srcImage2錯(cuò)誤\n");
return;
}
//做圖像混合加權(quán)操作
betaValue = (1.0 - alphaValue);
addWeighted(srcImage1, alphaValue, srcImage2, betaValue, 0.0, dstImage);
//創(chuàng)建并顯示原圖窗口
namedWindow("線性混合示例窗口[原圖]", 1);
imshow("線性混合示例窗口[原圖]", srcImage1);
namedWindow("線性混合示例窗口[效果圖]", 1);
imshow("線性混合示例窗口[效果圖]", dstImage);
}
/**
* ROI區(qū)域圖像疊加&圖像混合
*/
void ROI_LinearBlending() {
Mat srcImage = imread("/Users/*/Pictures/timg.jpeg");
Mat logoImage = imread("/Users/*/Pictures/img/OnePiece.png");
if (!srcImage.data) {
printf("讀取srcImage錯(cuò)誤\n");
}
if (!logoImage.data) {
printf("讀取logoImage錯(cuò)誤\n");
}
Mat imageROI;
//方法一
imageROI = srcImage(Rect(10, 10, logoImage.cols, logoImage.rows));
//方法二
//imageROI= srcImage(Range(10,10+logoImage.rows),Range(10,10+logoImage.cols));
//將logo加到原圖上
addWeighted(imageROI, 0.8, logoImage, 0.2, 0.0, imageROI);
namedWindow("區(qū)域線性圖像混合示例窗口", 1);
imshow("區(qū)域線性圖像混合示例窗口", srcImage);
}
對(duì)應(yīng)的三種運(yùn)行結(jié)果:



補(bǔ)充:
圖像加權(quán)和,就是在計(jì)算兩幅圖像的像素值之和時(shí),將每幅圖像的權(quán)重考慮進(jìn)來(lái),可以用公式表示為
dst= saturate(srcl * α + src2 * β + γ)
式中, saturate(表示取飽和值(最大值)。圖像進(jìn)行加權(quán)和計(jì)算時(shí),要求 srcl和 src2 必須大小,類型相同,但是對(duì)具體是什么類型和通道沒(méi)有特殊限制,它們可以是任意數(shù)據(jù)類型,也可以有任意數(shù)量的通道(灰度圖像或者彩色圖像),只要二者相同即可
OpenCv 中提供了函數(shù) cv2.addWeighted,用來(lái)實(shí)現(xiàn)圖像的加權(quán)和(混合、融合),該函數(shù)的語(yǔ)法格式為
dst=cv2.addWeighted(srcl,alpha,src2,beta, gamma)
參數(shù) alpha和 beta是 srcl 和 src2所對(duì)應(yīng)的系數(shù),它們的和可以等于 1,也可以不等于1
函數(shù)實(shí)現(xiàn)的功能是 dst= srcl * alpha+src2 * beta +gamma 需要注意,式中參數(shù) gamma 的值
可以是0 但是該參數(shù)是必選參數(shù),不能省略。
可以將上式理解為
“結(jié)果圖像=圖像 1×系數(shù)1+圖像2×系數(shù)2+ 亮度調(diào)節(jié)量”