《实用OpenCV》<五> 图像滤波(2)
2013-12-29 20:38
330 查看
模糊图像
模糊图像的第一步是在不改变太多外观的情况下减小图像的大小。模糊可以被认为一个低通滤波的操作,用一个简单直观的核矩阵来实现。图像可以被认为在两个轴方向上拥有各种频率成分。边缘拥有高的频率,而亮度改变不明显的地方拥有低频率。更具体地说,一个垂直边缘在沿水平轴表现高频率成分,反之亦然。纹理细致的地方也拥有高频率(细致的纹理是指像素亮度值在短像素距离内改变很大)。较小的图像不能很好地处理高频率。
这样想把,假设你有一张640×480的细致纹理图像,你无法在一张320×240图像中保持所有这些短间隔、高梯度的变化,因为只有四分之一的像素数量。所以当你要减小图像的大小的时候,你应该移除里面的高频成分。换言之,将其模糊。平滑那些短间隔、高梯度的变化。如果缩放前没有模糊化的话,你很可能在缩放图里看到人工痕迹。原因很简单,取决于信号理论的基本定理,即信号取样使得该信号在频率区域无限重复(注:此处翻译不太肯定,望大牛纠正)。所以如果信号有很多高频成份的话,重复的频率区域边缘会表现得相互干扰。一旦发生这种情况,信号就不能如实的修复过来。这里呢,我们的图像就是信号,通过移掉行列来调整,也就是,“下采样”。这种现象称为混淆。如果你想了解更多的话,你应该从一些电子信号处理资料来找到一些详细解释。模糊可以避免混淆因为它移除了图像的高频成分(注:对于图像生成来说,混淆会产生锯齿状的边缘或者梯阶效果)。
如果你想增加图像的大小的话,模糊也是一个很重要的后处理步骤。如果你要增加图像一倍大小,你可以每一行(列)加一空行(列)然后模糊,于是空行(列)会呈现相邻的近似的显示。
模糊化可以通过替换图像的像素为该像素在周围区域的某种均值来实现。为了有效地做到这一点,该区域保持矩形和像素周围的匀称。图像将和一个“归一化”核(矩阵)做卷积(归一化是因为我们要做平均,而不是求和)。
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
这个核认为每个像素一样重要。一个更好的核应该是与中心像素距离越大则影响越小。高斯核就是这样,是最常用的模糊核。
(注:核是线代里的概念,听似有点拗口,本想翻译成核矩阵,但不晓概念是否一样,姑且保留原意。)
1 4 6 4 1
4 16 24 16 4
6 24 36 24 6
4 16 24 16 4
1 4 6 4 1
除以所有元素的总量来“归一化”该核。你也可以通过OpenCV里的getGaussianKernel()方法来创建不同大小的高斯核。你可以马上将这些核替换到例5-1(前一篇文章里)中来模糊图像(不要忘了将核除以总数量来归一化)。然而,OpenCV也提供了更高级的方法GaussianBlur()。
例5-2 使用不同大小的高斯核来模糊图像
// Program to interactively blur an image using a Gaussian kernel of varying size // Author: Samarth Manoj Brahmbhatt, University of Pennyslvania #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace std; using namespace cv; Mat image, image_blurred; int slider = 5; float sigma = 0.3 * ((slider - 1) * 0.5 - 1) + 0.8; void on_trackbar(int, void *) { int k_size = max(1, slider); k_size = k_size % 2 == 0 ? k_size + 1 : k_size; //保证核大小为大于0的奇数 setTrackbarPos("Kernel Size", "Blurred image", k_size); sigma = 0.3 * ((k_size - 1) * 0.5 - 1) + 0.8; GaussianBlur(image, image_blurred, Size(k_size, k_size), sigma);//sigma为高斯核在X方向上的标准差,Y方向上 若未设置则等同X值 imshow("Blurred image", image_blurred); } int main() { image = imread("baboon.jpg"); namedWindow("Original image"); namedWindow("Blurred image"); imshow("Original image", image); sigma = 0.3 * ((slider - 1) * 0.5 - 1) + 0.8; GaussianBlur(image, image_blurred, Size(slider, slider), sigma); imshow("Blurred image", image_blurred); createTrackbar("Kernel Size", "Blurred image", &slider, 21, on_trackbar); while(char(waitKey(1) != 'q')) {} return 0; }
图 5-4 使用高斯核模糊图像
相关文章推荐
- 《实用OpenCV》<五> 图像滤波(4)
- 《实用OpenCV》<五> 图像滤波(1)
- 《实用OpenCV》<五> 图像滤波(3)
- 《实用OpenCV》<六> 图像中的形状(2)
- 《实用OpenCV》<六> 图像中的形状(1)
- 《实用OpenCV》<四> 图像和GUI窗口的基本操作(1)
- 《实用OpenCV》<四> 图像和GUI窗口的基本操作(2)
- 《实用OpenCV》<四> 图像和GUI窗口的基本操作(3)
- 《实用OpenCV》<四> 图像和GUI窗口的基本操作(4)
- Android NDK学习 <五> C++ 支持
- 进程控制理论<五>--进程通信方式对比
- 程序员_Java基础之<五>-线程
- Atitit.web 视频播放器classid clsid 大总结quicktime,vlc 1. Classid的用处。用来指定播放器 1 2. <object> 标签用于包含对象,比如图像、音
- 《实用OpenCV》<一> 计算机视觉及OpenCV介绍
- Android学习记录<五>
- 一步步优化JVM<五>:优化延迟或者响应时间(3)
- 【MySql】使用记录<五>
- 网络安全基础篇之<五>
- 双边滤波Matlab实现<The Bilateral Filter>
- ViewPager,RadioGroup,FragmentManager 详解 <五> Fragment,ViewPager 和ActionBar