目錄
前言
要說這加減乘除,大家肯定不陌生,從小學學數學開始,我們就接觸了這四個基本的四則運算。那圖像的加減乘除又是什麼呢?它能實現什麼樣的效果呢?讓我們走進今天的文章,來學習一下吧!
一、加
1、介紹
我們從加說起:
加實現了計算兩個數組或一個數組和一個scalar的每個元素的和的功能。
輸入數組和輸出數組都可以具有相同或不同的深度。例如,可以將16位無符號數組添加到8位有符號數組,並將總和存儲爲32位浮點數組。輸出數組的深度由dtype參數確定。在上面的第二和第三種情況下,以及在第一種情況下,當兩個輸入圖像的深度相同時,可以將dtype設置爲默認值-1。這時候,輸出圖像和輸入圖像的深入相同。
2、API
加的API如下:
void add(InputArray src1,
InputArray src2,
OutputArray dst,
InputArray mask = noArray(),
int dtype = -1
);
具體的參數如下:
(1)InputArray類型的src1 ,第一個輸入數組或scalar。
(2)InputArray類型的src2 ,第二個輸入數組或scalar。
(3)OutputArray類型的dst ,輸出圖像,圖像的尺寸、通道數和輸入圖像相同。
(4)InputArray類型的mask,可選操作掩碼-8位單通道數組,指定要更改的輸出數組元素。
(5)int類型的dtype,輸出數組的可選深度。
3、代碼實戰
我們使用兩個圖像來做一下實戰。
Mat ZWJ = imread("./image/YT_ZWJ1.png");
Mat ZM = imread("./image/YT_ZM1.png");
if (!ZWJ.data && !ZM.data)
{
cout << "ERROR : could not load image.\n";
return -1;
}
imshow("張無忌", ZWJ);
imshow("趙敏", ZM);
Mat YT_new;
add(ZWJ, ZM, YT_new);
imshow("倚天屠龍記-add", YT_new);
得到的結果如下,左邊的兩幅圖是原圖,後面的圖是利用前兩幅圖加得到的。
我想大家應該還記得我們之前講到的圖像混合,如果我們使用圖像混合得到的結果是什麼樣的呢?
二、減
1、介紹
講完加,自然就應該說一下減:
減實現了計算兩個數組或一個數組和一個scalar的每個元素的差的功能。
減法和加法只是加減運算不同,其他都是一樣的。讓我們走進API看一下吧
2、API
減的API如下:
void subtract(InputArray src1,
InputArray src2,
OutputArray dst,
InputArray mask = noArray(),
int dtype = -1
);
具體的參數如下:
(1)InputArray類型的src1 ,第一個輸入數組或scalar。
(2)InputArray類型的src2 ,第二個輸入數組或scalar。
(3)OutputArray類型的dst ,輸出圖像,圖像的尺寸、通道數和輸入圖像相同。
(4)InputArray類型的mask,可選操作掩碼-8位單通道數組,指定要更改的輸出數組元素。
(5)int類型的dtype,輸出數組的可選深度。
3、代碼實戰
我們使用兩個圖像來做一下實戰。
Mat ZWJ = imread("./image/YT_ZWJ1.png");
Mat ZM = imread("./image/YT_ZM1.png");
if (!ZWJ.data && !ZM.data)
{
cout << "ERROR : could not load image.\n";
return -1;
}
imshow("張無忌", ZWJ);
imshow("趙敏", ZM);
Mat YT_new;
subtract(ZWJ, ZM, YT_new);
imshow("倚天屠龍記-subtract", YT_new);
得到的結果如下,左邊的兩幅圖是原圖,後面的圖是利用前兩幅圖加得到的。
因爲後面的圖片是被減的,所以在最終圖像上,會取反(255減原值)。
三、乘
1、介紹
第三個要說明的是乘:
乘實現了計算兩個數組的按元素縮放的乘積的功能。
兩個數組相乘,對應位置上的元素相乘,得到該位置上的值。
2、API
乘的API如下:
void multiply(InputArray src1,
InputArray src2,
OutputArray dst,
double scale = 1,
int dtype = -1
);
具體的參數如下:
(1)InputArray類型的src1 ,第一個輸入數組或scalar。
(2)InputArray類型的src2 ,第二個輸入數組或scalar,尺寸和類型要與src1一致。
(3)OutputArray類型的dst ,輸出圖像,尺寸和類型要與src1一致。
(4)double類型的scale,可選比例因子。
(5)int類型的dtype,輸出數組的可選深度。
3、代碼實戰
我們使用兩個圖像來做一下實戰。
Mat ZWJ = imread("./image/YT_ZWJ1.png");
Mat ZM = imread("./image/YT_ZM1.png");
if (!ZWJ.data && !ZM.data)
{
cout << "ERROR : could not load image.\n";
return -1;
}
imshow("張無忌", ZWJ);
imshow("趙敏", ZM);
Mat YT_new;
multiply(ZWJ, ZM, YT_new, 0.05);
imshow("倚天屠龍記-multiply", YT_new);
得到的結果如下,左邊的兩幅圖是原圖,後面的圖是利用前兩幅圖加得到的。
大家能夠發現,我們使用了一個較小的比例因子,這是因爲圖像中最大的像素爲255,而一幅圖像中很常見像素值比較大,相乘就會超過255,最後導致整個圖像就是幾乎全白的,沒有太大研究的意義,所以我們要添加一個比例因子,讓其按比例縮放,就能看到更加真實的效果了。
四、除
1、介紹
最後要講的就是除:
除實現了計算執行兩個數組或標量按數組的每個元素的除法的功能。
在除中,要考慮的問題如下:
首先,除法可能是一個float數據和Mat的除,這個時候,計算的是float和Mat中每個數值的除;如果是兩個Mat除,那就是對應位置做除法。
其次,除數Mat中可能會存在0,這個位置求出的值直接取零。
根據上面第一點,我們就能知道,有兩種計算情況,那在實現中,會有兩個除函數。
2、API
除的API如下:
void divide(InputArray src1,
InputArray src2,
OutputArray dst,
double scale = 1,
int dtype = -1
);
void divide(double scale,
InputArray src2,
OutputArray dst,
int dtype = -1
);
具體的參數如下:
(1)InputArray類型的src1 ,第一個輸入數組或scalar。
(2)InputArray類型的src2 ,第二個輸入數組或scalar,尺寸和類型要與src1一致。
(3)OutputArray類型的dst ,輸出圖像,尺寸和類型要與src1一致。
(4)double類型的scale,scalar因子。
(5)int類型的dtype,輸出數組的可選深度。
3、代碼實戰
我們使用兩個圖像來做一下實戰。
Mat ZWJ = imread("./image/YT_ZWJ1.png");
Mat ZM = imread("./image/YT_ZM1.png");
if (!ZWJ.data && !ZM.data)
{
cout << "ERROR : could not load image.\n";
return -1;
}
imshow("張無忌", ZWJ);
imshow("趙敏", ZM);
Mat YT_new;
divide(ZWJ, ZM, YT_new,100);
imshow("倚天屠龍記-divide", YT_new);
divide(10000, ZWJ, YT_new);
imshow("張無忌-divide", YT_new);
divide(10000, ZM, YT_new);
imshow("趙敏-divide", YT_new);
得到的結果如下:
五、原圖與掩膜圖像的加減乘除
如果我們有一幅圖像,我們先做掩膜操作,然後計算原圖像與其掩膜圖像的加減乘除,看一下效果吧!
Mat YT = imread("./image/YiTian1.jpg");
if (!YT.data)
{
cout << "ERROR : could not load image.\n";
return -1;
}
imshow("倚天屠龍記", YT);
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0,
-1, 5, -1,
0, -1, 0);
Mat YT_mask;
filter2D(YT, YT_mask, YT.depth(), kernel);
imshow("倚天屠龍記-mask", YT_mask);
Mat YT_new;
add(YT, YT_mask, YT_new);
imshow("倚天屠龍記-add", YT_new);
subtract(YT, YT_mask, YT_new);
imshow("倚天屠龍記-subtract", YT_new);
multiply(YT, YT_mask, YT_new, 0.01);
imshow("倚天屠龍記-multiply", YT_new);
divide(YT, YT_mask, YT_new, 100);
imshow("倚天屠龍記-divide", YT_new);
得到的結果如下。