opencv學習筆記九:濾波與卷積

在之前我們都是把圖像當作圖像數組進行處理的,而濾波與卷積同樣是在圖像結構體上根據圖像像素之間的聯繫對之進行高級處理。而非將圖像當作一個整體進行顛倒,切割等操作。

濾波器(也稱核)

所謂濾波器,可以簡單理解爲對圖像的每一個像素點(錨點)及其附近的點進行卷積,而所謂卷積,就是以一個特定大小的核(比如5*5)對原像素值進行乘積,而對整幅圖像進行濾波操作,便會得到一個新的圖像。

閾值化操作

我們在對一幅圖像進行完一些基本處理之後,可能希望可以將高於某一個像素值的像素點置爲零或某一定值,而其他像素值不變等等類似的操作,這就是設定閾值。

cv::threshold()函數

	cv::threshold(
		cv::InputArray  src,
		cv::OutputArray  dst,
		double			 thresh,
		double			 maxValue,
		int				thresholdType
	);

在這裏插入圖片描述
在這裏插入圖片描述

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
	Mat src,dst;
	src = imread("1.jpg",0);
	imshow("原圖", src);
	
	threshold(src,dst,40,255,0);
	imshow("閾值化操作", dst);

	waitKey(0);
	return 0;
}

在這裏插入圖片描述
除了自己設置閾值,還可以使用自適應閾值操作函數adaptiveThreshold(),在這個函數中,閾值可以自己產生:

cv::adaptiveThreshold(
	cv::InputArray		src,			//輸入圖像
	cv::OutputArray		dst,			//輸出圖像
	double			    maxValue,       //當thresholdType參數爲THRESH_BINARY或者THRESH_BINARY_INV時的最大值
	int					adaptiveMethod,//自適應閾值算法方法,有兩種:ADAPTIVE_THRESH_MEAN_C或者ADAPTIVE_THRESH_GAUSSIAN_C
	int				    thresholdType,//取閾值類型,THRESH_BINARY或者THRESH_BINARY_INV
	int					blockSize,  //用來計算閾值的像素鄰域大小:3,5,7...
	double				C    //可調參數
);

該函數一些參數和上面的閾值函數是一樣的,下面我們寫個程序讀取一張單通道圖像,再對其進行閾值化操作和自適應閾值操作,來看看二者的區別:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
	Mat src,dst1,dst2;    
	src = imread("1.jpg",0);  //讀入一張圖像
	imshow("原圖", src);  //顯示該圖像
	//閾值化操作,取閾值類型爲二值化閾值操作
	threshold(src, dst1,40,255,0);    
	imshow("閾值化操作", dst1);    
	//自適應閾值,取閾值類型爲反二值化操作
	adaptiveThreshold(src, dst2, 255, ADAPTIVE_THRESH_MEAN_C, 1, 3, 10);
	imshow("自適應閾值化操作", dst2);
	
	waitKey(0);
	return 0;
}

運行效果圖:
在這裏插入圖片描述
中間一幅爲自適應閾值處理後的圖像,可以看到效果還是比較不錯的。

圖像平滑

平滑也稱“模糊”,是一種簡單而又常用的圖像處理操作。平滑圖像目的很多,例如降低噪聲或僞影。
#圖像平滑化//濾波操作:
消除圖像中的噪聲成分叫做圖像的平滑化或濾波操作:信號和圖像的能量大多計徵再幅度譜的低頻和中頻,而在高頻區有用信息往往被噪聲掩蓋,降低高頻成分幅度就可以起到降噪的功能。
圖像濾波目的有兩個:一個是抽出對象的特徵作爲圖像識別的特徵模式,另一個是爲適應圖像處理的要求,消除圖像數字化時混入的噪聲。
#平滑濾波:
平滑濾波是低頻增強的空間濾波技術,它的目的有兩類:一類是模糊,一類是消除噪聲。
關於濾波器,濾波器時我們實現上述功能的工具,opencv中提供了物種常用的濾波器:

  1. 方框濾波——BoxBlur()函數
  2. 均值濾波(鄰域平均濾波)——Blur()函數
  3. 高斯濾波——GaussianBlur()函數
  4. 中值濾波——medianBlur()函數
  5. 雙邊濾波——bilateralFilter()函數
    下面貼個程序演示一下各個濾波器的效果與區別:
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
	Mat src,dst1,dst2,dst3;
	src = imread("2.jpg", 1);
	blur(src, dst1, Size(5, 5));  //均值濾波
	boxFilter(src, dst2, src.depth(), Size(5, 5));  //方框濾波
	GaussianBlur(src, dst3, Size(5, 5), 0, 0); //高斯濾波
	
	imshow("原圖", src);
	imshow("均值濾波", dst1);
	imshow("方框濾波", dst2);
	imshow("高斯濾波", dst3);

	waitKey(0);
	return 0;
}

在這裏插入圖片描述

圖像形態學

膨脹和腐蝕

最基礎的形態學操作就是腐蝕和膨脹,他們在消除噪聲,元素分割以及連接等方面有廣泛應用。
膨脹是一種卷積操作,它將目標像素值替換爲卷積核覆蓋區域的局部最大值。圖中黑色區域並不是黑色像素點,而是表示高亮部分。
在這裏插入圖片描述
與膨脹對應,腐蝕是與之相反的操作,它是計算核覆蓋區域內的局部最小值,如圖:
在這裏插入圖片描述
簡單來說,膨脹就是擴大白色(高亮)像素,腐蝕就是擴大黑色像素;另外,膨脹填充凹面,腐蝕消除突起。下面是函數實現:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
	Mat src, dst1, dst2;
	src = imread("3.jpg", 1);

	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));   //定義核大小
	erode(src, dst1, element);   //腐蝕操作
	dilate(src, dst2, element);  //膨脹操作

	imshow("原圖", src);
	imshow("腐蝕", dst1);
	imshow("膨脹", dst2);

	waitKey(0);
	return 0;
}

在這裏插入圖片描述

自定義核

在上面代碼中,我們看到裏面有一行

Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));   //自定義核大小

這是自定義一個5*5大小的核,用到函數getStructuringElement();

cv::getStructuringElement(
	int        shape,    #生成核的形狀
	cv::Size   ksize,    #生成核的大小
	cv::Point  anchor = cv::Point(-1,-1)  #默認錨點在元素中心
);
#第一個參數:
MORPH_RECT      矩形    
MORPH_ELLIPSE   橢圓形
MORPH_CROSS     交叉形

通用形態學函數

當處理的對象是二值圖像和像素只可能是開(>0)或關(=0)的圖像醃膜時,基本的腐蝕和膨脹操作就夠了,需要對灰度圖或者彩色圖進行處理時,一些其他的操作就非常有用,這些操作可以通過cv::morphologyEx()實現:
在這裏插入圖片描述

										是否需要臨時圖像
	cv::MOP_OPEN      開操作                否
	cv::MOP_CLOSE     閉操作                否
	cv::MOP_GRADIENT  形態學梯度          總是需要
	cv::MOP_TOPHAT    頂帽操作        就地調用需要(src=dst)
 	cv::MOP_BLACKHAT  低帽操作		  就地調用需要(src=dst)

開操作和閉操作

dst = open(src,element) = dilate(erode(src,element),element);
開操作是對圖像先腐蝕,再對腐蝕的圖像進行膨脹的操作
dst = close(src,element) = erode(dilate(src,element),element);
閉操作是對圖像先膨脹,再對膨脹後的圖像進行腐蝕的操作

形態學梯度

dst = morph_grad(src) = dilate(src) - erode(src) ;
形態學梯度就是膨脹操作的結果減腐蝕操作的結果,得到原圖像的邊緣;

頂帽和黑帽

dst = tophat(src) = src - open(src) ;
頂帽操作顯示與鄰域相比更亮的部分。可以提取圖像中的明亮局部
dst = blackhat(src) = close(src) - src ;
黑帽操作顯示與鄰域相比更暗的部分。可以提取圖像中的暗洞

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章