一.实验目的

  1. 进一步理解图像平滑和图像锐化等空间域增强方法的原理。
  2. 了解图像平滑和图像锐化的效果和作用。
  3. 掌握图像模板运算的流程。

二.实验主要仪器设备和材料

计算机,VS2017+OpenCV

三.实验原理

图像平滑

众所周知,实际获得的图像在形成、传输、接收和处理的过程中,不可避免地存在着外部和内部的噪声干扰。噪声恶化了图像质量,使图像模糊,给分析带来困难。因此,去除噪声,恢复原始图像时图像处理中的一个重要内容。消除图像噪声的工作称之为图像平滑或滤波。图像平滑方法包括空域法和频域法两大类。在空域法中,图像平滑常用的方法是采用均值滤波或中值滤波。

  1. 对于均值滤波,它是采用一个有奇数点的滑动窗口在图像上滑动,将窗口中心点对应的图像像素点的灰度值用窗口内的各个点的灰度值的平均值代替,在取均值过程中,如果窗口规定了各个像素点所占的权重,也就是各个像素点的系数,则称为加权均值滤波。
  2. 对于中值滤波,窗口中心点所对应像素的灰度值用窗口内所有像素的中间值代替。实现均值或中值滤波时,可以定义一个n*n的模板数组。另外,读者需要注意一点,在用窗口扫描图像过程中,对于图像四个边缘的像素点,可以不处理;也可以用灰度值为"0"的像素点扩展图像的边缘。

图象锐化

锐化处理的主要目的是突出图像中的细节或者增强被模糊了的细节,这种模糊不是由于错误操作,就是特殊图像获取方法的固有影响。图像均值滤波器可以使图像变模糊,是因为均值处理与积分相类似,因此可以对其进行逆运算(如微分运算)就可以使图像变得清晰。常常采用基于一阶或二阶微分的锐化滤波器实现图像的锐化处理。

  1. 一阶微分是通过梯度法来实现的。对于图像f(i,j),它在点(i,j)处的梯度是一个矢量,定义为:

    利用差分法近似上述公式,得到:

    为了便于编程和提高运算,可进一步简化为:

    利用差分运算时,图像的第一行和第一列的像素的梯度无法求得,一般用后一行或后一列的梯度值近似代替。微分运算可以增强图像高频分量(边缘等细节),但是仅仅微分处理后的图像非常暗,效果不理想,因此既要增强图像边缘,又要保持目标物体的内部灰度不变,常采用给边缘规定一个特定的灰度级的方法来完成梯度锐化处理。公式为:

    La为一指定的灰度值,它将边界的灰度值统一化,这样可以使其边界更加清晰明显。该方法基本上不破坏图像的背景,又可找到边缘,并根据需要增强边缘。

  2. 基于二阶微分的锐化滤波器,即拉普拉斯增强算子。一个二元图像函数f(x, y)的拉普拉斯变换定义为:

    由于拉普拉斯是一种微分算子,它的应用强调图像中灰度的突变及降低灰度慢变化的区域,这将产生一幅把图像中的浅灰色边线和突变点叠加到暗背景中的图像。将原始图像和拉普拉斯图像叠加在一起的简单方法可以保护拉普拉斯锐化处理的效果,同时又能复原背景信息。这种方法可表示为:

四.实验内容

编程实现车牌图像的去噪和锐化处理。首先对图像去噪,分别采用均值滤波器和中值滤波器进行处理,比较两种滤波器效果;然后对去噪后的图像进行锐化,分别采用一阶微分和二阶微分,比较锐化效果。

#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;//均值滤波函数
void AverFiltering(const Mat &src, Mat &dst) {if (!src.data) return;//at访问像素点for (int i = 0; i < src.rows; ++i)for (int j = 0; j < src.cols; ++j) {if (i >= 1 && j >= 1 && i < src.rows - 1 && j < src.cols - 1) {//边缘不进行处理dst.at<Vec3b>(i, j)[0] = (src.at<Vec3b>(i, j)[0] + src.at<Vec3b>(i - 1, j - 1)[0] + src.at<Vec3b>(i - 1, j)[0] + src.at<Vec3b>(i, j - 1)[0] +src.at<Vec3b>(i - 1, j + 1)[0] + src.at<Vec3b>(i + 1, j - 1)[0] + src.at<Vec3b>(i + 1, j + 1)[0] + src.at<Vec3b>(i, j + 1)[0] +src.at<Vec3b>(i + 1, j)[0]) / 9;dst.at<Vec3b>(i, j)[1] = (src.at<Vec3b>(i, j)[1] + src.at<Vec3b>(i - 1, j - 1)[1] + src.at<Vec3b>(i - 1, j)[1] + src.at<Vec3b>(i, j - 1)[1] +src.at<Vec3b>(i - 1, j + 1)[1] + src.at<Vec3b>(i + 1, j - 1)[1] + src.at<Vec3b>(i + 1, j + 1)[1] + src.at<Vec3b>(i, j + 1)[1] +src.at<Vec3b>(i + 1, j)[1]) / 9;dst.at<Vec3b>(i, j)[2] = (src.at<Vec3b>(i, j)[2] + src.at<Vec3b>(i - 1, j - 1)[2] + src.at<Vec3b>(i - 1, j)[2] + src.at<Vec3b>(i, j - 1)[2] +src.at<Vec3b>(i - 1, j + 1)[2] + src.at<Vec3b>(i + 1, j - 1)[2] + src.at<Vec3b>(i + 1, j + 1)[2] + src.at<Vec3b>(i, j + 1)[2] +src.at<Vec3b>(i + 1, j)[2]) / 9;}else {//边缘赋值dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2];}}
}//求九个数的中值
uchar Median(uchar n1, uchar n2, uchar n3, uchar n4, uchar n5,uchar n6, uchar n7, uchar n8, uchar n9) {uchar arr[9];arr[0] = n1;arr[1] = n2;arr[2] = n3;arr[3] = n4;arr[4] = n5;arr[5] = n6;arr[6] = n7;arr[7] = n8;arr[8] = n9;for (int gap = 9 / 2; gap > 0; gap /= 2)//希尔排序for (int i = gap; i < 9; ++i)for (int j = i - gap; j >= 0 && arr[j] > arr[j + gap]; j -= gap)swap(arr[j], arr[j + gap]);return arr[4];//返回中值
}//中值滤波函数
void MedianFlitering(const Mat &src, Mat &dst) {if (!src.data)return;for (int i = 0; i < src.rows; ++i)for (int j = 0; j < src.cols; ++j) {if (i > 1 && i < src.rows - 1 && j > 1 && j < src.cols - 1) {dst.at<Vec3b>(i, j)[0] = Median(src.at<Vec3b>(i, j)[0], src.at<Vec3b>(i + 1, j + 1)[0],src.at<Vec3b>(i + 1, j)[0], src.at<Vec3b>(i, j + 1)[0], src.at<Vec3b>(i + 1, j - 1)[0],src.at<Vec3b>(i - 1, j + 1)[0], src.at<Vec3b>(i - 1, j)[0], src.at<Vec3b>(i, j - 1)[0],src.at<Vec3b>(i - 1, j - 1)[0]);dst.at<Vec3b>(i, j)[1] = Median(src.at<Vec3b>(i, j)[1], src.at<Vec3b>(i + 1, j + 1)[1],src.at<Vec3b>(i + 1, j)[1], src.at<Vec3b>(i, j + 1)[1], src.at<Vec3b>(i + 1, j - 1)[1],src.at<Vec3b>(i - 1, j + 1)[1], src.at<Vec3b>(i - 1, j)[1], src.at<Vec3b>(i, j - 1)[1],src.at<Vec3b>(i - 1, j - 1)[1]);dst.at<Vec3b>(i, j)[2] = Median(src.at<Vec3b>(i, j)[2], src.at<Vec3b>(i + 1, j + 1)[2],src.at<Vec3b>(i + 1, j)[2], src.at<Vec3b>(i, j + 1)[2], src.at<Vec3b>(i + 1, j - 1)[2],src.at<Vec3b>(i - 1, j + 1)[2], src.at<Vec3b>(i - 1, j)[2], src.at<Vec3b>(i, j - 1)[2],src.at<Vec3b>(i - 1, j - 1)[2]);}else {//边缘赋值dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2];}}
}// 梯度锐化函数
void DegreeSharpDeal(const Mat &src, Mat &dst) {if (!src.data)return;for (int i = 0; i < src.rows; ++i)for (int j = 0; j < src.cols; ++j) {float a, b, c;if (i > 1 && j > 1) {a = abs((float)src.at<Vec3b>(i, j)[0] - (float)src.at<Vec3b>(i - 1, j)[0]) + abs((float)src.at<Vec3b>(i, j)[0] - (float)src.at<Vec3b>(i, j - 1)[0]);b = abs((float)src.at<Vec3b>(i, j)[1] - (float)src.at<Vec3b>(i - 1, j)[1]) + abs((float)src.at<Vec3b>(i, j)[1] - (float)src.at<Vec3b>(i, j - 1)[1]);c = abs((float)src.at<Vec3b>(i, j)[2] - (float)src.at<Vec3b>(i - 1, j)[2]) + abs((float)src.at<Vec3b>(i, j)[2] - (float)src.at<Vec3b>(i, j - 1)[2]);a = a + src.at<Vec3b>(i, j)[0];b = b + src.at<Vec3b>(i, j)[1];c = c + src.at<Vec3b>(i, j)[2];}else {//边缘赋值a = src.at<Vec3b>(i, j)[0];b = src.at<Vec3b>(i, j)[1];c = src.at<Vec3b>(i, j)[2];}if (a > 255 || b > 255 || b > 255 || a < 0 || b < 0 || c < 0) {dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2];}else {dst.at<Vec3b>(i, j)[0] = a;dst.at<Vec3b>(i, j)[1] = b;dst.at<Vec3b>(i, j)[2] = c;}}
}// 拉普拉斯锐化函数
void LaplacianSharpDeal(const Mat &src, Mat &dst) {if (!src.data)return;Mat img(src.size(), src.type());for (int i = 0; i < src.rows; ++i)for (int j = 0; j < src.cols; ++j) {float a, b, c;if (i > 1 && i < src.rows - 1 && j > 1 && j < src.cols - 1) {a = 5 * (float)src.at<Vec3b>(i, j)[0] - (float)src.at<Vec3b>(i - 1, j)[0] - (float)src.at<Vec3b>(i, j - 1)[0] -(float)src.at<Vec3b>(i, j + 1)[0] - (float)src.at<Vec3b>(i + 1, j)[0];b = 5 * (float)src.at<Vec3b>(i, j)[1] - (float)src.at<Vec3b>(i - 1, j)[1] - (float)src.at<Vec3b>(i, j - 1)[1] -(float)src.at<Vec3b>(i, j + 1)[1] - (float)src.at<Vec3b>(i + 1, j)[1];c = 5 * (float)src.at<Vec3b>(i, j)[2] - (float)src.at<Vec3b>(i - 1, j)[2] - (float)src.at<Vec3b>(i, j - 1)[2] -(float)src.at<Vec3b>(i, j + 1)[2] - (float)src.at<Vec3b>(i + 1, j)[2];}else {//边缘赋值a = src.at<Vec3b>(i, j)[0];b = src.at<Vec3b>(i, j)[1];c = src.at<Vec3b>(i, j)[2];}if (a > 255 || b > 255 || b > 255 || a < 0 || b < 0 || c < 0) {dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2];}else {dst.at<Vec3b>(i, j)[0] = a;dst.at<Vec3b>(i, j)[1] = b;dst.at<Vec3b>(i, j)[2] = c;}}
}void main() {Mat image = imread("噪声图像.bmp");Mat image1(image.size(), image.type());Mat image2(image.size(), image.type());Mat image3(image2.size(), image2.type());Mat image4(image2.size(), image2.type());AverFiltering(image, image1);MedianFlitering(image, image2);LaplacianSharpDeal(image2, image3);DegreeSharpDeal(image2, image4);imshow("均值滤波", image1);imshow("中值滤波", image2);imshow("拉普拉斯锐化处理", image3);imshow("梯度锐化处理", image4);waitKey();
}

openCV实现图像的空间域增强相关推荐

  1. 图像处理3-经典空间域增强——空域滤波

    图像处理系列: 图像处理1-经典空间域增强--灰度映射 图像处理2-经典空间域增强--直方图均衡化 空域滤波 这里根据模板是线性的还是非线性的进行分类,分别根据<图像处理与分析教程>上的方 ...

  2. 图像的空间域与频率域

    图像的空间域:是指图像平面所在的二维平面,对于空间域的图像处理主要是对像元灰度值的改变,其位置不变. 图像的频率域:是图像像元的灰度值随位置变化的空间频率,以频谱表示信息分布特征,傅立叶变换能把图像从 ...

  3. Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCV实现图像的直方图算法增强(C++)

    Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCV实现图像的直方图算法增强(C++) Baumer工业相机 Baumer工业相机使用图像算法增加图像的技术背景 Baumer工业相机 ...

  4. MATLAB中实现图像的空间域滤波和频率域滤波

    1. 空间域滤波 空间域滤波是指在图像空间中借助模板对图像领域进行操作,处理图像每一个像素值.主要分为线性滤波和非线性滤波两类,根据功能可分为平滑滤波器和锐化滤波器.平滑可通过低通来实现,平滑的目的有 ...

  5. 【youcans 的 OpenCV 学习课】7. 空间域图像滤波

    专栏地址:『youcans 的图像处理学习课』 文章目录:『youcans 的图像处理学习课 - 总目录』 [youcans 的 OpenCV 学习课]7. 空间域图像滤波 图像滤波是在尽可能保留图像 ...

  6. youcans 的 OpenCV 学习课—8.频率域图像滤波(上)

    欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『youcans 的 OpenCV 学习课』 系列,持续更新中 youcans 的 OpenCV 学习课-1.安装与环境配置 yo ...

  7. 数字图像处理-空间域图像增强(一)(图像反转,对数变换,幂次变换、分段线性变换)

    空间域增强的第一部分:图像反转,对数变换,幂次变换.分段线性变换 (s:现点值,r: 原点值) 图像反转: 这个无需多说,就是把黑变白,白变黑,拿八位灰度图像来说 表达式:s=255-r 作用:看清暗 ...

  8. 深入学习OpenCV中图像相似度的算法

    最近一段时间学习并做的都是对图像进行处理,其实自己也是新手,各种尝试,所以我这个门外汉想总结一下自己学习的东西,图像处理的流程.但是动起笔来想总结,一下却不知道自己要写什么,那就把自己做过的相似图片搜 ...

  9. 空间域图像增强:卷积和空间域滤波

    1.什么是卷积? 卷积:数学中关于两个函数的一种无穷积分运算,是通过两个函数f 和g 生成第三个函数的一种数学算子,表征函数f 经过翻转和平移与g 的重叠部分的累积. 2.什么是空间卷积? 线性空间滤 ...

最新文章

  1. scroll事件实现监控滚动条并分页显示示例(zepto.js)
  2. “文艺复兴” ConvNet卷土重来,压过Transformer FAIR重新设计纯卷积新架构
  3. 二分法(三种基本模版)
  4. Django-Model中的ForeignKey,ManyToManyField与OneToOneField
  5. count返回0_你是一直认为 count(1) 比 count(*) 效率高么?
  6. vue PC端国际化一站式解决方案
  7. 基于JAVA的在线图书销售系统
  8. apt install:文件尺寸不符(25294 != 25412)。您使用的镜像正在同步中?
  9. PPT 2013 提升演讲逼格 视频教程
  10. 【Linux应用】SAN(存储区域网络)技术
  11. English——让步状语从句(一般现在时表将来)(三)
  12. 2022搜狐校园算法大赛推荐赛道Rank2方案分享
  13. 【教程】创建活动报名二维码(活动报名/会议签到扫码,带微信手机号认证)
  14. Unity 通过代码修改材质球属性
  15. access()函数的用法
  16. 随机森林 Iris 特征重要性
  17. Linux服务器下安装vsftpd,搭建文件服务器
  18. hadoop生态系统的详细介绍-详细一点
  19. 安装zabbix及部署
  20. PTA 7-2 构建下三角矩阵 (15分) 非得用vector

热门文章

  1. DBN+LSTM神经网络电容量回归分析,基于MATLAB编程的深度信念网络+lstm回归分析,
  2. 阿里云域名实名认证状态查询
  3. 懒人数据库 MongoDB 5.x
  4. 虚幻4与Unity: 哪个游戏引擎是开发者的最爱?
  5. 1685_Excel的几种脚本处理方式
  6. Python实现线性回归(公式推导+源代码)
  7. Zend PDT Eclipse + Zend Server Communication Edition(CE)
  8. 运动模糊 motion blur
  9. Get请求后端并带参数
  10. 【大数据架构】浅谈数据中台