基于C++的OpenCV(八)图像处理

一、线性滤波:方框滤波、均值滤波、高斯滤波

1.1.平滑处理

平滑处理(smoothing)也称为模糊处理(bluring),是一种简单且使用频率很高的图像处理方法。平滑处理的用途有很多,最常见的是用来减少图像上的噪点或者失真。

1.2.图像滤波与滤波器

图像滤波指在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏直接影响到后续图像处理和分析的有效性和可靠性。

消除图像中的噪声成分叫作图像的平滑化或滤波操作。信号或图像的能量大部分集中在幅度谱的低频和中频段,而在高频段,有用的信息经常被噪声淹没。

图像滤波的目的有两个:
一个是抽出对象的特征作为图像识别的特征模式;
另一个是为适应图像处理的要求,消除图像数字化时所混入的噪声。

滤波处理的要求:
一是不能损坏图像的轮廓及边缘等重要信息;
二是使图像清晰视觉效果好。

平滑滤波是低频增强的空间域滤波技术。它的目的有两类:一类是模糊;另一类是消除噪声。

空间域的平滑滤波一般采用简单平均法进行,就是求邻近像元点的平均亮度值。邻域的大小与平滑效果直接相关,邻域越大平滑的效果越好,但邻域过大,平滑也会使边缘信息损失的越大,从而使输出的图像变得模糊,因此需合理选择邻域的大小。

方框滤波——BoxBlur函数
均值滤波(邻域平均滤波)——Blur函数
高斯滤波——GaussianBlur函数
中值滤波——medianBlur函数
双边滤波——bilateralFilter函数

1.3.线性滤波器的简介

线性滤波器:线性滤波器经常用于剔除输入信号中不想要的频率或者从许多频率中选择一个想要的频率。

几种常见的线性滤波器:
低通滤波器:允许低频率通过;
高通滤波器:允许高频率通过;
带通滤波器:允许一定范围频率通过;
带阻滤波器:阻止一定范围频率通过并且允许其他频率通过;
全通滤波器:允许所有频率通过,仅仅改变相位关系;
陷波滤波器(Band-Stop Filter):阻止一个狭小频率范围通过,是一种特殊带阻滤波器。

1.4.滤波和模糊

滤波可分为低通滤波和高通滤波两种:高通滤波是指用高斯函数作为滤波函数的滤波操作,至于是不是模糊,要看是高斯低通还是高斯高通,低通就是模糊,高通就是锐化。

高斯滤波是指用高斯函数作为滤波函数的滤波操作。
高斯模糊就是高斯低通滤波。

1.5.领域算子与线性领域滤波

邻域算子(局部算子)是利用给定像素周围的像素值的决定此像素的最终输出值的一种算子。而线性领域滤波就是一种常见的领域算子,像素的输出值取决于输入像素的加权和。

邻域算子除了用于局部色调调整以外,还可以用于图像滤波,以实现图像的平滑和锐化,图像边缘增强或者图像噪声的去除。

线性滤波处理的输出像素值是输入像素值的加权和。
方框滤波——boxblur函数
均值滤波——blur函数
高斯滤波——GaussianBlur函数

1.6.方框滤波(box Filter)

方框滤波(box Filter)被封装在一个名为boxblur的函数中,即boxblur函数的作用是使用方框滤波器(box filter)来模糊一张图片,从src输入,从dst输出。

void boxFilter(InputArray src,OutputArray dsy,int depth,Size ksize,Point anchor=Point(-1,-1),boolnormalize=true,int borderType=BORDER_DEFAULT)

第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。该函数对通道是独立处理的,且可以处理任意通道数的图片。但需要注意,待处理的图片深度应该为CV_8U、CV_16U、CV_16S、CV_32F以及CV_64F之一。
第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
第三个参数,int类型的ddepth,输出图像的深度,-1代表使用原图深度,即src.depth()。
第四个参数,Size类型(对Size类型稍后有讲解)的ksize,内核的大小。一般用Size(w,h)来表示内核的大小,其中w为像素宽度,h为像素高度。Size(3,3)就表示3x3的核大小,Size(5,5)就表示5X5的核的中心。
第六个参数,bool类型的normalize,默认值为true,一个标识符,表示内核是否被其区域归一化(normalized)了。
第七个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT。

1.7.均值滤波

均值滤波是最简单的一种滤波操作,输出图像的每一个像素是核窗口内输入图像对应像素的平均值(所有像素加权系数相等),其实就是归一化后的方框滤波。

1.均值滤波基础理论
均值滤波是典型的线性滤波算法,主要方法为领域平均法,即用一片图像区域的各个像素的平均值来代替原图像中的各个像素值。一般需要在图像上对目标像素给出一个模板(内核),该模板包括了其周围的临近像素(比如以目标像素为中心的周围8(3*3-1)个像素,构成一个滤波模板,即去掉目标像素本身)。再用模板中的全体像素的平均值来代替原来像素值。

2.均值滤波的缺陷
均值滤波本身存在着固有缺陷,即它不能很好的保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。

3.在opencv中使用均值滤波——blur函数
blur函数的作用是:对输入的图像src进行均值滤波后用dst输出。

void blur(InputArray src,OutputArray dst,Size ksize,Point anchor=Point(-1,-1),int borderType=BORDER_DEFAULT)

第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。该函数对通道是独立处理的,且可以处理任意通道数的图片。但需要注意的是,待处理的图片深度应该为CV_8U、CV_16U、CV_16S、CV_32F以及CV_64F之一。
第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。可以用Mat::Clone,以源图片为模板,来初始化得到目标图。
第三个参数,Size类型的ksize,内核的大小。一般写作Size(w,h)来表示内核的大小。
第四个参数,Point类型的anchor,表示锚点(即被平滑的那个点),它的默认值Point(-1,-1)。如果这个点坐标是负值,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。
第五个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT。

1.8.高斯滤波

1)高斯滤波基础理论
高斯滤波是一种线性平滑滤波,可以消除高斯噪声,广泛应用于图像处理的减噪过程。通俗地讲,高斯滤波就是对整幅图像进行加权平均地过程,每一个像素点地值,都是其本身和领域内的其他像素值经过加权平均后得到。

高斯滤波的具体操作是:用一个模板(或称卷积、掩膜)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

图像与圆形方框模糊做卷积将会生成更加精确的焦外成像效果。由于高斯函数的傅里叶变换是另外一个高斯函数,所以高斯模糊对于图像来说就是一个低通滤波操作。
高斯滤波器是一类根据高斯函数的形状来选择权值的线性平滑滤波器。高斯平滑滤波器对于抑制服从正态分布的噪声非常有效。

2)高斯滤波:GaussianBlur函数
GaussianBlur函数的作用是用高斯滤波器来模糊一张图片,对输入的图像src进行高斯滤波后用dst输出。它将原图像和指定的高斯核函数做卷积运算,并且支持就地过滤(In-placefiltering)。
void GaussianBlur(InputArray src,OutputArray dst,Size ksize,double sigmaX,double sigmaY=0,int borderType=BORDER_DEFAULT)
第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象。可以是单独的任意通道数的图片,其图片深度应该为CV_8U、CV_16U、CV_16S、CV_32F以及CV_64F之一。
第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。可以用Mat::Clone,以源图片为模板,来初始化得到目标图。
第三个参数,Size类型的ksize高斯内核的大小。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数,或者是零,这都由sigma计算而来。
第四个参数,double类型的sigmaX,表示高斯核函数在X方向的标准偏差。
第五个参数,double类型的sigmaY,表示高斯核函数在Y方向的标准偏差。若sigmaY为零,就将他设为sigmaX;如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来。
第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT。

1.9.线性滤波相关OpenCV源码

【1】OpenCV中boxFilter函数源码

void cv::boxFilter(InputArray _src,OutputArray _dst,int ddepth,Size ksize,Point anchor,bool ksize,Point anchor,bool normalize,int borderType)
{
	Mat src=_src.getMat();
	int sdepth=src.depth(),cn=src.channels();
	if(ddepth<0)
		ddepth=sdepth;
	_dst.create(src.size(),CV_MAKETYPE(ddepth,cn));
	Mat dst=_dst.getMat();

	if(borderType!=BORDER_CONSTANT&&normalize)
	{
		if(src.rows==1)
			ksize.height=1;
		if(src.cols==1)
			ksize.width=1;
	}

	#ifdef HAVE_TEGRA_OPTIMIZATION
		if(tegra::box(src,dst,ksize,anchor,normalize,borderType))
			return;
	#endif
		Ptr<FilterEngine> f=createBoxFilter(src.type(),dst.type(),ksize,anchor,normalize,borderType);
		f->apply(src,dst);
}

其中,Ptr是用来动态分配的对象的智能指针模板类。函数内部先复制源图的形参Mat数据到临时变量,定义一些临时变量,再处理ddepth小于零的情况,接着处理borderType不为BORDER_CONSTANT且normalize为真的情况,最终调用FilterEngine滤波引擎创建一个BoxFilter,正式开始滤波操作。

【2】FilterEngine类解析:OpenCV图像滤波核心引擎
FilterEngine类是OpenCV关于图像滤波的主要类,是OpenCV图像滤波功能额核心引擎。各种滤波函数如blur、GaussianBlur其实是就是再函数末尾处定义了一个Ptr类型的f,然后f->apply(src,dst)。

这个类可以把几乎所有的滤波操作施加到图像上,它包含了所有必要的中间缓存器。有很多和滤波相关的create系函数的返回值直接就是Ptr
	cv::createSeparableLinearFilter()
		cv::createLinearFilter(),cv::createGaussianFilter(),cv::createDerivFilter()
	cv::createBoxFilter()
	cv::createMorphologyFilter()

PtrCreateLinearFilter(int srcType,int dstType,InputArray kernel,Point_anchor=Point(-1,-1),double delta=0,int rowBorderType=BORDER_DEFAULT,intcolumnBorderType=-1,const Scalar&borderValue=Scalar())
其中的Ptr是用来动态分配的对象的智能指针模板类,而尖括号里的模板参数就是FilterEngine。

使用FilterEngine类可以分块处理大量的图像,构建复杂的管线,其中就包含一些进行滤波阶段。如果我们需要使用预定义好的滤波操作,有cv::filter2D()、cv::erode()和cv::dilate()可以选择,他们不依赖于FilterEngine,在自己函数体内部实现了FilterEngine提供的功能。

class CV_EXPORTS FilterEngine
{
	public:
		//默认构造函数
		FilterEngine();
		//完整的构造函数
		FilterEngine(const Ptr<BaseFilter>& _filter2D,
							const Ptr_<BaseRowFilter>& _rowFilter,
							const Ptr<BaseColumnFilter>& _columnFilter,
							int srcType,int dstType,int bufType,
							int _rowBorderType=BORDER_REPLICATE,
							int _columnBorderType=-1,
							const Scalar&_borderValue=Scalar());
		//默认析构函数
		virtual ~FilterEngine();
		//重新初始化引擎。释放之前滤波器申请的内存
		void init(const Ptr<BaseFilter>& _filter2D,
					constPtr<BaseRowFilter>& _rowFilter,
					constPtr<BaseColumnFilter>& _columnFilter,
					int srcType,int dstType,int bufType,
					int _rowBorderType=BORDER_REPLICALE,int _columnBorderType=-1,
					const Scalar&_borderValue=Scalar());
		//开始对指定了ROI区域和尺寸的图片进行滤波操作
		virtual int start(Size wholeSize,Rect roi,int maxBufRows=-1);
		//开始对制定了ROI区域的图片进行滤波操作
		virtual int start(const Mat& src,const Rect&srcRoi=Rect(0,0,-1,-1),bool isolated=false,intmaxBufRows=-1);
		//处理图像的下一个srcCount行
		virtual int proceed(const uchar*src,int srcStep,int srcCount,uchar*dst,intdstStep);
		//对图像指定的ROI区域进行滤波操作,若srcRoi=(0,0,-1,-1),则对整个图像进行滤波操作
		virtual void applay(const Mat&src,Mat& dst,
									const Rect&srcRoi=Rect(0,0,-1,-1),
									Point dstOfs=Point(0,0),
									bool isolated=false);

		//如果滤波器可分离,则返回true
		boolisSeparable() const{return (const BaseFilter*)filter2D==0;}

		//返回输入和输出行数
		int remainingInputRows() const;
		intremainingOutputRows() const;

		//一些成员参数定义
		int srcType,dstType,bufType;
		Size ksize;
		Point anchor;
		int maxWidth;
		Size wholeSize;
		Rect roi;
		int dx1,dx2;
		int rowBorderType,columnBorderType;
		vector<int>borderTab;
		int borderElemSize;
		vector<uchar>ringBuf;
		vector<uchar>srcRow;
		vector<uchar>constBorderValue;
		vector<uchar>constBorderRow;
		int bufStep,startY,startY0,endY,rowCount,dstY;
		vector<uchar*>rows;

		Ptr<BaseFilter>filter2D;
		Ptr<BaseRowFilter>rowFilter;
		Ptr<BaseColumnFilter>ColumnFilter;
};

【3】OpenCV中blur函数源码

void cv::blur(InputArray src,OutputArray dst,Size ksize,Point anchor,int borderType)
	{
		boxFilter(src,dst,-1,ksize,anchor,true,borderType);
	}

1.10.OpenCV中GaussianBlur函数源码

void cv::GaussianBlur(InputArray _src,OutputArray _dst,Size ksize,double siama1,double sigma2,int borderType)
{
	//复制形参Mat数据到临时变量
	Mat src=_src.getMat();
	_dst.create(src.size(),src.type());
	Mat dst=_dst.getMat();

	//处理边界选项不为BORDER_CONSTANT时的情况
	if(borderType!=BORDER_CONSTANT)
	{
		if(src.rows==1)
			ksize.height=1;
		if(src.cols==1)
			ksize.width=1;
	}

	//若ksize长宽都为1,将源图复制给目标图
	if(ksize.width==1&&ksize.height==1)
	{
		src.copyTo(dst);
		return;
	}

	#ifdef HAVE_TEGRA_OPTIMIZATION
		if(sigma1==0&&sigma2==0&&tegra::gaussian(src,dst,ksize,borderType)
			return;
	#endif

	#if defined HAVE_IPP&&(IPP_VERSION_MOJOR>=7)
		if(src.type()==CV_32F1&&sigma1==sigma2&&ksize.width==ksize.height&&sigma1!=0.0)
		{
			IppiSize roi=(src.cols,src.rows);
			int bufSize=0;
			ippiFilterGaussGetBufferSize_32f_CLR(roi,ksize.width,&bufSize0;
			AutoBuffer<uchar>buf(bufSize+128);
			if(ippiFilterGaussBorder_32f_CLR((const Ipp32f*)src.data,(int)src.step,(Ipp32f*)dst.data,(int)dst.step,roi,ksize.width,(Ipp32f)sigma1,(IppoBorderType)borderType,0.0,alignPtr(&buf[0],32))>=0)
			return;
			}
	#endif

	Ptr<FilterEngine> f=createGaussianFilter(src.type(),ksize,sigma1,sigma2,borderType);
	f->apply(src,dst);
	}

1.11.线性滤波核心API函数

【1】方框滤波:boxFilter函数
boxFilter的函数作用是使用方框滤波(box filter)来模糊一张图片,由src输入,dst输出。

void boxFilter(InputArray src,OutputArray dst,int ddepth,Size ksize,Point anchor=Point(-1,-1),bool normalize=true,int borderType=BORDER_DEFAULT)

第一个参数:InputArray类型的src,输入图像,即源图像,填Mat类的对象。该函数对通道是独立处理的,且可以处理任意通道数的图片。但需要注意,待处理的图片深度应该为CV_8U、CV_16U、CV_16S、CV_32F以及CV_64F之一。
第二个参数:OutputArray类型的dst,即目标图像,需要和源图像有一样的尺寸和类型。
第三个参数:int类型的ddepth,输出图像的深度。“-1”代表使用原图深度,即src.depth()。
第四个参数:Size类型的ksize,内核的大小,一般用Size(w,h)的写法来表示内核的大小(其中,w为像素宽度,h为像素高度)。
第五个参数:Point类型的anchor,表示锚点(即被平滑的那个点),注意它有默认值Point(-1,-1)。如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。
第六个参数:bool类型的normalize,默认值为true,一个标识符,表示内核是否被其区域归一化(normalized)了。
第七个参数:int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT。

Mat image=imread("2.jpg");
Mat out;
boxFilter(image,out,-1,Size(5,5);
#include
#include
#include

using namespace cv;

int main()
{
	Mat image=imread("2.jpg");
	namedWindow("方框滤波【原图】“);
	namedWindow("方框滤波【效果图】”);

	imshow("方框滤波【原图】“,image);
	 Mat out;
	 boxFilter(image,out,-1,Size(5,5));

	imshow("方框滤波【效果图】“,out);

	waitKey(0);
}

【2】均值滤波:blur函数
blur的作用是对输入的图像src进行均值滤波后用dst输出。

void blur(InputArray src,OutputArray dst,Size ksize,Point anchor=Point(-1,-1),int borderType=BORDER_DEFAULT)

第一个参数:InputArray类型的src,输入图像,即源图像,填Mat类的对象。该函数对通道是独立处理的,且可以处理任意通道数的图片。但需要注意,待处理的图片深度应该为CV_8U、CV_16U、CV_16S、CV_32F以及CV_64F之一。
第二个参数:OutputArray类型的dst,即目标图像,需要和源图像有一样的尺寸和类型。
第三个参数:Size类型的ksize,内核的大小,一般用Size(w,h)的写法来表示内核的大小(其中,w为像素宽度,h为像素高度)。
第四个参数:Point类型的anchor,表示锚点(即被平滑的那个点),注意它有默认值Point(-1,-1)。如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。
第五个参数:int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT。

Mat image=imread("1.jpg");

Mat out;
blur(image,out,Size(7,7));
#include
#include
#include

using namespace cv;

int main()
{
	Mat image=imread("1.jpg");
	namedWindow("均值滤波【原图】“);
	namedWindow("均值滤波【效果图】”);

	imshow("均值滤波【原图】“,image);
	 Mat out;
	blur(image,out,-1,Size(7,7));

	imshow("均值滤波【效果图】“,out);

	waitKey(0);
}

【3】高斯滤波:GaussianBlur函数
GaussianBlur函数的作用是用高斯滤波器来模糊一张图片,对输入的图像src进行高斯滤波后用dst输出。

void GaussianBlur(InputArray src,OutputArray dst,Size ksize,double sigmaX,double sigmaY=0,intborderType=BORDER_DEFAULT)

第一个参数:InputArray类型的src,输入图像,即源图像,填Mat类的对象。该函数对通道是独立处理的,且可以处理任意通道数的图片。但需要注意,待处理的图片深度应该为CV_8U、CV_16U、CV_16S、CV_32F以及CV_64F之一。
第二个参数:OutputArray类型的dst,即目标图像,需要和源图像有一样的尺寸和类型。
第三个参数:Size类型的ksize,内核的大小,一般用Size(w,h)的写法来表示内核的大小(其中,w为像素宽度,h为像素高度)。
第四个参数:double类型的sigmaX,表示高斯核函数在X方向的标准偏差。
第五个参数:double类型的sigmaY,表示高斯核函数在Y方向的标准偏差。若sigmaY为零,就将它设为sigmaX,如果sigmaX和sigmaY都是0。
第六个参数:int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT。

Mat image=imread("1.jpg");

Mat out;
GaussianBlur(image,out,Size(5,5),0,0);
#include
#include
#include

using namespace cv;

int main()
{
	Mat image=imread("1.jpg");
	namedWindow("高斯滤波【原图】“);
	namedWindow("高斯滤波【效果图】”);

	imshow("高斯滤波【原图】“,image);
	 Mat out;
	GaussianBlur(image,out,Size(5,5),0,0);

	imshow("高斯滤波【效果图】“,out);

	waitKey(0);
}

1.12.图像线性滤波综合示例

二、非线性滤波:中值滤波、双边滤波

2.1.非线性滤波

在很多情况下,使用邻域像素的非线性滤波会得到更好的效果。比如在噪声是散粒噪声而不是高斯噪声,即图像偶尔会出现很大的值的时候,用高斯滤波器对图像进行模糊的话,噪声像素是不会被去除的,他们只是转换为更为柔和但仍然可见的散粒。

2.2.中值滤波

中值滤波(Median filter)是一种典型的非线性滤波技术,基本思想是用像素点领域灰度值的中值来代替该像素点的灰度值,该方法在去除脉冲噪声、椒盐噪声的同时又能保留图像的边缘细节。

中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,其基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值得中指代替,让周围得像素值接近真实值,从而消除孤立得噪声点。这对于斑点噪声(speckle noise)和椒盐噪声(salt-and-pepper noise)来说尤其有用,因为它不依赖于邻域内那些与典型值差别很大得值。中值滤波器在处理连续图像窗函数时与线性滤波器得工作方式类似,但滤波过程却不再是加权运算。

中值滤波在一定的条件下可以克服常见线性滤波器,如最小均方滤波、方框滤波器、均值滤波等带来的图像细节模糊,而且对滤除脉冲干扰及图像扫描噪声非常有效,也常用于保护边缘信息。保存边缘的特性使它在不希望出现边缘模糊的场合也很有用,是非常经典的平滑噪声处理方法。

中值滤波与均值滤波器比较
优势:在均值滤波器中,由于噪声成分被放入平均计算中,所以输出受到了噪声的影响。但在中值滤波器中,由于噪声成分很难选上,所以几乎不会影响到输出。
劣势:中值滤波花费的时间是均值滤波的5倍以上。

中值滤波选择每个像素的邻域像素中的中值作为输出,或者说中值滤波将每一像素点的灰度值设置为该点某领域窗口内的所有像素点灰度值的中值。

具体操作:
1)按强度值大小排列像素值;
2)选择排序像素集的中间值作为点的新值。
一般采用奇数点的邻域来计算中值,但像素点数为偶数时,中值就取排序像素中间两点的平均值。

中值滤波在一定条件下,可以客服线性滤波器(如均值滤波等)所带来的图像细节模糊,对滤除脉冲干扰即像素扫描噪声最为有效,而且在实际运算过程中并不需要图像的统计特性,也给计算带来不少方便。但是对一些细节(特别是细、尖顶等)多的图像不太适合。

2.3.双边滤波

双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的,具有简单、非迭代、局部的特点。

2.4.非线性滤波相关核心API函数

【1】中值滤波:medianBlur函数

【2】双边滤波:bilateralFilter函数

2.5.OpenCV中5种图像滤波综合

三、形态学滤波(1):腐蚀与膨胀

3.1.形态学概述

形态学(morphology)一词通常表示生物学的一个分支,该分支主要研究动植物的形态和结构。而我们图像粗粒中的形态学,往往指的是数学形态学。

数学形态学(Mathematical morphology)是一门建立在格论和拓扑学基础之上的图像分析学科,是数学形态学图像处理的基本理论。其基本的运算包括:二值腐蚀和膨胀、二值开闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat变换、颗粒分析、流域变换、灰值腐蚀和膨胀、灰值开闭运算、灰值形态学梯度等。

3.2.膨胀

3.3.腐蚀

3.4.相关OpenCV源码

3.5.相关核心API函数

3.6.综合示例:腐蚀与膨胀

四、形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽

4.1.开运算

4.2.闭运算

4.3.形态学梯度

4.4.顶帽

4.5.黑帽

4.6.形态学滤波OpenCV源码

4.7.核心API函数:morphologhEx()

4.8.形态学操作使用

4.9.综合使用形态学滤波

五、漫水填充

5.1.漫水填充的定义

5.2.漫水填充的基本思想

5.3.实现漫水填充算法:floodFill函数

5.4.漫水填充示例

六、图像金字塔与图像尺寸缩放

6.1.概论

6.2.图像金字塔

6.3.高斯金字塔

6.4.拉普拉斯金字塔

6.5.尺寸调整:resize()函数

6.6.图像金字塔相关的API函数

6.7.图像金字塔与图片尺寸缩放示例

七、阈值化

7.1.固定阈值操作:Threshold()函数

7.2.自适应阈值操作:adaptiveThreshold()函数

7.3.基本阈值操作示例

你可能感兴趣的:(c++,OpenCV,opencv,图像处理)