一.膨脹
1.膨脹原理
? ? ? ? 膨脹的本質就是通過微積分的轉換,將圖像A和圖形B進行卷積操作合并成一個A+B圖像。核就是指任意的形狀或者大小的圖形B。例如下圖,將核(也就是圖形B)通過微積分卷積,和圖像A合并成一個圖像A+B。
2.特點
- 圖像就會更加明亮????
- 圖像就會更加粗糙
如下圖所示:?
?
?3.膨脹的API
- 處理圖像膨脹的API:void dilate( InputArray src, OutputArray dst, InputArray kernel, Point anchor, int iterations, int borderType, const Scalar&borderValue )
第一個參數:src 的類型是 InputArray,它指的是輸入圖像,它可以是 Mat 類的數據。圖像的通道數可以是任意數,但是圖像的深度一般是 CV_8U,CV_16U,CV_16S,CV_32F,CV_64F
第二個參數:dst 的類型是 OutputArray,它指的是目標圖像(輸出圖像),值得注意的是輸出圖像的尺寸、類型要和輸入圖像是一致的。
第三個參數:InputArray 類型的 kernel,膨脹操作的核(可以理解為輸入圖形B)。當這個值為 NULL 的時候,表示使用的核參考點默認是 3*3。這個參數通常會配合 getStructingElement 參數的使用(這個參數的使用,下面我會詳細說到)。
第四個參數:Point 類型的 anchor,描點的位置,默認是(-1,-1),表示中心位置。
第五個參數:int 類型的迭代次數,默認是 1
第六個參數:int 類型的 borderType,這個類型用于推斷圖像外部的邊界模式,用的最多的是 BORDER_DEFAULT
下面是常用的幾種邊框模式(這幾種相對比較常用,其他的用的很少)
BORDER_CONSTANT:用指定的像素填充邊框
BORDER_REPLICATE:用已知的邊緣像素來填充邊框
BORDER_WRAP:用另一邊的像素來補償填充
BORDER_DEFAULT:默認模式畫邊框
BORDER_TRANSPANT: 用透明的方式畫框
第七個參數:const Scalar 類型的 borderType,一般不用填寫,因為這個 API 已經有了默認值 morphologyDefaultBorderValue()
- 獲取核(圖形B)的API: CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
?第一個參數:表示內核的形狀(就是圖形B是以什么形狀放在圖像A上的),這里包括了:矩形(MORPH_RECT)、交叉形(MORPH_CROSS)、橢圓形(MORPH_ELLIPSE),常用的內核形狀是矩形
第二個參數:內核的尺寸
第三個參數:錨點的位置,默認值 Point(-1,-1),表示的是位于中心點
4.?代碼實戰:實現圖像膨脹功能
(1)功能實現的步驟:imread 讀取圖片、使用 cvtColor 對圖片進行灰度操作、使用 getStructingElement 獲取卷積層(也就是獲取圖形B)、使用 dilate 對圖片進行膨脹(將A和B合并)、imwrite 保存圖片。流程圖如下:
(2)代碼如下:
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>using namespace cv;
using namespace std;int main()
{Mat testImage = imread("zjl.jpg");//讀取圖片if(testImage.empty()){printf("read testImage failed....\n");}Mat vertical_structure = getStructuringElement(MORPH_CROSS, Size(20,20));//創建一個20*20的十字形結構元素dilate(testImage, testImage, vertical_structure);//膨脹操作,testImage為輸入圖像,testImage為輸出圖像,vertical_structure為核imwrite("zjl1.jpg", testImage);//保存圖片return 0;
}
(3)效果如下:上圖是MORPH_CROSS(十字交叉的核),下圖是MORPH_RECT(矩形核)效果圖。
?二.腐蝕
1.腐蝕原理
? ? ? ? 原理和膨脹一樣,腐蝕就是膨脹的反向操作,膨脹是把圖像圖像變大,而腐蝕就是把圖像變小。
2.特點
- 圖像更加細小
- 黑暗背景部分會更加大
3.腐蝕的API
- ?CV_EXPORTS_W void erode( InputArray src, OutputArray dst, InputArray kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue() );
第一個參數:src 的類型是 InputArray,它指的是輸入圖像,它可以是 Mat 類的數據。圖像的通道數可以是任意數,但是圖像的深度一般是 CV_8U,CV_16U,CV_16S,CV_32F,CV_64F
第二個參數:dst 的類型是 OutputArray,它指的是目標圖像(輸出圖像),值得注意的是輸出圖像的尺寸、類型要和輸入圖像是一致的。
第三個參數:InputArray 類型的 kernel,膨脹操作的核。當這個值為 NULL 的時候,表示使用的核參考點默認是 3*3。這個參數通常會配合 getStructingElement 參數的使用(這個參數的使用,下面我會詳細說到)。
第四個參數:Point 類型的 anchor,描點的位置,默認是(-1,-1),表示中心位置。
第五個參數:int 類型的迭代次數,默認是 1
第六個參數:int 類型的 borderType,這個類型用于推斷圖像外部的邊界模式,它的默認值是 BORDER_DEFAULT
第七個參數:const Scalar 類型的 borderType,一般不用填寫,因為這個 API 已經有了默認值 morphologyDefaultBorderValue()
- ?CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
第一個參數:表示內核的形狀,這里包括了:矩形(MORPH_RECT)、交叉(MORPH_CROSS)、橢圓形(MORPH_ELLIPSE)
第二個參數:內核的尺寸
第三個參數:錨點的位置,默認值 Point(-1,-1),表示的是位于中心點
?4.代碼實戰:實現圖像腐蝕功能
(1)功能實現的步驟:imread 讀取圖片、使用 cvtColor 對圖片進行灰度操作、使用 getStructingElement 獲取卷積層(也就是獲取圖形B)、使用 erode 對圖片進行腐蝕、imwrite 保存圖片。流程圖如下:?
(2)代碼如下:?
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>using namespace cv;
using namespace std;int main()
{Mat testImage = imread("zjl.jpg");//讀取圖片if(testImage.empty()){printf("could not load image.....\n");return -1;}Mat vertical_structure = getStructuringElement(MORPH_RECT, Size(15,15));//獲取核圖形erode(testImage, testImage, vertical_structure);//腐蝕操作imwrite("zjl2.jpg", testImage);//保存圖片return 0;
}