3.5.1均值滤波

1.数学原理
概念:“把每个像素都用周围的8个像素来做均值操作 ”
作用:平滑图像的用处, 有的图像的锐度很高,用这样的均值算法,可以把锐度降低。使得图像看上去更加自然
两种3x3的平滑滤波器(线性滤波):3x3平均滤波器R=1/9 ∑Zi------滤波器模板系数都为1; 3x3加权滤波器R=1/16∑Zi,滤波器模板系数不同,中心点影响最大。
均值滤波就是将滤波器模板和图像像素进行卷积。

需要注意的是滤波模板(卷积核)必须为奇数

2.实现代码
第一;opencv自带的均值滤波函数为
void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )
参数解释:
. InputArray src: 输入图像,可以是Mat类型,图像深度是CV_8U、CV_16U、CV_16S、CV_32F以及CV_64F其中的某一个。
. OutputArray dst: 输出图像,深度和类型与输入图像一致
. Size ksize: 滤波模板(卷积核)kernel的尺寸,一般使用Size(w, h)来指定,如Size(3,3)
. Point anchor=Point(-1, -1): 字面意思是锚点(卷积核的中心点),也就是处理的像素位于kernel的什么位置,默认值为(-1, -1)即位于kernel中心点,如果没有特殊需要则不需要更改
. int borderType=BORDER_DEFAULT: 用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <vector>
#include <opencv2/imgproc/imgproc.hpp>
#include<cmath>
using namespace std;
using namespace cv;
int main()
{Mat src, dst;src = imread("c:/users/征途/desktop/vs-cpp/project3/04.jpg");blur(src,dst, Size(3, 3));imshow("src", src);imshow("dst", dst);waitKey(0);return 0;
}

第二,自己用c++实现均值滤波函数

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <vector>
#include <opencv2/imgproc/imgproc.hpp>
#include<cmath>
using namespace std;
using namespace cv;void myblur(const Mat& src, Mat& dst, Size ksize)
{//若模板不是奇数模板,则报错退出if (ksize.width % 2 == 0 || ksize.height % 2 == 0){cout << "please input odd ksize" << endl;exit(-1);}//根据ksize大小扩充模板边界int awidth = (ksize.width - 1) / 2;  //公式中的a int aheight = (ksize.height - 1) / 2;// 公式中的bMat asrc;//图像边界扩充函数copyMakeBorder,void copyMakeBorder( const Mat& src, Mat& dst,int top, int bottom, int left, int right,int borderType, const Scalar& value = Scalar() );copyMakeBorder(src, asrc, aheight, aheight, awidth, awidth, BORDER_DEFAULT);//根据图像通道数遍历图像求均值//通道数为1if (src.channels() == 1){for (int i = 0+aheight; i < src.rows + aheight; i++) // i < 扩充后图片高{for (int j = 0+awidth; j < src.cols + awidth; j++){int sum = 0;   //sum是成绩和int mean = 0;   //mean是均值for (int k = i - aheight; k <= i + aheight; k++) {for (int l = j - awidth; l <= j + awidth; l++){sum += asrc.at<uchar>(k, l);  //模板系数和像素乘积的和,采用的是3x3都为1的平均滤波模板}}mean = sum / (ksize.width*ksize.height); // 乘积和/模板系数和dst.at<uchar>(i - aheight, j - awidth) = mean;}}}//通道数为3 if (src.channels() == 3){for (int i = aheight; i < src.rows + aheight; i++){for (int j = awidth; j < src.cols + awidth; j++){int sum[3] = { 0 };int mean[3] = { 0 };for (int k = i - aheight; k <= i + aheight; k++){for (int l = j - awidth; l <= j + awidth; l++) //依次根据通道读取每个通道上的,模板系数和像素乘积的和{sum[0] += asrc.at<Vec3b>(k, l)[0];sum[1] += asrc.at<Vec3b>(k, l)[1];sum[2] += asrc.at<Vec3b>(k, l)[2];}}for (int m = 0; m < 3; m++) //依次循环按照通道数将卷积后的结果赋予dst{mean[m] = sum[m] / (ksize.width*ksize.height);dst.at<Vec3b>(i - aheight, j - awidth)[m] = mean[m];}}}}
}int main()
{Mat src, dst1,dst2;src = imread("c:/users/征途/desktop/vs-cpp/project3/04.jpg");//opencv自带函数blur(src,dst1, Size(3, 3));imshow("src", src);imshow("dst1", dst1);//自己编写的函数dst2 = Mat::zeros(src.size(), src.type());myblur(src, dst2, Size(3, 3));imshow("dst2", dst2);waitKey(0);return 0;
}

结果:1为原图,2为系统自带函数结果,3为自己编写结果

3.5.2中值滤波

1.数学原理
先将掩膜中欲求的像素及其领域内的像素值排序,确定出中值,并将中值赋予给该像素点。
针对随机噪声,椒盐噪声效果好,可以保护图像尖锐边缘;对高斯噪声效果差。
应用:中值滤波对脉冲噪声(如椒盐噪声)的抑制十分有用。

缺点:易造成图像的不连续性

2.实现代码
实现的思路:用一个数组存储模板中所有的像素值,进行排序,取数组中的中间值赋值给当前像素点

1.opencv自带函数为medianBlur()
2.c++自己编写函数mymedianBlur()
代码实现:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <vector>
#include <opencv2/imgproc/imgproc.hpp>
#include<cmath>
using namespace std;
using namespace cv;
//首先进行编写冒泡排序算法
void bublle_sort(std::vector<int> &arr)
{bool flag = true;//默认数组排序已经排好for (int i = 0; i < arr.size() - 1; ++i){while (flag = false)   //如果排序错误,则执行循环体中的语句{for (int j = 0; j < arr.size() - 1 - i; ++j){if (arr[j] > arr[j + 1]){int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;flag = true;}}}}
}//用c++实现中值滤波
void mymedianBlur(cv::Mat& src, cv::Mat& dst, cv::Size ksize)//Mat &a的意思是创建一个矩阵a的引用
{//图像边界扩充if (ksize.width % 2 == 0 || ksize.height % 2 == 0) //卷积核要取奇数{fprintf(stderr, "Please enter odd size!");exit(-1);}int hh = (ksize.height - 1) / 2;int hw = (ksize.width - 1) / 2;cv::Mat Newsrc;cv::copyMakeBorder(src, Newsrc, hh, hh, hw, hw, cv::BORDER_REFLECT_101);//图像扩充,以边缘为轴,对称dst = cv::Mat::zeros(src.rows, src.cols, src.type());//编写中值滤波,先进行滑窗遍历图像来获取像素点像素//首先遍历图像源for (int i = hh; i < src.rows + hh; i++){uchar* ptrdst = dst.ptr(i - hh);   //滑窗内的ptrdstfor (int j = hw; i < src.cols + hw; j++){std::vector<int> pix; //定义一个std内存中的容器,容器名叫pix,容器内的值为int类型,与数组类似,但是容器的大小可变//使用滑窗算法遍历for (int r = i - hh; r <= i + hh; r++)   //定义滑窗的高{const uchar* ptrsrc = Newsrc.ptr(r);  //指针取原图位于滑窗内的位置r处的元素for (int c = j - hw; c <= j + hw; c++) // 滑窗的宽{pix.push_back(ptrsrc[c]);  //在r的前提下,利用指针获取处的元素}}//对读取出来的元素冒泡排序bublle_sort(pix);ptrdst[j - hw] = pix[(ksize.area() - 1) / 2];//将排序后的中值映射给输出图像}}
}// 主函数应用
int main()
{cv::Mat src = cv::imread("c:/users/征途/desktop/vs-cpp/project3/09中值.jpg");Mat dst1;Mat dst2;cv::Size ksize(5, 5);mymedianBlur(src, dst1, ksize);medianBlur(src, dst2, (5,5));imshow("my", dst1);imshow("cv", dst2);waitKey(0);return 0;
}

冈萨雷斯数字图像处理第三章空间滤波相关推荐

  1. 冈萨雷斯数字图像处理第三章灰度变换与空间滤波算法 c++

    3.2一些基本的灰度变换函数 具体有 1.图像反转函数 2.对数变换函数 3.幂次(伽马)变换函数 4.分段线性变换函数(对比拉伸.灰度切割.位图切割) 3.2.1图像反转函数 1.数学原理 灰度级范 ...

  2. 数字图像处理——第三章 空间域图像增强(空间滤波)

    文章目录 1. 空间滤波基础 2. 线性滤波器 2.1 平滑空间滤波器 2.2 锐化空间滤波器 2.2.1 基于一阶微分的图像增强--梯度法 2.2.2 基于二阶微分的图像增强--拉普拉斯算子 3. ...

  3. 数字图像处理第三章part2

    chap03-空间滤波基础 本节对应原书第三章的后半部分,第三章主讲图像增强,借机引入空间滤波,空间域分析和频率域分析后都会涉及. 从时域信号引入频率和空间频率 前面说过信号可以理解为函数.由于时间只 ...

  4. 数字图像处理——第三章 空间域图像增强(灰度变换和直方图处理)

    文章目录 空间域图像增强 1. 背景知识 2. 基本灰度变换 2.1 图像反转 2.2 对数变换 2.3 幂次变换 2.4 分段线性变换函数 2.4.1 对比拉伸 2.4.2 灰度切割 2.4.3 位 ...

  5. 数字图像处理第三章<一>、灰度变换

    第三章 灰度变换和空间滤波 本章主要介绍图像增强空间域处理的基本知识 一.背景知识 空间域处理基本表达式:g(x,y)=T[f(x,y)]g(x,y) = T[f(x,y)]g(x,y)=T[f(x, ...

  6. 数字图像处理第三章边缘检测(Sobel算子、Laplace算子)

    边缘 边缘(edge)是指图像局部强度变化最显著的部分.主要存在于目标与目标.目标与背景.区域与区域(包括不同色彩)之间,是图像分割.纹理特征和形状特征等图像分析的重要基础. 边缘检测概念 1.边缘检 ...

  7. 数字图像处理 第三章 灰度变换与空间滤波

    空间域处理主要分为灰度变换和空间滤波两类.灰度变换对图像的单个像素进行操作,主要以对比度和阈值处理为目的.空间滤波涉及改善性能的操作,如通过图像中每个像素的领域处理来锐化图像. 1.背景知识 空间域增 ...

  8. 数字图像处理第三章-----灰度变换

    目录 一:灰度变换与空间滤波 二.灰度变换 2.1 图像反转 2.2 对数变换 2.3 幂律变换(伽马变换) 一:灰度变换与空间滤波 图像处理中分为空间域的变换和频率域的变换, 空间域: 指的时图像的 ...

  9. 数字图像处理 第三章 图像变换

    图像变换 图像和其他信号一样,既能在空间域(简称空域)处理,也能在频率域(简称频域)处理.把图像信息从空域变换到频域,可以更好地分析.加工.处理图像信息.因为图像信息的频域处理具有如下特点:①能量守恒 ...

最新文章

  1. 相对熵与交叉熵的区别
  2. 云计算的6个未来趋势
  3. 8.基本数据结构-顺序表和链表
  4. 使用Mockito时遇到的一些问题
  5. 单线程多线程_面试系列 redis为什么快amp;单线程amp;多线程
  6. Nginx学习之七:通过Nginx社区进行技术交流
  7. Internal Error 2738 - Installing ArcGIS Server 9.3,10 for Java
  8. 微信小程序生成海报库
  9. RobotFramework与Eclipse集成
  10. 使用echarts生成海友网企业全国分布地图
  11. java8使用Comparator.comparing进行排序
  12. 云管理服务MSP扫盲
  13. 2021 HZNU Winter Training Day 17 (2018 German Collegiate Programming Contest (GCPC 18))
  14. [ACL2017]Going out on a limb:Joint Extraction of Entity Mentions and Relations without Depende...
  15. CSK与DCSK调制与解调
  16. 22春天津大学《国际经济法学》在线作业二
  17. 基于OPenCV的视频播放变慢
  18. 小鹏 肖志光_自动驾驶:小鹏在展翅,蔚来有未来
  19. 代码随想录算法训练营第七天
  20. C# 调用c++错误A call to PInvoke function has unbalanced the stack

热门文章

  1. 51单片机c语言年月日设定,综合实例:51单片机(AT89C52)万年历(温度闹钟年月日时分秒星期)...
  2. AD 多边形 圆形 快速覆铜
  3. 纠结的上传控件,啊!多么痛的领悟
  4. 面试复习题--音视频
  5. 软件测评师--第15小时 可靠性测试
  6. 软件测评师--第六小时 白盒测试技术
  7. objdump使用方法
  8. 神经网络训练输入数据为什么需要归一化呢
  9. Windows环境 C++ 安装OpenCV-contrib
  10. 人工智能史话(番外篇)