OpenCV要点总结——第六章 图像处理(一)

Note:

1消除图像中的噪声成分叫做图像的平滑化或滤波操作。

2信号或图像的能量大部分集中在幅度谱的低频和中频段,而在较高频段,有用信息经常被噪声淹没。

3滤波:低通就是模糊,高通就是锐化。

1.线性滤波

(1)方框滤波:boxFilter    用不同权重结合一个小邻域的像素,得到处理效果。

boxFilter( g_srcImage, g_dstImage1, -1,Size( g_nBoxFilterValue+1, g_nBoxFilterValue+1));
		//src  dst  ddpeth=-1表示使用原图深度  内核大小

(2)均值滤波:blur         加权系数相等的方框操作即归一化。

blur( g_srcImage, g_dstImage2, Size( g_nMeanBlurValue+1, g_nMeanBlurValue+1), Point(-1,-1));
		//src   dst   内核大小   锚点(被平滑的点)在中心


(3)高斯滤波:GaussianBlur       对整幅图加权平均。//ksize参数为奇数

GaussianBlur( g_srcImage, g_dstImage3, Size( g_nGaussianBlurValue*2+1, g_nGaussianBlurValue*2+1 ), 0, 0);
		//src   dst  内核大小  x方向的标准偏差   y方向的标准偏差
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace std;
using namespace cv;


//-----------------------------------【全局变量声明部分】-------------------------------
Mat g_srcImage,g_dstImage1,g_dstImage2,g_dstImage3;//存储图片的Mat类型
int g_nBoxFilterValue=3;  //方框滤波参数值
int g_nMeanBlurValue=3;  //均值滤波参数值
int g_nGaussianBlurValue=3;  //高斯滤波参数值


//-----------------------------------【全局函数声明部分】-------------------------------
//三个轨迹条的回调函数
static void on_BoxFilter(int, void *);		//方框滤波
static void on_MeanBlur(int, void *);		//均值滤波
static void on_GaussianBlur(int, void *);			//高斯滤波


//-----------------------------------【main( )函数】----------------------------------
int main(   )
{
	//改变console字体颜色
	system("color 5F");  

	// 载入原图
	g_srcImage = imread( "1.jpg", 1 );
	if( !g_srcImage.data ) { printf("Oh,no,读取srcImage错误~! \n"); return false; }

	//克隆原图到三个Mat类型中
	g_dstImage1 = g_srcImage.clone( );
	g_dstImage2 = g_srcImage.clone( );
	g_dstImage3 = g_srcImage.clone( );

	//显示原图
	namedWindow("【<0>原图窗口】", 1);
	imshow("【<0>原图窗口】",g_srcImage);

//轨迹条创建
	//=================【<1>方框滤波】==================
	//创建窗口
	namedWindow("【<1>方框滤波】", 1);
	//创建轨迹条
	createTrackbar("内核值:", "【<1>方框滤波】",&g_nBoxFilterValue, 40,on_BoxFilter );
		//滑条名 所属窗口 初始值 最大值 函数
	on_BoxFilter(g_nBoxFilterValue,0);
	//================================================

	//=================【<2>均值滤波】==================
	//创建窗口
	namedWindow("【<2>均值滤波】", 1);
	//创建轨迹条
	createTrackbar("内核值:", "【<2>均值滤波】",&g_nMeanBlurValue, 40,on_MeanBlur );
	on_MeanBlur(g_nMeanBlurValue,0);
	//================================================

	//=================【<3>高斯滤波】=====================
	//创建窗口
	namedWindow("【<3>高斯滤波】", 1);
	//创建轨迹条
	createTrackbar("内核值:", "【<3>高斯滤波】",&g_nGaussianBlurValue, 40,on_GaussianBlur );
	on_GaussianBlur(g_nGaussianBlurValue,0);
	//================================================


	//输出一些帮助信息
	cout<<endl<<"\t运行成功,请调整滚动条观察图像效果~\n\n"
		<<"\t按下“q”键时,程序退出。\n";

	//按下“q”键时,程序退出
	while(char(waitKey(1)) != 'q') {}

	return 0;
}

//滤波操作
//-----------------------------【on_BoxFilter( )函数】------------------------------------
//	描述:方框滤波操作的回调函数
//-----------------------------------------------------------------------------------------------
static void on_BoxFilter(int, void *)
{
	//方框滤波操作
	boxFilter( g_srcImage, g_dstImage1, -1,Size( g_nBoxFilterValue+1, g_nBoxFilterValue+1));
		//src  dst  ddpeth=-1表示使用原图深度  内核大小
	//显示窗口
	imshow("【<1>方框滤波】", g_dstImage1);
}


//-----------------------------【on_MeanBlur( )函数】------------------------------------
//	描述:均值滤波操作的回调函数
//-----------------------------------------------------------------------------------------------
static void on_MeanBlur(int, void *)
{
	//均值滤波操作
	blur( g_srcImage, g_dstImage2, Size( g_nMeanBlurValue+1, g_nMeanBlurValue+1), Point(-1,-1));
		//src   dst   内核大小   锚点(被平滑的点)在中心
	//显示窗口
	imshow("【<2>均值滤波】", g_dstImage2);
}


//-----------------------------【ContrastAndBright( )函数】------------------------------------
//	描述:高斯滤波操作的回调函数
//-----------------------------------------------------------------------------------------------
static void on_GaussianBlur(int, void *)
{
	//高斯滤波操作
	GaussianBlur( g_srcImage, g_dstImage3, Size( g_nGaussianBlurValue*2+1, g_nGaussianBlurValue*2+1 ), 0, 0);
		//src   dst  内核大小  x方向的标准偏差   y方向的标准偏差
	//显示窗口
	imshow("【<3>高斯滤波】", g_dstImage3);
}

2.非线性滤波

(1)中值滤波medianBlur  原理:数字图像或数字序列中一点的值用 该点的一个邻域中所有点得中值代替。

                                             如3*3的函数窗,计算【i,j】为中心的像素中值。

                                            1按强度值大小排列像素点,2选择排序像素集的中间值作为点【i,j】新值。

static void on_MedianBlur(int, void *)
{
	medianBlur ( g_srcImage, g_dstImage4, g_nMedianBlurValue*2+1 );
    //src  dst  ksize孔径的线性尺寸(必须是大于1的奇数)
	imshow("【<4>中值滤波】", g_dstImage4);
}

(2)双边滤波bilateralFilter    优点:边缘保存较好

                                               缺点:由于保存了过多的高频信息,只能对低频信息进行较好的滤波。

static void on_BilateralFilter(int, void *)
{
	bilateralFilter ( g_srcImage, g_dstImage5, g_nBilateralFilterValue, g_nBilateralFilterValue*2, g_nBilateralFilterValue/2 );
//src  dst  每个像素邻域直径  颜色空间参数  标注方差  
	imshow("【<5>双边滤波】", g_dstImage5);
}

3.形态学滤波

(1)腐蚀和膨胀 erode和dilate

note:膨胀和腐蚀都是对白色高亮部分而言

             多数情况下,核是一个小的,中间带有参考点和实心正方形或者圆盘。其实可以把核视为模板或掩码。

腐蚀是求局部最小操作;膨胀是求局部最大操作

static void on_ErodeDilate(int, void*)
{
	//偏移量的定义
	int offset = g_nErodeDilateNum - g_nMaxIterationNum;	//偏移量
	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
	//自定义核
	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset*2+1, Absolute_offset*2+1), Point(Absolute_offset, Absolute_offset) );
        //核形状 (MORPH_ELLIPSE椭圆   MORPH_CROSS十字)  核大小  锚点
	//进行操作
	if( offset < 0 )
		erode(g_srcImage, g_dstImage, element);//src  dst  核
	else
		dilate(g_srcImage, g_dstImage, element);
	//显示图像
	imshow("【腐蚀/膨胀】",g_dstImage);
}

(2)开运算和闭运算 morphologyEx-->MORPH_OPEN和MORPH_LOSE

开运算:先腐蚀后膨胀。 可消除小物体,在纤细点处分离物体,并且在平滑较大物体的边界的同时不明显改变提及。

闭运算:先膨胀后腐蚀 。 可排除小型黑洞。

//-----------------------------------【on_OpenClose( )函数】----------------------------------
static void on_OpenClose(int, void*)
{
	//偏移量的定义
	int offset = g_nOpenCloseNum - g_nMaxIterationNum;//偏移量
	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
	//自定义核
	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset*2+1, Absolute_offset*2+1), Point(Absolute_offset, Absolute_offset) );
	//进行操作
	if( offset < 0 )
			morphologyEx(g_srcImage, g_dstImage, MORPH_OPEN, element);
	else
			morphologyEx(g_srcImage, g_dstImage, MORPH_CLOSE, element);
		


	//显示图像
	imshow("【开运算/闭运算】",g_dstImage);
}

(3)顶帽和黑帽morphologyEx-->MORPH_TOPHAT和MORPH_BLACKHAT

顶帽:原图像与开运算的结果图之差。可分离比邻近点亮一些的斑块;微小物品比较有规律的情况下,可以使用顶帽来背景提取。

黑帽:闭运算的结果图与原图之差。可分离比邻近点暗一些的板块。

//-----------------------------------【on_TopBlackHat( )函数】--------------------------------
static void on_TopBlackHat(int, void*)
{
	//偏移量的定义
	int offset = g_nTopBlackHatNum - g_nMaxIterationNum;//偏移量
	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
	//自定义核
	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset*2+1, Absolute_offset*2+1), Point(Absolute_offset, Absolute_offset) );
	//进行操作
	if( offset < 0 )
		morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT , element);
	else
		morphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);
	//显示图像
	imshow("【顶帽/黑帽】",g_dstImage);
}

(4)形态学梯度morphologyEx-->MORPH_GRADIENT

Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));  
	//进行形态学操作
	morphologyEx(image, image, MORPH_GRADIENT, element);//核

猜你喜欢

转载自blog.csdn.net/Raoodududu/article/details/81938192