opencv学习笔记九:滤波与卷积

在之前我们都是把图像当作图像数组进行处理的,而滤波与卷积同样是在图像结构体上根据图像像素之间的联系对之进行高级处理。而非将图像当作一个整体进行颠倒,切割等操作。

滤波器(也称核)

所谓滤波器,可以简单理解为对图像的每一个像素点(锚点)及其附近的点进行卷积,而所谓卷积,就是以一个特定大小的核(比如5*5)对原像素值进行乘积,而对整幅图像进行滤波操作,便会得到一个新的图像。

阈值化操作

我们在对一幅图像进行完一些基本处理之后,可能希望可以将高于某一个像素值的像素点置为零或某一定值,而其他像素值不变等等类似的操作,这就是设定阈值。

cv::threshold()函数

	cv::threshold(
		cv::InputArray  src,
		cv::OutputArray  dst,
		double			 thresh,
		double			 maxValue,
		int				thresholdType
	);

在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
	Mat src,dst;
	src = imread("1.jpg",0);
	imshow("原图", src);
	
	threshold(src,dst,40,255,0);
	imshow("阈值化操作", dst);

	waitKey(0);
	return 0;
}

在这里插入图片描述
除了自己设置阈值,还可以使用自适应阈值操作函数adaptiveThreshold(),在这个函数中,阈值可以自己产生:

cv::adaptiveThreshold(
	cv::InputArray		src,			//输入图像
	cv::OutputArray		dst,			//输出图像
	double			    maxValue,       //当thresholdType参数为THRESH_BINARY或者THRESH_BINARY_INV时的最大值
	int					adaptiveMethod,//自适应阈值算法方法,有两种:ADAPTIVE_THRESH_MEAN_C或者ADAPTIVE_THRESH_GAUSSIAN_C
	int				    thresholdType,//取阈值类型,THRESH_BINARY或者THRESH_BINARY_INV
	int					blockSize,  //用来计算阈值的像素邻域大小:3,5,7...
	double				C    //可调参数
);

该函数一些参数和上面的阈值函数是一样的,下面我们写个程序读取一张单通道图像,再对其进行阈值化操作和自适应阈值操作,来看看二者的区别:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
	Mat src,dst1,dst2;    
	src = imread("1.jpg",0);  //读入一张图像
	imshow("原图", src);  //显示该图像
	//阈值化操作,取阈值类型为二值化阈值操作
	threshold(src, dst1,40,255,0);    
	imshow("阈值化操作", dst1);    
	//自适应阈值,取阈值类型为反二值化操作
	adaptiveThreshold(src, dst2, 255, ADAPTIVE_THRESH_MEAN_C, 1, 3, 10);
	imshow("自适应阈值化操作", dst2);
	
	waitKey(0);
	return 0;
}

运行效果图:
在这里插入图片描述
中间一幅为自适应阈值处理后的图像,可以看到效果还是比较不错的。

图像平滑

平滑也称“模糊”,是一种简单而又常用的图像处理操作。平滑图像目的很多,例如降低噪声或伪影。
#图像平滑化//滤波操作:
消除图像中的噪声成分叫做图像的平滑化或滤波操作:信号和图像的能量大多计征再幅度谱的低频和中频,而在高频区有用信息往往被噪声掩盖,降低高频成分幅度就可以起到降噪的功能。
图像滤波目的有两个:一个是抽出对象的特征作为图像识别的特征模式,另一个是为适应图像处理的要求,消除图像数字化时混入的噪声。
#平滑滤波:
平滑滤波是低频增强的空间滤波技术,它的目的有两类:一类是模糊,一类是消除噪声。
关于滤波器,滤波器时我们实现上述功能的工具,opencv中提供了物种常用的滤波器:

  1. 方框滤波——BoxBlur()函数
  2. 均值滤波(邻域平均滤波)——Blur()函数
  3. 高斯滤波——GaussianBlur()函数
  4. 中值滤波——medianBlur()函数
  5. 双边滤波——bilateralFilter()函数
    下面贴个程序演示一下各个滤波器的效果与区别:
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
	Mat src,dst1,dst2,dst3;
	src = imread("2.jpg", 1);
	blur(src, dst1, Size(5, 5));  //均值滤波
	boxFilter(src, dst2, src.depth(), Size(5, 5));  //方框滤波
	GaussianBlur(src, dst3, Size(5, 5), 0, 0); //高斯滤波
	
	imshow("原图", src);
	imshow("均值滤波", dst1);
	imshow("方框滤波", dst2);
	imshow("高斯滤波", dst3);

	waitKey(0);
	return 0;
}

在这里插入图片描述

图像形态学

膨胀和腐蚀

最基础的形态学操作就是腐蚀和膨胀,他们在消除噪声,元素分割以及连接等方面有广泛应用。
膨胀是一种卷积操作,它将目标像素值替换为卷积核覆盖区域的局部最大值。图中黑色区域并不是黑色像素点,而是表示高亮部分。
在这里插入图片描述
与膨胀对应,腐蚀是与之相反的操作,它是计算核覆盖区域内的局部最小值,如图:
在这里插入图片描述
简单来说,膨胀就是扩大白色(高亮)像素,腐蚀就是扩大黑色像素;另外,膨胀填充凹面,腐蚀消除突起。下面是函数实现:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
	Mat src, dst1, dst2;
	src = imread("3.jpg", 1);

	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));   //定义核大小
	erode(src, dst1, element);   //腐蚀操作
	dilate(src, dst2, element);  //膨胀操作

	imshow("原图", src);
	imshow("腐蚀", dst1);
	imshow("膨胀", dst2);

	waitKey(0);
	return 0;
}

在这里插入图片描述

自定义核

在上面代码中,我们看到里面有一行

Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));   //自定义核大小

这是自定义一个5*5大小的核,用到函数getStructuringElement();

cv::getStructuringElement(
	int        shape,    #生成核的形状
	cv::Size   ksize,    #生成核的大小
	cv::Point  anchor = cv::Point(-1,-1)  #默认锚点在元素中心
);
#第一个参数:
MORPH_RECT      矩形    
MORPH_ELLIPSE   椭圆形
MORPH_CROSS     交叉形

通用形态学函数

当处理的对象是二值图像和像素只可能是开(>0)或关(=0)的图像腌膜时,基本的腐蚀和膨胀操作就够了,需要对灰度图或者彩色图进行处理时,一些其他的操作就非常有用,这些操作可以通过cv::morphologyEx()实现:
在这里插入图片描述

										是否需要临时图像
	cv::MOP_OPEN      开操作                否
	cv::MOP_CLOSE     闭操作                否
	cv::MOP_GRADIENT  形态学梯度          总是需要
	cv::MOP_TOPHAT    顶帽操作        就地调用需要(src=dst)
 	cv::MOP_BLACKHAT  低帽操作		  就地调用需要(src=dst)

开操作和闭操作

dst = open(src,element) = dilate(erode(src,element),element);
开操作是对图像先腐蚀,再对腐蚀的图像进行膨胀的操作
dst = close(src,element) = erode(dilate(src,element),element);
闭操作是对图像先膨胀,再对膨胀后的图像进行腐蚀的操作

形态学梯度

dst = morph_grad(src) = dilate(src) - erode(src) ;
形态学梯度就是膨胀操作的结果减腐蚀操作的结果,得到原图像的边缘;

顶帽和黑帽

dst = tophat(src) = src - open(src) ;
顶帽操作显示与邻域相比更亮的部分。可以提取图像中的明亮局部
dst = blackhat(src) = close(src) - src ;
黑帽操作显示与邻域相比更暗的部分。可以提取图像中的暗洞

发布了26 篇原创文章 · 获赞 40 · 访问量 3648

猜你喜欢

转载自blog.csdn.net/qq_43667130/article/details/103054852