膨胀与腐蚀
腐蚀
形态学操作-腐蚀
腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下图像的像素值
膨胀
形态学操作(morphology operators) - 膨胀
图像形态学操作--基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学
形态学有四个基本操作:腐蚀、膨胀、开、闭
膨胀与腐蚀是图像处理中最常用的形态学操作手段
跟卷积操作类似,假设有图像A和结构元素B在A上面移动,其中B定义其中心为锚点,计算B覆盖下A的最大像素值用来替代锚点的像素,其中B作为结构体可以是任意形状
相关API
getStructuringElement(int shape,Size ksize,Point anchor)//获取结构
形状(MORPH_RECT\MORPH_CROSS\MORPH_ELLIPSE)
大小
锚点 默认是Point(-1,-1)意思就是中心像素
dilate(src,dst,kernel)
dst(x,y) = max src(x+x1,y+y1);
erode(src,dst,kernel)
dst(x,y) = min src(x+x1,y+y1);
动态调整结构元素大小
TrackBar - createTrackbar(constString&trackbarname,const String winName,int* value,int count,Trackbarcallback func,void* userdata = 0)
其中最重要的是callback函数功能。如果设置为NULL就是说只有值update,但是不会调用callback的函数
代码演示:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
Mat src,dst;
char OUTPUT_WIN[] = "output image";
int element_size = 3;
int max_size = 21;
void CallBack_Demo(int,void*);
int main(int argc,char** argv){
src = imread("");
if(!src.data){
printf("could not load image...\n");
return -1;
}
namedWindow("input image",CV_WINDOW_AUTOSIZE);
imshow("input image",src);
namedWindow(OUTPUT_WIN,CV_WINDOW_AUTOSIZE);
createTrackbar("Element Size",OUTPUT_WIN,&element_size,max_size,CallBack_Demo);
CallBack_Demo(0,0);
waitKey(0);
return 0;
}
void CallBack_Demo(int,void*){
int s = element_size * 2 + 1;
Mat structureElement = getStructuringElement(MORPH_RECT,Size(s,s),Point(-1,-1));
dilate(src,dst,structureElement,Point(-1,-1));//膨胀
erode(src,dst,structureElement);//腐蚀
imshow(OUTPUT_WIN,dst);
}
形态学操作
开操作 open
先腐蚀后膨胀 dst = open(src,element)=dilate(erode(src,element))
可以去掉小的对象,假设对象是前景色,背景是黑色
比操作 close
先膨胀后腐蚀 dst = close(src,element)=erode(dilate(src,element));
可以填充小的洞(fill hole),假设对象是前景色,背景是黑色
形态学梯度 Morphological Gradien
膨胀减去腐蚀
dst = morph(src,element)=dilate(src,element)-erode(src,element);
又称为基本梯度(其中还包括内部梯度、方向梯度)
顶帽 top hat
顶帽是原图像与开操作之间的差值图像
黑帽 black hat
黑帽是闭 操作图像与原图像的差值图像
相关API
morphologyEx(src,dst,CV_MOP_BLACKHAT,kernel);
Mat src 输入图像
Mat dst 输出结果
int OPT CV_MOP_OPEN/CV_MOP_CLOSE/CV_MOP_GRADIENT/CV_MOP_TOPHAT/CV_MOP_BLACKHAT形态学操作类型
Mat kernel 结构元素
int lteration 迭代次数,默认是1
代码演示:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
int main(int argc,char** argv){
Mat src,dst;
src = imread("");
if(!src.data){
printf("could not load image...\n");
return -1;
}
namedWindow("input image",CV_WINDOW_AUTOSIZE);
imshow("input image",src);
char output_title[] = "morphology demo";
namedWindow(output_title,CV_WINDOW_AUTOSIZE);
Mat kernel = getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));
morphologyEx(src,dst,CV_MOR_OPEN,kernel);//开操作
morphologyEx(src,dst,CV_MOR_CLOSE,kernel);/闭比操作
morphologyEx(src,dst,CV_MOR_GRADIENT,kernel);//形态学梯度
morphologyEx(src,dst,CV_MOR_TOPHAT,kernel);//顶帽
imshow(output_title,dst);
waitKey(0);
return 0;
}
形态学操作应用---提取水平与垂直线
原理方法
图像形态学操作时候,可以通过自定义的结构元素实现结构元素对输入图像一些对象敏感、另一些对象不敏感,这样就会让敏感的对象改变而不敏感的对象保留输出。通过使用两个最基本的形态学操作---膨胀与腐蚀,使用不同的结构元素实现对输入图像的操作得到想要的结果
膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素
腐蚀,输出的像素值结构元素覆盖下输入图像的最小像素值
结构元素:上述的膨胀与腐蚀可以使用任意的结构元素
常见的形状:矩形、圆、直线、磁盘形状、砖石形状等各种自定义形状
提取步骤:
输入图像彩色图像 imread
转换为灰度图像 cvtColor
转换为二值图像 adaptiveThreshold
定义结构元素
开操作(腐蚀+膨胀)提取 水平与垂直线
API
转换为二值图像
adaptiveThreshold(Mat src,//输入的灰度图像
Mat dest,//二值图像
double maxValue,//二值图像最大值
int adaptiveMethod,//自适应方法,只能其中之一
//ADAPTIVE_THRESH_MEAN_C,ADAPTIVE_THRESH_GAUSSIAN_C
int thresholdType, //阙值类型
int blockSize,//块大小
double C//常量C可以是正数,0,负数)
代码演示:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
int main(int argc,char** argv){
Mat src,dst;
src = imread("");
if(!src.data){
printf("could not load image...\n");
return -1;
}
char INPUT_WIN[] = "input image";
char OUTPUT_WIN[] = "result image";
namedWindow(INPUT_WIN,CV_WINDOW_AUTOSIZE);
Mat gray_src;
cvtColor(src,gray_src,CV_BGR2GRAY);
imshow("gray image",gray_src);
Mat binImg;
adaptiveThreshold(gray_src,binImg,255,ADAPIVE_THRESH_MEAN_C,THRESH_BINARY,15,-2);
Mat hline = getStructuringElement(MORP_RECT,Size(src.cols/16,1),Point(-1,-1));//水平结构元素
Mat vline = getStructuringElement(MORPH_RECT,Size(1,src.rows/16),Point(-1,-1));//垂直结构元素
Mat temp;
erode(binImg,dst,hline);
dilate(temp,dst,hline);
//morphologyEx(binImg,dst,CV_MOP_OPEN,vline);
bitwise_not(dst,dst);
blur(dst,dst,Size(3,3),Point(-1,-1));
imshow("Final Result",dst);
waitKey(0);
return 0;
}