模糊原理
Smooth/Blur 是图像处理中最简单和常用的操作之一
使用该操作的原因之一就为了给图像预处理时候减低噪声
使用Smooth/Blur操作其背后是数学的卷积计算
f 和g表示图像
(i,j) 坐标
h(k,l)表示卷积核(卷积算子,又称掩膜)函数
通常这些卷积算子计算都是线性操作,所以又叫线性滤波
归一化盒子滤波(均值滤波)
假设有6x6的图像像素点矩阵。
卷积过程:6x6上面是个3x3的窗口,从左向右,从上向下移动,黄色的每个像个像素点值之和取平均值赋给中心红色像素作为它卷积处理之后新的像素值。每次移动一个像素格。
均值api:
[C++] 纯文本查看 复制代码 - blur(Mat src, Mat dst, Size(xradius, yradius), Point(-1,-1));
高斯滤波
一维正态分布示意图
正态分布中,越接近中心点,取值越大,越远离中心,取值越小。
计算平均值的时候,我们只需要将"中心点"作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。正态分布显然是一种可取的权重分配模式。
上面的正态分布是一维的,而对于图像都是二维的,所以我们需要二维的正态分布。
二维的正态分布
正态分布的密度函数叫做"高斯函数"(Gaussian function)。它的一维形式是:
其中,μ是x的均值,σ是x的方差。因为计算平均值的时候,中心点就是原点,所以μ等于
根据一维高斯函数,可以推导得到二维高斯函数:
有了这个函数 ,就可以计算每个点的权重了。
获取权重矩阵
假定中心点的坐标是(0,0),那么距离它最近的8个点的坐标如下:
更远的点以此类推。
为了计算权重矩阵,需要设定σ的值。假定σ=1.5,则模糊半径为1的权重矩阵如下:
这9个点的权重总和等于0.4787147,如果只计算这9个点的加权平均,还必须让它们的权重之和等于1,因此上面9个值还要分别除以0.4787147,得到最终的权重矩阵。
除以总值这个过程也叫做”归一问题“
目的是让滤镜的权重总值等于1。否则的话,使用总值大于1的滤镜会让图像偏亮,小于1的滤镜会让图像偏暗。
计算模糊值
有了权重矩阵,就可以计算高斯模糊的值了。
假设现有9个像素点,灰度值(0-255)如下:
每个点乘以自己的权重值:
得到
将这9个值加起来,就是中心点的高斯模糊的值。
对所有点重复这个过程,就得到了高斯模糊后的图像。对于彩色图片来说,则需要对RGB三个通道分别做高斯模糊。
高斯模糊API:
[C++] 纯文本查看 复制代码 - GaussianBlur(Mat src, Mat dst, Size(11, 11), sigmax, sigmay);
其中Size(x, y), x, y 必须是正数而且是奇数
均值模糊效果图[C++] 纯文本查看 复制代码 /*
注意:
*/
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
Mat src, dst;
src = imread("D:/IDE/opencv-3.1.0/demo.jpg");
if (!src.data) {
printf("加载图片异常\n");
return -1;
}
blur(src, dst, Size(60, 1), Point(-1, -1)); //X方向的模糊
//blur(src, dst, Size(1, 60), Point(-1, -1)); //Y方向的模糊
//blur(src, dst, Size(60, 60), Point(-1, -1)); //整体方向都模糊
//均值滤波函数的调用
namedWindow("最终效果", CV_WINDOW_AUTOSIZE);
imshow("最终效果", dst);
waitKey(0);
return 0;
}
高斯模糊的实现:[C++] 纯文本查看 复制代码 #include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
Mat src, dst;
src = imread("D:/IDE/opencv-3.1.0/demo.jpg");
if (!src.data) {
printf("加载图片异常\n");
return -1;
}
GaussianBlur(src, dst, Size(5, 5), 11, 11);
//高斯模糊函数的现实
namedWindow("最终效果", CV_WINDOW_AUTOSIZE);
imshow("最终效果", dst);
waitKey(0);
return 0;
}
|