OpenCV中圖像算術操作與邏輯操作
在圖像處理中有兩類最重要的基礎操作分別是圖像點操作與塊操作,簡單點說圖像點操作就是圖像每個像素點的相關邏輯與幾何運算、塊操作最常見就是基於卷積算子的各種操作、實現各種不同的功能。今天小編就跟大家一起學習OpenCV中圖像點操作相關的函數與應用場景。常見算術運算包括加、減、乘、除,邏輯運算包括與、或、非、異或。準備工作:
選擇兩張大小一致的圖像如下、加載成功以後顯示如下:
加法操作結果如下:
減法操作結果如下:
乘法操作結果如下:
除法操作結果如下:
權重加法操作結果如下:
異或與非操作結果如下:
代碼如下:
Mat src1, src2, dst;
src1 = imread("D:/vcprojects/images/test1.png");
src2 = imread("D:/vcprojects/images/moon.png");
const char* input_title1 = "input image - 1";
const char* input_title2 = "input image - 2";
namedWindow(input_title1, CV_WINDOW_AUTOSIZE);
namedWindow(input_title2, CV_WINDOW_AUTOSIZE);
imshow(input_title1, src1);
imshow(input_title2, src2);
// create result windows and background image
const char* output_title = "result image";
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
Mat bgImg = Mat(src1.size(), src1.type());
Mat whiteImg = Mat(src1.size(), src1.type());
whiteImg = Scalar(255, 255, 255);
// 臨時圖像
Mat skel(src1.size(), CV_8UC1, Scalar(0));
Mat temp(src1.size(), CV_8UC1);
Mat element = getStructuringElement(MORPH_CROSS, Size(3, 3), Point(-1, -1));
bool done = false;
int index = 9, c;
while (true) {
switch (index) {
case 1:
// 加操作
add(src1, src2, dst, Mat(), -1);
imshow(output_title, dst);
break;
case 2:
// 減操作
subtract(src1, src2, dst, Mat(), -1);
imshow(output_title, dst);
break;
case 3:
// 乘操作
bgImg = Scalar(2, 2, 2);
multiply(src1, bgImg, dst, 1.0, -1);
imshow(output_title, dst);
break;
case 4:
// 除操作
bgImg = Scalar(2, 2, 2);
divide(src1, bgImg, dst, 1.0, -1);
imshow(output_title, dst);
break;
case 5:
// 基於權重加法 - 調節亮度
addWeighted(src1, 1.5, src2, 0.5, 0, dst, -1);
imshow(output_title, dst);
break;
case 6:
// 邏輯非
bitwise_not(src1, dst, Mat());
imshow(output_title, dst);
break;
case 7:
subtract(whiteImg, src1, dst, Mat(), -1);
imshow(output_title, dst);
break;
case 8:
// 邏輯異或
bgImg = Scalar(255, 255, 255);
bitwise_xor(src1, bgImg, dst, Mat());
imshow(output_title, dst);
break;
default:
imshow(output_title, src2);
break;
}
c = waitKey(500);
if ((char)c == 27) {
break;
}
if(c > 0) {
index = c % 9;
}
}
此外我們還可以基於邏輯操作與形態學的腐蝕操作實現二值圖像的骨架提取,Demo演示結果如下:
代碼實現如下:
// 提取骨架
// 轉灰度與二值化
cvtColor(src1, src1, COLOR_BGR2GRAY);
threshold(src1, dst, 127, 255, CV_THRESH_BINARY);
//bitwise_not(src1, src1);
do {
// 開操作 - 確保去掉小的干擾塊
morphologyEx(src1, temp, MORPH_OPEN, element);
// 取反操作
bitwise_not(temp, temp);
// 得到與源圖像不同
bitwise_and(src1, temp, temp);
// 使用它提取骨架、得到是僅僅比源圖像小一個像素
bitwise_or(skel, temp, skel);
// 每次循環腐蝕,通過不斷腐蝕的方式得到框架
erode(src1, src1, element);
// 對腐蝕之後的圖像尋找最大值,如果被完全腐蝕則說明
// 只剩下背景黑色、已經得到骨架,退出循環
double max;
minMaxLoc(src1, 0, &max);
done = (0 == max);
} while (!done);
// 顯示骨架
imshow(output_title, skel);
總結:
通過上述代碼演示,可以發現簡單的圖像算術運算也可以發揮大作用,基於黑色背景圖像與原圖權重疊加可以實現圖像亮度調整、基於乘法可以實現對比度調整。基於邏輯操作與腐蝕操作可以實現二值圖像的骨架提取。