一、算法概述
1、邏輯運算
OpenCV4 針對兩個圖像之間的“與”、“或”、“異或”、以及“非”運算分别提供了
bitwise_and()
、
bitwise_or()
、
bitwise_xor()
、
bitwise_not()
函數。圖像像素間的邏輯運算與數字間的邏輯運算相同,具體規則見表1。圖像的“非”運算隻針對一個數值進行,是以在表1中對像素求非運算時對圖像1的像素進行“非”運算。如果像素取值隻有0和1,那麼表1中的前4行資料正好對應了所有的運算規則,但是
CV_8U
類型的圖像像素值從0取到255,此時的邏輯運算就需要将像素值轉成二進制後再進行,是以
CV_8U
類型是8位資料,對0求非是11111111,也就是255.在表1的最後一行資料中,像素5對應的二進制為101,像素值6對應的二進制是110,是以“與”運算得100(4),“或”運算得011(3),對像素5進行非運算得11111010(250)。
表1 圖像邏輯運算規則
圖像資料類型 | 像素值1 | 像素值2 | 與 | 或 | 異或 | 非(圖像) |
---|---|---|---|---|---|---|
二值 | 1 | |||||
二值 | 1 | 1 | 1 | |||
二值 | 1 | 1 | 1 | 1 | ||
二值 | 1 | 1 | 1 | 1 | ||
8位 | 255 | |||||
8位 | 5 | 6 | 4 | 7 | 3 | 250 |
2、函數解析
//像素求“與”運算
void bitwise_and(InputArray src1,
InputArray src2,
OutputArray dst,
InputArray mask = noArray());
//像素求“或”運算
void bitwise_or(InputArray src1,
InputArray src2,
OutputArray dst,
InputArray mask = noArray());
//像素求“異或”運算
void bitwise_xor(InputArray src1,
InputArray src2,
OutputArray dst,
InputArray mask = noArray());
//像素求“非”運算
void bitwise_not(InputArray src,
OutputArray dst,
InputArray mask = noArray());
-
:第一個圖像矩陣,可以是多通道圖像資料。src1
-
:第二個圖像矩陣,尺寸、通道數和資料類型都需要與src2
一緻。src1
-
:邏輯運算輸出結果,尺寸、通道數和資料類型都與dst
一緻。src1
-
:掩膜,用于設定圖像或矩陣中邏輯運算的範圍。mask
在進行邏輯運算時,一定要保證兩個兩個圖像矩陣之間的尺寸、資料類型和通道數相同,多個通道進行邏輯運算時不同通道之間是獨立運作的。
3、用途
按位運算的用途:比如要得到一個加logo的圖像。如果将兩幅圖檔直接相加會改變圖檔的顔色,如果用圖像混合,則會改變圖檔的透明度,這時候就需要用按位操作,既不改變圖像顔色,又不改變圖像透明度,類似PS。
二、代碼實作
#include <opencv2\opencv.hpp>
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
Mat img = imread("X8.jpg");
if (img.empty())
{
cout << "請确認圖像檔案名稱是否正确" << endl;
return -1;
}
//1、建立兩個黑白圖像
Mat img0 = Mat::zeros(200, 200, CV_8UC1);
Mat img1 = Mat::zeros(200, 200, CV_8UC1);
Rect rect0(50, 50, 100, 100);
img0(rect0) = Scalar(255);
Rect rect1(100, 100, 100, 100);
img1(rect1) = Scalar(255);
imshow("img0", img0);
imshow("img1", img1);
//-----------------------------------------------------------------
// 在進行邏輯運算時,一定要保證兩個兩個圖像矩陣之間的尺寸、資料類型
// 和通道數相同,多個通道進行邏輯運算時不同通道之間是獨立運作的。
//-----------------------------------------------------------------
//2、進行邏輯運算
Mat myAnd, myOr, myXor, myNot, imgNot;
bitwise_not(img0, myNot); // 邏輯“非”運算
bitwise_and(img0, img1, myAnd); // 邏輯“與”運算
bitwise_or(img0, img1, myOr); // 邏輯“或”運算
bitwise_xor(img0, img1, myXor); // 邏輯“異或”運算
bitwise_not(img, imgNot); // 邏輯“非”運算
imshow("myAnd", myAnd);
imshow("myOr", myOr);
imshow("myXor", myXor);
imshow("myNot", myNot);
imshow("img", img);
imshow("imgNot", imgNot);
waitKey(0);
return 0;
}