基本形態學操作:
- 腐蝕 (Erosion)
- 膨脹 (Dilation)
其他形態學操作:
- 開運算 (Opening)
- 閉運算 (Closing)
- 形態梯度 (Morphological Gradient)
- 頂帽 (Top Hat)
- 黑帽(Black Hat)
腐蝕與膨脹:
腐蝕操作描述爲:掃描圖像的每一個像素,用結構元素與其覆蓋的二值圖像做“與”操作:如果都爲1,結果圖像的該像素爲1,否則爲0。
膨脹操作描述爲:掃描圖像的每一個像素,用結構元素與其覆蓋的二值圖像做“與”操作:如果都爲0,結果圖像的該像素爲0,否則爲1。
以上都是關於二值圖像的形態學操作,對於灰度圖像:
-
腐蝕操作
其中,g(x,y)爲腐蝕後的灰度圖像,f(x,y)爲原灰度圖像,B爲結構元素。腐蝕運算是由結構元素確定的鄰域塊中選取圖像值與結構元素值的差的最小值。
-
膨脹操作
其中,g(x,y)爲腐蝕後的灰度圖像,f(x,y)爲原灰度圖像,B爲結構元素。 膨脹運算是由結構元素確定的鄰域塊中選取圖像值與結構元素值的和的最大值。
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
Mat srcImage,dstImage;
int g_TrackBarValue = 0;
int g_StructElementSize = 3;
//回調函數
void Process(){
Mat element = getStructuringElement(MORPH_RECT,
Size(g_StructElementSize *2+1,g_StructElementSize*2+1),
Point(g_StructElementSize,g_StructElementSize));
if(g_TrackBarValue){
erode(srcImage,dstImage,element);
}
else{
dilate(srcImage,dstImage,element);
}
imshow("效果圖像",dstImage);
}
void on_TrackbarNumChange(int ,void *){
Process();
}
void on_ElementSizeChange(int, void *){
Process();
}
int main(int argc,char **argv){
//載入一張圖片
srcImage = imread("img.jpg");
if(!srcImage.data){
cout<<"input error!"<<endl;
return 0;
}
namedWindow("原始圖像");
imshow("原始圖像",srcImage);
namedWindow("效果圖像");
//初識化
Mat element = getStructuringElement(MORPH_RECT,
Size(g_StructElementSize *2+1,g_StructElementSize*2+1),
Point(g_StructElementSize,g_StructElementSize));
dilate(srcImage,dstImage,element);
imshow("效果圖像",dstImage);
//創建滑動塊
createTrackbar("erode/dilate","效果圖像",&g_TrackBarValue,1,on_TrackbarNumChange);
createTrackbar("size","效果圖像",&g_StructElementSize,21,on_ElementSizeChange);
while(char(waitKey(1)!='q')){}
return 0;
}
膨脹圖像:
腐蝕圖像:
其他形態學操作:
-
開運算是通過先對圖像腐蝕再膨脹實現的。
-
閉運算是通過先對圖像膨脹再腐蝕實現的。
-
形態學梯度:膨脹圖與腐蝕圖之差
-
頂帽:原圖像與開運算結果圖之差
-
黑帽:閉運算結果圖與原圖像之差
運行形態學操作的核心函數是 morphologyEx 。
- src : 原 (輸入) 圖像
- dst: 輸出圖像
- operation: 需要運行的形態學操作。 我們有7個選項:
-
- Dilate:MORPH_DILATE:0
- Erode:MORPH_ERODE:1
- Opening: MORPH_OPEN : 2
- Closing: MORPH_CLOSE: 3
- Gradient: MORPH_GRADIENT: 4
- Top Hat: MORPH_TOPHAT: 5
- Black Hat: MORPH_BLACKHAT: 6
- element: 內核,可以使用函數:get_structuring_element:getStructuringElement <> 自定義。
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#define WINDOWNAME "效果圖"
using namespace std;
using namespace cv;
//全局變量
int g_kernelsize = 0;
int g_elment = 0;
int g_operater = 0;
const int g_maxsize = 21;
const int g_maxelment = 2;
const int g_maxoperater = 6;
Mat srcImage,dstImage;
//創建回調函數
void on_Morphology(int,void *){
Mat elment = getStructuringElement(g_elment,
Size(g_kernelsize*2+1,g_kernelsize*2+1),
Point(g_kernelsize,g_kernelsize));
morphologyEx(srcImage,dstImage,g_operater,elment);
imshow(WINDOWNAME,dstImage);
}
int main(int argc,char **argv){
//載入一張圖像
srcImage = imread("1.jpg");
if(!srcImage.data){
cout<<"input error!";
return 0;
}
imshow("原始圖像",srcImage);
dstImage.create(srcImage.size(),srcImage.type());
//創建顯示形態學操作的窗口
namedWindow(WINDOWNAME);
//選擇形態學操作的方法
createTrackbar("Operator:",WINDOWNAME,&g_operater,g_maxoperater,on_Morphology);
//指定內核形狀
createTrackbar("Element:",WINDOWNAME,&g_elment,g_maxelment,on_Morphology);
//指定內核大小
createTrackbar("Kernel size:",WINDOWNAME,&g_kernelsize,g_maxsize,on_Morphology);
//啓動默認值
on_Morphology(0,0);
//程序結束操作
while(char(waitKey(0)) == 'q') break;
return 0;
}
腐蝕:
膨脹:
開運算:
閉運算:
形態學梯度:
頂帽:
黑帽: