前言
在上一章中描述了如何進(jìn)行圖像模糊曙蒸,詳細(xì)描述可點擊查看(http://www.reibang.com/writer#/notebooks/47386368/notes/77175002)
目標(biāo)
本章中瓷们,將學(xué)習(xí)如何:
- 什么是膨脹與腐蝕
- 形態(tài)學(xué)處理——膨脹
- 形態(tài)學(xué)處理——腐蝕
- 動態(tài)調(diào)整結(jié)構(gòu)元素大小
- 代碼演示
什么是膨脹與腐蝕
- 膨脹與腐蝕屬于形態(tài)學(xué)范疇孝治,具體的含義根據(jù)字面意思來理解即可胞谈。用更形象的話就是“增肥”與“減肥”填具。他們的運用廣泛:消除噪聲;分割(isolate)獨立的圖像元素艰额、澄港、連接(join)相鄰的元素以及尋找圖像中明顯的極大值區(qū)域或極小值區(qū)域。
形態(tài)學(xué)處理——膨脹
-
相關(guān)AIP:
void dilate( InputArray src, OutputArray dst, InputArray kernel,
Point anchor = Point(-1,-1), int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue() );
-
跟卷積操作類似柄沮,假設(shè)有圖像A和結(jié)構(gòu)元素B回梧,結(jié)構(gòu)元素B在A上面移動,其中B定義其中心為錨點祖搓,計算B覆蓋下A的最大像素值用來替換錨點的像素狱意,其中B作為結(jié)構(gòu)體可以是任意形狀。形態(tài)學(xué)操作——膨脹(感官上圖像黑色部分變細(xì))
形態(tài)學(xué)處理——腐蝕
-
相關(guān)AIP:
void erode( InputArray src, OutputArray dst, InputArray kernel,
Point anchor = Point(-1,-1), int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue() );
-
腐蝕跟膨脹操作的過程類似拯欧,唯一不同的是以最小值替換錨點重疊下圖像的像素值详囤。形態(tài)學(xué)處理——腐蝕(感官上圖像黑色部分變粗)
動態(tài)調(diào)整結(jié)構(gòu)元素大小
TrackBar - createTrackbar(const String & trackbarname, const String winName, int* value, int count, Trackbarcallback func, void* userdata=0)
其中最中要的是 callback 函數(shù)功能。如果設(shè)置為NULL就是說只有值update镐作,但是不會調(diào)用callback的函數(shù)藏姐。
代碼演示
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
Mat src, erode_dst, dilate_dst;
char dilate_Win[] = "Dilation windows", erode_Win[] = "Erosion windows";
int dilat_element = 0, erode_element = 0;
int dilate_size = 0, erode_size = 0;
int const MAX_ELEMENT = 2;
int const MAX_KERNEL_SIZE = 21;
void dilation(int, void*);
void erosion(int, void*);
int main(int argc, char* argv[])
{
// 1、加載圖像滑肉,可以是BGR或者灰度圖像
src = imread("D:/瀏覽器下載/谷歌下載/lena512color.tiff");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
char input_win[] = "input image";
namedWindow(input_win, WINDOW_AUTOSIZE);
imshow(input_win, src);
// 2包各、創(chuàng)建兩個窗口(一個用于膨脹dilation摘仅,另一個用于erosion)
// 每次移動任何滑塊時靶庙,都會調(diào)用dilation或erosion函數(shù),它將根據(jù)當(dāng)前的trackbar值更新輸出圖像
namedWindow(dilate_Win, WINDOW_AUTOSIZE);
namedWindow(erode_Win, WINDOW_AUTOSIZE);
// 3娃属、為每個操作創(chuàng)建兩組滑塊
// 3.1 第一個滑塊返回dilat_element或erode_element
createTrackbar("卷積核類型:", dilate_Win, &dilat_element, MAX_ELEMENT, dilation);
// 3.2 第二個滑塊返回dilate_size或erode_size
createTrackbar("卷積核大小:", dilate_Win, &dilate_size, MAX_KERNEL_SIZE, dilation);
createTrackbar("卷積核類型:", erode_Win, &erode_element, MAX_ELEMENT, erosion);
createTrackbar("卷積核大小:", erode_Win, &erode_size, MAX_KERNEL_SIZE, erosion);
dilation(0, 0);
erosion(0, 0);
waitKey(0);
return 0;
}
// 膨脹
void dilation(int, void*)
{
int dilate_type; // 內(nèi)核選擇三中形狀中的任何一種
if (0 == dilat_element){ dilate_type = MORPH_RECT; }
else if (1 == dilat_element){ dilate_type = MORPH_CROSS; }
else if (2 == dilat_element){ dilate_type = MORPH_ELLIPSE; }
int s = dilate_size * 2 + 1;
Mat kernel = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1)); // 獲取結(jié)構(gòu)元素
dilate(src, dilate_dst, kernel, Point(-1, -1), dilate_type);
imshow(dilate_Win, dilate_dst);
return;
}
// 腐蝕
void erosion(int, void*)
{
int erosion_type; // 內(nèi)核選擇三中形狀中的任何一種
if (0 == erode_element){ erosion_type = MORPH_RECT; }
else if (1 == erode_element){ erosion_type = MORPH_CROSS; }
else if (2 == erode_element){ erosion_type = MORPH_ELLIPSE; }
int s = erode_size * 2 + 1;
Mat kernel = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1)); // 獲取結(jié)構(gòu)元素
erode(src, erode_dst, kernel, Point(-1, -1), erosion_type);
imshow(erode_Win, erode_dst);
return;
}