1. 程式人生 > >【OpenCV影象處理】三、影象的邏輯運算

【OpenCV影象處理】三、影象的邏輯運算

影象的邏輯運算就是將兩幅影象的對應畫素進行邏輯運算。邏輯運算主要包括 與(AND)或(OR)及補運算。要對灰度影象進行邏輯運算,就要首先對影象進行二值化處理。

影象的二值化處理在上一篇中已經敘述完畢,這篇主要寫影象的與,或和補三種邏輯運算。

在OpenCV中,除了本文中所提到的使用類似的函式進行影象的邏輯運算外,還可以直接使用邏輯運算子進行操作,例如在求兩個影象的或時,可以直接使用如下語句:

resultOr = (img1 | img2);
因為在Mat類中已經為我們過載了這些運算子。靈活的使用運算子可以給我們帶來很大的方便

在這裡再次感謝周師兄的提醒~ :D 

1.與運算

影象的與運算就是將兩幅二值影象的對應畫素進行邏輯與操作,如果處理的影象不是二值影象,那麼要先進行二值化處理。

可以用來求得兩幅尺寸相同的影象的相交區域。

使用OpenCV程式設計也十分簡單,將兩幅影象按畫素進行與操作即可。

相關程式碼如下:

//二值影象的邏輯與(AND)運算

#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>

using namespace std;
using namespace cv;

int main()
{
	Mat imag1, imag2, result;
	//imag1和imag2都是單通道的二值影象
	imag1 = imread("1234.jpg");
	imag2 = imread("2345.jpg");
	result = imag1.clone();
	//進行遍歷畫素即可
	int rowNumber = result.rows;
	int colNumber = result.cols;
	for (int i = 0; i < rowNumber; i++)
	{
		for (int j = 0; j < colNumber; j++)
		{
			result.at<uchar>(i,j) = imag1.at<uchar>(i,j)&& imag2.at<uchar>(i,j);
		}
	}
	imshow("原圖1", imag1);
	imshow("原圖2", imag2);
	imshow("邏輯與後的影象", result);
	waitKey();
	return 0;
}


2.或運算

或運算和與運算操作方法類似,只是將兩幅影象的對應畫素該位進行或運算即可,同樣的,如果處理的影象不是二值影象,則應該首先對影象進行二值化。

相關程式碼如下:

//二值影象的邏輯或(OR)運算

#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>

using namespace std;
using namespace cv;

int main()
{
	Mat imag1, imag2, result;
	//imag1和imag2都是單通道的二值影象
	imag1 = imread("1234.jpg");
	imag2 = imread("2345.jpg");
	result = imag1.clone();
	//進行遍歷畫素即可
	int rowNumber = result.rows;
	int colNumber = result.cols;
	for (int i = 0; i < rowNumber; i++)
	{
		for (int j = 0; j < colNumber; j++)
		{
			result.at<uchar>(i, j) = imag1.at<uchar>(i, j) || imag2.at<uchar>(i, j);
		}
	}
	imshow("原圖1", imag1);
	imshow("原圖2", imag2);
	imshow("邏輯與後的影象", result);
	waitKey();
	return 0;
}

3.補運算

補運算是對二值影象的每個畫素取邏輯非。同樣的如果處理的不是二值影象,也要先進行二值化處理。此外在OpenCV中對一幅二值化影象求補運算除了可以用按畫素求補外還可以直接使用求反的符號“~”,如“~imag1”就是對imag1進行求補操作

相關的實現程式碼如下:

//對二值影象進行求補運算

#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>

using namespace std;
using namespace cv;

int main()
{
	Mat imag, result1,result2;
	imag = imread("二值圖.jpg");
	result1 = result2 = imag.clone();
	result1 = ~imag;
	int rowNumber = result2.rows;
	int colNumber = result2.cols;
	for (int i = 0; i < rowNumber; i++)
	{
		for (int j = 0; j < colNumber; j++)
		{
			//求補操作
			result2.at<uchar>(i, j) = 255 - imag.at<uchar>(i, j);	
		}
	}
	imshow("原影象", imag);
	imshow("result1", result1);
	imshow("result2", result2);
	waitKey();
	return 0;
}

上面程式中採用了兩種方法進行影象求補的操作,程式執行的結果為: