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);//核
上一篇: filter2D函数的使用
下一篇: 一维数据的kalman滤波