形態(tài)學(xué)的高級形態(tài)往往是建立在腐蝕和膨脹這兩個(gè)基本操作之上,關(guān)于腐蝕和膨脹請參考OpenCV中的腐蝕和膨脹(9)
使用OpenCV中函數(shù)morphologyEx進(jìn)行形態(tài)學(xué)操作
(1)開運(yùn)算 (Opening)
(2)閉運(yùn)算 (Closing)
(3)形態(tài)梯度 (Morphological Gradient)
(4)頂帽 (Top Hat)
(5)黑帽(Black Hat)
開運(yùn)算(Opening)
開運(yùn)算是通過先對圖像腐蝕再膨脹實(shí)現(xiàn)的
能夠排除小團(tuán)塊的物體(假設(shè)物體背景明亮)
閉運(yùn)算(Closing)
閉運(yùn)算是通過先對圖像膨脹后再腐蝕實(shí)現(xiàn)的
能夠排除小型黑洞(黑色區(qū)域)
形態(tài)梯度(Morphological Gradient)
膨脹圖與腐蝕圖只差
頂帽(Top Hat)
原圖像與開運(yùn)算結(jié)果的圖只差
黑帽(Black Hat)
閉運(yùn)算結(jié)果圖與原圖像只差
函數(shù)morphologyEx參數(shù)介紹
void morphologyEx( InputArray src,// 預(yù)處理圖像
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?OutputArray dst,// 處理結(jié)果圖像
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int op,// 需要運(yùn)行的形態(tài)學(xué)操作
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? InputArray kernel,? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Point anchor = Point(-1,-1),
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int iterations =1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int borderType = BORDER_CONSTANT,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const Scalar& borderValue = morphologyDefaultBorderValue()
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? );
op 有六種形式 (2--6)
Opening:MORPH_OPEN: 2 // 開運(yùn)算
Closing:MORPH_CLOSE: 3 // 閉運(yùn)算
Gradient:MORPH_GRADIENT: 4 // 形態(tài)梯度
Top Hat:MORPH_TOPHAT: 5 // 頂帽
Black Hat:MORPH_BLACKHAT: 6 // 黑帽
代碼
- (void)initMat {
self.img = [UIImage imageNamed:@"123.png"];
UIImageToMat(_img, m_src);
[self morphologyEx];
}
- (void)createImageView {
CGFloat h = self.view.frame.size.width * 2 / 3;
self.imgView1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, h)];
[self.view addSubview:_imgView1];
_imgView1.backgroundColor = [UIColor lightGrayColor];
_imgView1.image = _img;
self.imgView2 = [[UIImageView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_imgView1.frame) + 5, self.view.frame.size.width, h)];
[self.view addSubview:_imgView2];
_imgView2.backgroundColor = [UIColor lightGrayColor];
_imgView2.image = _img;
}
- (void)createSlider {
NSArray *tempArr = @[@"Operator :", @"Element :", @"Kernel Size :"];
CGFloat w = self.view.frame.size.width - 100;
CGFloat y = self.view.frame.size.height - 50;
for (NSInteger i = 0; i < 3; i++) {
UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(90,? y - 45 * i, w, 40)];
[self.view addSubview:slider];
[slider addTarget:self action:@selector(valueChanged:)
forControlEvents:UIControlEventValueChanged];
[self sliderMumValueWith:i slider:slider];
slider.tag = 1000 + i;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, y - 45 * i, 80, 40)];
label.textAlignment = NSTextAlignmentRight;
[self.view addSubview:label];
label.font = [UIFont systemFontOfSize:10];
label.text = tempArr[i];
}
}
- (void)sliderMumValueWith:(NSInteger)i slider:(UISlider *)slider {
switch (i) {
case 0: {
slider.continuous = YES; // NO makes it call only once you let go
slider.minimumValue = 2;
slider.maximumValue = 6;
} break;
case 1: {
slider.continuous = YES; // NO makes it call only once you let go
slider.minimumValue = 0;
slider.maximumValue = 2;
} break;
case 2: {
slider.continuous = YES; // NO makes it call only once you let go
slider.minimumValue = 0;
slider.maximumValue = 21;
} break;
}
}
- (void)morphologyEx {
// 由于 MORPH_X的取值范圍是: 2,3,4,5 和 6
Mat element = getStructuringElement(morph_elem, cv::Size(2 * morph_size + 1, 2 * morph_size + 1), cv::Point(morph_size, morph_size));
/// 運(yùn)行指定形態(tài)學(xué)操作
morphologyEx(m_src, m_dst, morph_operator, element);
_imgView2.image = MatToUIImage(m_dst);//morph_operator
}
創(chuàng)建公共變量
Mat m_src, m_dst;
int morph_elem = 0;
int morph_size = 0;
int morph_operator = 0;
調(diào)用
[self initMat];
[self createSlider];
[self createImageView];
參考資料