欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-12 10:07:26
...

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);//核

 

相关标签: 滤波