计算机视觉实验:图像增强应用实践

本次实验主要从基于统计、函数映射的图像增强方法和基于滤波的图像增强方法两种方法中对一些图像增强的算法进行实现。主要的编程语言为python,调用了python自带的PIL图像库用于读取图像,利用numpy进行图像运算,最后使用opencv第三方库进行对比验证。下面为实验的详细步骤与过程。

基于统计、函数映射的图像增强方法

图像反转

所谓的图像反转是将颜色或灰度进行颠倒,如白色变成黑色,亮变暗暗变亮等等。其原理在于用255减去每个像素的颜色值或灰度值,从而达到反转的效果,R/G/B = 255 - R/G/B。下面使用代码进行实现(完整代码见 图片反转.py)。

  • 调用Image与numpy读取图像信息
  1.  img = np.array(Image.open(path))
  1. 根据shape判断是否是彩色图并用255减去颜色值
  1. if len(img.shape) > 2:
  2.         img = np.array(list(map(lambda x:list(map(lambda y:list(map(lambda z:255-z, y)), x)), img)))
  3. else:
  4.         img = np.array(list(map(lambda x:list(map(lambda y:255-y, x)) , img)))
  • 保存图像
  1. 下面的uint8是为了改变数据类型 否则会报错
  2. image = Image.fromarray(np.uint8(img))
  3. 保存图片
  4. image.save(f'./output/reverse/{path[7:]}')
  5. image.show()

调用opencv进行结果对比

代码如下所示,此代码调用了opencv库进行图像反转操作。完整代码见图片反转opencv.py

与上面的代码基本一致,不同点在于调用Opencv来代替Image与numpy的部分操作。其关键不同代码如下所示。

  1. 创建空图像
  2. dst = np.zeros((height, width, 3), np.uint8)
  3. for i in range(height):
  4.  for j in range(width):
  5.         (b, g, r) = img[i, j]
  6.         b = 255 - b
  7.         g = 255 - g
  8.         r = 255 - r
  9.         dst[i, j] = (b, g, r)
  10. 部分代码参考于https://laoai.blog.csdn.net/article/details/81133070

最后两者结果如下图图1所示

图1 图像反转结果对比图

从结果中可以看出,与原始图像相比颜色发生了很大的反转。而未用Openvc处理与使用了Opencv处理的结果是一样的。

直方图均衡化

直方图均衡化只要是让灰度能均匀分布而不是集中在某个范围内。使得某些地方特别亮某些特别暗。直方图均衡化的操作流程一般如下图图2所示,首先需要计算出目前原始图像的灰度直方图。然后对数量占比进行累加。累加得到的结果均在0-1之间。那么用255乘以结果,以获取最新的映射关系,此时再绘制直方图那么就可看出其分布更均匀。下面利用代码进行实现。

图2 直方图均衡化流程图

此处使用一张灰度图进行处理coins.png

  • 计算直方图

利用字典统计每个灰度值的数量映射

  1. def show_hist(img):
  2.     hist = collections.defaultdict(int)
  3.     for i in img:
  4.         for j in i:
  5.             hist[j] += 1
  6.     绘制直方图
  7.     plt.title('灰度直方图')
  8.     plt.xlabel('Bins')
  9.     plt.xlim([0256])
  10.     plt.ylabel('Pixels')
  11.     plt.bar(hist.keys(), hist.values())
  12.     plt.show()
  13.     return hist

 累加操作

  1. for i in range(256):
  2.     if i:
  3.         reduction_hist[i] = hist[i]+reduction_hist[i-1]
  4.     else:
  5.         reduction_hist[i] = hist[i]
  • 计算新的映射关系
  1. for index, i in enumerate(img):
  2.     for jndex, j in enumerate(i):
  3.         img[index][jndex] = reduction_hist[img[index][jndex]]*255

调用opencv进行结果对比

Opencv只需要调用下面的库函数即可进行直方图均衡化操作。详细代码可见直方图均衡化cv.py

  1. img = cv2.equalizeHist(img)

将原始图像、非opencv处理的直方图均衡化图像与opencv处理的直方图均衡化图像进行对比,如下图图3所示。可以看到后面两者与前面原始图像相比其直方图分布更均匀。而后面两者基本无差别。

图3 直方图均衡化结果对比图

伽马变换

伽马变换的数学公式如下所示,其中s为变换后的值,c为一常数此处取1,$\gamma$是用于控制变换幅度的,而r则是原图像的输入范围在0-1。

在查阅资料后发现,opencv并未自带伽马变换的相关函数,所以此处不进行与opencv的结果对比。根据学习发现,伽马变换需要进行以下步骤。

  • 图像数据归一化
  • 图像各像素点进行乘幂运算

最后代码如下:

  1. def gama_transfer(img,power1):
  2.     if len(img.shape) > 3:
  3.          img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
  4.     img = 255*np.power(img/255,power1)
  5.     img = np.around(img)
  6.     img[img>255] = 255
  7.     out_img = img.astype(np.uint8)
  8.     return out_img
  9. 参考于https://zhuanlan.zhihu.com/p/340513008?utm_id=0

结果输出如下图图4所示,

图4 伽马变换结果对比图

从图片对比中可以看出, 时暗部变量,对于此图可以看得更清晰, 时暗部变暗,图片则更难看清。

基于滤波的图像增强方法

均值滤波

均值滤波的原理在于将图像中的每个像素点的值都变成其周围n阶矩阵的平均值。所以在编程实现中,首先需要创建一个大小一样的0矩阵用以记录平均值。然后遍历一次图像,将计算得到的平均值填充进0矩阵中即可得到均值滤波的结果。其核心代码如下(完整可见`均值滤波.py`):

  1. for index in range(height):
  2.         for jndex in range(width):
  3.             判断是否为边界
  4.             if index <= int((kernel-1)/2) - 1 or index >= height - 1 - int((kernel-1)/2) \
  5.                     or jndex <= int((kernel-1)/2) - 1 or jndex >= height - int((kernel-1)/2) - 1:
  6.                 result[index, jndex] = img[index, jndex]
  7.             else:  均值值滤波
  8.                 result[index, jndex] = np.average(
  9.                     img[index - int((kernel-1)/2):index + int((kernel-1)/2) + 1,
  10.                     jndex - int((kernel-1)/2):jndex + int((kernel-1)/2) + 1])
  11. 部分参考于https://blog.csdn.net/qq_43633939/article/details/120854570

此处对于边界不做任何处理。上面的代码是针对灰度图的,若需要对彩色图片进行滤波处理,则可在后面加上三个通道即可如下面代码所示。

  1. for kndex in range(3):
  2.     result[index, jndex, kndex] = np.average(
  3.         img[index - int((kernel - 1) / 2):index + int((kernel - 1) / 2) + 1,
  4.             jndex - int((kernel - 1) / 2):jndex + int((kernel - 1) / 2) + 1, kndex])

调用opencv进行结果对比

均值滤波对于opencv存在一个函数调用,只需要指定滤波核即可进行操作。此处滤波核均选择3*3。

  1. import cv2
  2. path = './pics/save.bmp'
  3. # img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
  4. img = cv2.imread(path)
  5. ksize = [3,3]
  6. dst=cv2.blur(img,ksize)
  7. cv2.imshow('img', dst)
  8. cv2.imwrite(f'./cv-output/mean-filtering/{path[7:]}', img)
  9. cv2.waitKey(0)

最后将输出结果进行对比,如下图图5所示。

图5 均值滤波结果对比图

可以看出原图和滤波后的图像差别还是很大的,原图的噪点颗粒很清晰,而滤波后则变得模糊。同时opencv的结果和自编代码的结果差别不大。

高斯滤波

高斯滤波的流程图如下图图6所示,

图6 高斯滤波流程图

对于高斯滤波首先需要根据下面的高斯公式计算出各点的高斯值,

其中x,y均是离中心点的距离,所以说对于整个图像高斯值是固定的。在得到这些值后,将他们的各自除以他们的和以进行归一化。最后中心值等于归一化的结果除以周围点颜色值后求和。根据以上思路可进行编程如下:

  • 计算高斯值
  1. kernel = 3
  2. sigma = 1.3
  3. K = np.zeros([kernel, kernel])
  4. 计算高斯值
  5. for x in range(-12):
  6.     for y in range(-1,2):
  7.         K[x+1, y+1] = np.exp( -(x ** 2 + y ** 2) / (2 * (sigma ** 2)))

  • 归一化
  1. 归一化
  2. K = K/np.sum(K)
  • 加权求和
  1. result[index, jndex] = np.sum(K*img[index - int((kernel-1)/2):index + int((kernel-1)/2) + 1,
  2.                     jndex - int((kernel-1)/2):jndex + int((kernel-1)/2) + 1])

完整代码可见于`高斯滤波.py`

调用opencv进行结果对比

对于opencv高斯滤波只需要一个函数即可进行。完整代码见高斯滤波cv.py。

  1. result = cv2.GaussianBlur(img, (33), 1.3)

最后输出结果如下图图7所示,

图7 高斯滤波结果对比图

可以看到和原图相比高斯滤波后的结果变得模糊,同时有些噪点也变得不明显。高斯滤波的结果和opencv的结果基本一致。

实验结论或体会

本次实验完成了图像反转、直方图均衡化、伽马变换、均值滤波、高斯滤波五种图像增强方法的代码实现。并将输出的图片与opencv的结果进行对比发现基本一致,说明本次实验编程实现的方法基本与实际相符合。同时图像增强后的图像与原图进行对比,可以看出不同增强方法的作用,比如说高斯滤波可以减弱图像的噪点,伽马变换可以让原图的暗部或亮部细节更突出以获得隐藏的信息,直方图均衡化可以让图像亮度或颜色分布更均匀使得图像原本不能看出的细节可清晰显示等等。

在此次实验中,对图像进行增强需要用到python的PIL库和numpy库,这些的使用让我们更加地了解图像处理的方式。同时通过对这些库的练习也让我更加熟练地直接操作图像的像素点。理论课中讲解的关于图像增强方法的知识,在代码编辑实现过程中均得以体现,通过实验对理论知识理解也更加深入。总而言之,此次的实验让我对图像增强方法以及图像的处理方法有了更加深入的了解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/19916.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于DCT变换和huffman编码的语音压缩算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 多通道滤波 4.2 DCT变换 4.3 量化 4.3 哈夫曼编码 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ................................…

云上 Index:看「简墨」如何为云原生打造全新索引

拓数派首款数据计算引擎 PieCloudDB Database 是一款全新的云原生虚拟数仓。为了提升用户使用体验&#xff0c;提高查询效率&#xff0c;在实现存算分离的同时&#xff0c;PieCloudDB 设计与打造了全新的存储引擎「简墨」等模块&#xff0c;并针对云场景和分析型场景设计了高效…

网络安全进阶学习第九课——SQL注入介绍

文章目录 一、什么是注入二、什么是SQL注入三、SQL注入产生的原因四、SQL注入的危害五、SQL注入在渗透中的利用1、绕过登录验证&#xff1a;使用万能密码登录网站后台等。2、获取敏感数据3、文件系统操作4、注册表操作5、执行系统命令 六、如何挖掘SQL注入1、SQL注入漏洞分类按…

跨境电商代运营模式,Live Market打造跨境电商出海SaaS服务平台

近年来&#xff0c;我国跨境电商发展取得可喜进展。商务部数据显示&#xff0c;跨境电商货物进出口规模占外贸比重由5年前的不足1%上升到目前的5%左右。私域流量业态在电商领域兴起&#xff0c;品牌企业在线上建立自主经营的手机应用软件直接触达用户。跨境电商的发展模式转向平…

【力扣】92. 反转链表 II <链表指针>

【力扣】92. 反转链表 II 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回反转后的链表。 示例 1 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输出&#xff…

Eclipse进行debug

目录 基本步骤三种执行方式 -- 键盘快捷键variables面板移除debug过的项目通过eclipse调用具有软件界面的项目进行debug各个variable颜色具有的意义 基本步骤 点击eclipse右上角debug按钮 调出debug面板 点击小蜘蛛图标&#xff08;不是点绿色三角的Run&#xff09; 此时会进…

第一个 vue-cli 项目

一、什么是 vue-cli vue-cli 官方提供的一个脚手架&#xff0c;用于快速生成一个 vue 的项目模板&#xff1b;预先定义好的目录结构及基础代码&#xff0c;就好比咱们在创建 Maven 项目时可以选择创建一个骨架项目&#xff0c;这个骨架项目就是脚手架&#xff0c;我们的开发更加…

Maven【入门笔记】

Maven 解决版本依赖的问题 https://www.liaoxuefeng.com/wiki/1252599548343744/1309301146648610 如果没有项目管理工具&#xff0c;在开发项目的时候&#xff0c;我们需要手动管理依赖包&#xff0c;需要管理依赖包的版本、去找到并下载依赖包、还有依赖包所依赖的包 等等。…

百度与AI:历史、投资和监管

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 百度的人工智能在中国具有先发优势 随着ChatGPT的爆火&#xff0c;人工智能重新引起了投资者的注意&#xff0c;然而人工智能并不是突然爆火的&#xff0c;而是全球众多公司在人工智能技术上进行数十年如一日的研发和积累&a…

解决新版 Idea 中 SpringBoot 热部署不生效

标题 依赖中添加 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <opt…

项目管理中的需求分析:实施策略与最佳实践

引言 在项目管理的过程中&#xff0c;需求分析起着至关重要的作用。理解和定义项目需求是项目成功的关键一步&#xff0c;它可以帮助我们确定项目的目标和范围&#xff0c;以及如何有效地达到这些目标。在本文中&#xff0c;我们将深入探讨需求分析的重要性&#xff0c;讨论如…

rar压缩包怎么改成zip格式

不知道大家有没有遇到需要转换压缩包格式的问题&#xff0c;今天想和大家分享rar压缩包改成zip格式的方法。 方法一&#xff1a; 直接修改rar压缩包的后缀名变为zip&#xff0c;就可以修改压缩包文件格式了 方法二&#xff1a; 先将rar压缩包解压出来&#xff0c;然后再将解…

【Spring】bean的生命周期

1.具体的生命周期过程 bean对象创建&#xff08;调用无参构造器&#xff09; 给bean对象设置属性 bean对象初始化之前操作&#xff08;由bean的后置处理器负责&#xff09; bean对象初始化&#xff08;需在配置bean时指定初始化方法&#xff09; bean对象初始化之后操作&am…

数字IC验证高频面试问题整理附答案(二)

近日后台有同学私信还想要验证的面试题目&#xff0c;这不就来了~ Q16.权重约束中”:”和”: /”的区别 : 操作符表示值范围内的每一个值的权重是相同的,比如[1:3]:40,表示1&#xff0c;2&#xff0c;3取到的概率为40/120&#xff1b; :&#xff0f;操作符表示权重要平均分到…

点击编辑变完成

<template><div><button click"dialogshowtrue">添加部门</button><div>部门列表</div><el-table ref"multipleTable" :data"form" tooltip-effect"dark" style"width: 100%">&l…

无人机管控平台,推动电力巡检管理水平提升

各地区无人机作业水平和管理水平存在参差不齐&#xff0c;电力巡检管理要求与业务发展水平不匹配的问题。同时&#xff0c;巡检数据的存储和管理分散&#xff0c;缺乏有效的整合与共享手段&#xff0c;使得内外业脱节&#xff0c;没有形成统一应用和闭环管理。这就导致巡检数据…

springBoot多数据源使用tdengine(3.0.7.1)+MySQL+mybatisPlus+druid连接池

一、安装部署 1、我这里使用的 3.0.7.1版本&#xff0c;因为我看3.x版本已经发布了一年了&#xff0c;增加了很多新的功能&#xff0c;而且3.x官方推荐&#xff0c;对于2.x的版本&#xff0c;官网都已经推荐进行升级到3.x&#xff0c;所以考虑到项目以后的发展&#xff0c;决定…

K8s影响Pod调度和Deployment

5.应用升级回滚和弹性伸缩

数学学习——最优化问题引入、凸集、凸函数、凸优化、梯度、Jacobi矩阵、Hessian矩阵

文章目录 最优化问题引入凸集凸函数凸优化梯度Jacobi矩阵Hessian矩阵 最优化问题引入 例如&#xff1a;有一根绳子&#xff0c;长度一定的情况下&#xff0c;需要如何围成一个面积最大的图像&#xff1f;这就是一个最优化的问题。就是我们高中数学中最常见的最值问题。 最优化…

【深度学习】Transformer,Self-Attention,Multi-Head Attention

必读文章&#xff1a; https://blog.csdn.net/qq_37541097/article/details/117691873 论文名&#xff1a;Attention Is All You Need 文章目录 1、Self-Attention 自注意力机制2、Multi-Head Attention 1、Self-Attention 自注意力机制 Query&#xff08;Q&#xff09;表示当…