【OpenCV学习笔记 009】图像滤波
来源:互联网 发布:Ubuntu 软件怎么打不开 编辑:程序博客网 时间:2024/05/01 13:44
滤波是信号处理及图像处理中的一个基本操作,目的是选择性地提取图像中被认为传达重要信息的部分。它可以去除图像中的噪声,提取刚兴趣的视觉特征,允许图像重采样,理论基础源于广义的信号与系统理论。我们观察一副图像时,可以看到不同的灰度(或彩色值)在图像中的分布,一些灰度强度变化慢,一些灰度强度变化快。频域就是观察图像中变化的频率所构成的一种描述图像,空间域则是观察灰度分布来描述一幅图像。频域分析按照高频到低频的次序,分解图像到频率内容。低频对应区域的图像强度变化缓慢,高频变换快速,如可用来明确表示频谱的傅里叶(Fourier)变换或余弦(Cosine)变换,图像是二维的因此它包含垂直频率和水平频率。低通(Low-pass)滤波器去除图像中的高频成分,高通(High-pass)滤波器去除了低频成分。
一、低通滤波器
1.概念及原理
(1)cv::blur是一个非常简单的低通滤波器,方案是将每个像素替换为相邻像素的平均值,这样就使快速的强化变换变为平缓的过渡。当滤波器的作用相当于将一个像素替换为相邻像素的加权总和时,我们称它是线性的。矩阵可以表示滤波器的不同权重,矩阵中的每一项都是对应位置的相乘因子,这个矩阵被称为核(Kernel)或掩码(Mask)。对于3x3的箱式滤波器,它对应的核是
应用一个线性滤波器就是沿着图像的每个像素移动一个核,并且把每个对应的像素乘上关联的权重。在数学上这一过程被称作卷积(Convolution)。
(2)cv::GaussianBlur高斯滤波器中,像素的权重和它离开中心像素点距离成正比。一维高斯函数公式
A:使不同权重之和为1的归一化系数。σ(西格玛):数值控制高斯函数的高度,值越大函数越平坦。想应用二维高斯滤波,可以利用高斯滤波器的分离特性先对图像的行应用一维高斯滤波器再对图像的列应用相同的一维高斯滤波器。
2.实验
源码示例
#include<iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include<imgproc/imgproc.hpp> using namespace std;using namespace cv;int main(){Mat image = imread("girl.jpg");namedWindow("image");imshow("image", image);Mat resultBlur;blur(image, resultBlur, Size(5, 5));namedWindow("resultBlur");imshow("resultBlur", resultBlur);//高斯滤波器Mat resultGauss;GaussianBlur(image, resultGauss, Size(5, 5), 1.5);namedWindow("resultGauss");imshow("resultGauss", resultGauss);waitKey(0);return 0;}
运行结果
可以看出低通滤波器效果是对图像进行模糊或平滑,因为它减弱了物体边缘处可见的快速变化。
二、中值滤波器
1.概念及原理
(1)中值滤波器无法表示为一个核矩阵,即是非线性的。是将该像素及它的相邻区域组成一组数组,计算这组数组的中值并用中值替换当前的像素值。因此该滤波器在去除椒盐噪点效果甚好,但是椒盐噪点对均值滤波器的影响非常大。
2.实验
使用中值滤波器去除椒盐噪点。
源码示例
#include<iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include<imgproc/imgproc.hpp> using namespace std;using namespace cv;void salt(cv::Mat& image, int n){for (int k = 0; k<n; k++){int i = rand() % image.cols;int j = rand() % image.rows;if (image.channels() == 1){image.at<uchar>(j, i) = 255;}else{image.at<cv::Vec3b>(j, i)[0] = 255;image.at<cv::Vec3b>(j, i)[1] = 255;image.at<cv::Vec3b>(j, i)[2] = 255;}}}int main(){Mat image = imread("girl.jpg");salt(image, 5000);namedWindow("image");imshow("image", image);//中值滤波Mat resultMedianBlur;medianBlur(image, resultMedianBlur, 5);namedWindow("resultMedianBlur");imshow("resultMedianBlur", resultMedianBlur);waitKey(0);return 0;}处理效果
三、Sobel滤波器检测边缘
1.概念及原理
(1)使用高通滤波器强调图像中的高频分量进行边缘检测。Sobel运算水平滤波器和垂直滤波器能够生成8位图像(CV_8U),在这种表示中零值对应的灰度值为128,负数表示为较暗的像素,整数表示为较亮的像素。
(2)Sobel算子是一种经典的边缘检测线性滤波器,它基于一个简单的3x3核。
我们把图像看成二维函数,Sobel算子可被认为是图像在垂直和水平方向变化的测量。在数学中称为梯度。被定义为由函数在两个正交方向上的一阶导数组成的二维向量:
由于梯度是一个二维向量,它拥有距离和方向。梯度向量的距离给出变化的幅度,通常使用欧拉距离(L2距离)。
2.实验
使用Sobel滤波器进行边缘检测。
源码示例
#include<iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include<imgproc/imgproc.hpp> using namespace std;using namespace cv;int main(){Mat image = imread("girl.jpg");namedWindow("image");imshow("image", image);//水平滤波器Mat sobelX;Mat sobelY;//8位图像(CV_8U)表示结果Sobel(image, sobelX, CV_8U, 1, 0, 3, 0.4, 128);Sobel(image, sobelY, CV_8U, 0, 1, 3, 0.4, 128);namedWindow("sobelX");imshow("sobelX", sobelX);namedWindow("sobelY");imshow("sobelY", sobelY);//计算Sobel范式Sobel(image, sobelX, CV_16S, 1, 0);Sobel(image, sobelY, CV_16S, 0, 1);Mat sobelNorm;sobelNorm = abs(sobelX) + abs(sobelY);//搜寻sobel极大值double sobmin, sobmax;minMaxLoc(sobelNorm, &sobmin, &sobmax);//变换为8位图像Mat sobelImage;sobelNorm.convertTo(sobelImage, CV_8U, -255. / sobmax, 255);namedWindow("sobelImage");imshow("sobelImage", sobelImage);//阈值化得到二值图像Mat sobelThresholded;threshold(sobelImage, sobelThresholded, 220, 255, THRESH_BINARY);namedWindow("sobelThresholded");imshow("sobelThresholded", sobelThresholded);waitKey(0);return 0;}实验结果
水平和垂直Sobel运算后的结果
Sobel滤波器范式和通过阈值(选择合适的阈值有难度)化得到的二值图
四、图像的拉普拉斯变换
1.概念及原理
拉普拉斯是另外一只基于图像导数的高通线性滤波器,它是通过计算二阶导数来衡量图像的弯曲度。2D函数的拉普拉斯变换定义的是二阶导数之和。
最简单的形式可以使用3x3核近似描述。
2.实验
源码示例
#include<iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include<imgproc/imgproc.hpp> using namespace std;using namespace cv;//拉普拉斯变换class LaplacianZC{public:Mat img;//原图Mat laplace;//包含Laplacian的32位浮点图像int aperture;public:LaplacianZC() : aperture(3){};//设置卷积核的大小void setAperture(int a){aperture = a;}//计算浮点数LaplacianMat computeLaplacian(const Mat&image){//计算LaplacianLaplacian(image, laplace, CV_32F, aperture);//保留图像的局部备份(用于零点交叉)img = image.clone();return laplace;}//返回8位图像存储的Laplacian结果,零点交叉于灰度值128//如果没有指定scale参数,那么最大值将缩放至强度255//必须在调用它之前调用computeLaplacianMat getLaplacianImage(double scale = -1.0){if (scale<0){double lapmin, lapmax;minMaxLoc(laplace, &lapmin, &lapmax);scale = 127 / max(-lapmin, lapmax);}Mat laplaceImage;laplace.convertTo(laplaceImage, CV_8U, scale, 128);return laplaceImage;}//得到零点交叉的二值图像,如果相邻像素的乘积小于threshold,那么相邻交叉将被忽略Mat getZeroCrossings(float threshold = 1.0){//创建迭代器Mat_<float>::const_iterator it = laplace.begin<float>()+laplace.step1();Mat_<float>::const_iterator itend = laplace.end<float>();Mat_<float>::const_iterator itup = laplace.begin<float>();//初始化为白色的二值图像Mat binary(laplace.size(), CV_8U, Scalar(255));Mat_<uchar>::iterator itout = binary.begin<uchar>() + binary.step1();//对输入阈值取反threshold*= -1.0;for (; it!=itend;++it,++itup,++itout){//如果相邻像素的乘积为负数,那么符号发生改变if (*it**(it - 1) < threshold)*itout = 0;//水平方向零点交叉else if (*it**itup < threshold) *itout = 0;//垂直方向零点交叉}return binary;}};int main(){Mat image = imread("girl.jpg",0);namedWindow("image");imshow("image", image);LaplacianZC laplacian;//图像7x7拉普拉斯变换laplacian.setAperture(7);Mat flap = laplacian.computeLaplacian(image);/*laplacian.laplace = laplacian.getLaplacianImage();namedWindow("laplace");imshow("laplace", laplacian.laplace);*///零交叉的二值图像laplacian.laplace = laplacian.getZeroCrossings();namedWindow("zeroCross");imshow("zeroCross", laplacian.laplace);waitKey(0);return 0;}
图像的7x7拉普拉斯变换
图像零交叉的二值图像
【OpenCV学习笔记 009】图像滤波 配套的源码下载
- 【OpenCV学习笔记 009】图像滤波
- 【OpenCV学习笔记】十五、图像滤波
- opencv学习之图像滤波
- 图像处理学习笔记——opencv 最小值滤波
- opencv学习笔记(十八)——图像非线性滤波
- Opencv 学习笔记之图像线性滤波综合示例
- OpenCV学习笔记(十一)图像导向滤波
- OpenCV学习——图像卷积滤波
- Opencv学习——图像滤波
- opencv学习 图像低通滤波
- OpenCV学习笔记(14):形态学滤波对图像进行边缘及角点检测
- OpenCV学习笔记02--利用滚动条控制视频;高斯滤波处理图像。
- opencv学习笔记(十九)——图像滤波综合运用实例
- 【opencv学习笔记1】5种图像滤波辨析:方框、均值、高斯、中值、双边
- opencv学习笔记第五章 使用形态学滤波对图像进行开闭运算
- opencv-图像滤波
- Opencv中图像滤波
- opencv之 图像滤波
- 设置jsp页面的背景图片
- 三、Linux设备模型(3)_Uevent
- Python文件的读写
- IOS-定位地图
- 误删文件的解决办法
- 【OpenCV学习笔记 009】图像滤波
- 生产者与消费者问题
- 前台页面table表格相同数据列合并
- 读书笔记八
- 例题:反片语(UVa156)
- Android中AsyncTask的使用
- JQuery中$.ajax()方法参数详解
- xamarin axml无法预览
- 第3周项目3 求集合并集