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

news2024/11/13 11:10:39

本次实验主要从基于统计、函数映射的图像增强方法和基于滤波的图像增强方法两种方法中对一些图像增强的算法进行实现。主要的编程语言为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.coloradmin.cn/o/815824.html

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

相关文章

奇富科技联合哈银消金获《亚洲银行家》中国最佳信贷项目奖

7月28日&#xff0c;全球金融领域最具含金量的奖项之一《亚洲银行家》颁布2023年度奖项&#xff0c;奇富科技荣获“中国最佳信贷项目”殊荣。值得关注的是&#xff0c;该奖项由奇富科技与哈银消金联合获得&#xff0c;双方联合获奖&#xff0c;是主办方对奇富科技全面赋能金融机…

【限时优惠】红帽openstack管理课程(CL210) 即将开课

课程介绍 通过实验室操作练习&#xff0c;学员将能够深入学习红帽企业 Linux OpenStack 平台各服务的手动安装方法&#xff0c;还将了解 OpenStack 开发社区的未来发展计划。 培训地点&#xff1a; 线下面授&#xff1a;苏州市姑苏区干将东路666号401室&#xff1b; 远程…

Java平台标准版 8 文档

Java 平台标准版 8 文档 (oracle.com)https://docs.oracle.com/javase/8/docs/ JDK 8 是 JRE 8 的超集&#xff0c;包含 JRE 8&#xff0c;以及编译器和调试器等工具&#xff0c;如 开发小程序和应用程序。JRE 8 提供了库&#xff0c; Java 虚拟机 &#xff08;JVM&#xff09;…

ElasticSearch学习之ElasticSearch快速入门实战

1.先“分词” 2.倒排索引&#xff08;前提是分词&#xff09; ElasticSearch官网地址&#xff1a;欢迎来到 Elastic — Elasticsearch 和 Kibana 的开发者 | Elastichttps://www.elastic.co/cn/ 一、下载 下载地址&#xff1a;https://www.elastic.co/cn/downloads/past-re…

C++ ------ 模板初阶

文章目录 泛型编程模板函数模板概念原理函数模板的实例化类模板 泛型编程 我们在实现交换函数的时候&#xff0c;只能实现一个数据类型的交换函数&#xff0c;想要在C中完成对应类型数据的交换一种方法是使用函数重载&#xff0c;就像下面这样 void Swap(int& left, int&am…

MyBatis源码剖析之延迟加载源码细节

文章目录 什么是延迟加载&#xff1f;实现局部延迟加载全局延迟加载 延迟加载原理实现延迟加载原理&#xff08;源码剖析)Setting 配置加载&#xff1a;延迟加载代理对象创建注意事项 什么是延迟加载&#xff1f; 在开发过程中很多时候我们并不需要总是在加载⽤户信息时就⼀定…

Git分布式版本控制工具和GitHub(二)--Git指令入门

一.指令入门前的准备 1.Git全局设置 2.获取Git仓库 例如&#xff1a;将我GitHub上的first_resp仓库克隆到本地。 点击进入first_rep&#xff0c;后面本地仓库操作的学习就是在这个界面右键打开Git Bash 3.工作区&#xff0c;暂存区&#xff0c;版本库概念 注&#xff1a;如果空…

案例研究|康明斯中国通过JumpServer搭建统一的运维安全审计平台

作为全球动力技术先行者&#xff0c;康明斯&#xff08;中国&#xff09;投资有限公司&#xff08;以下简称为康明斯中国&#xff09;设计、制造、分销多元的动力解决方案&#xff0c;并提供服务支持。公司产品囊括柴油及天然气发动机、发电机组、交流发电机、排放处理系统、涡…

使用AOP切面对返回的数据进行脱敏的问题

1.注解类 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** Author: xiaoxin* Date: 2023/7/21 17:15*/ Retention(RetentionPolicy.RUNTIME) Targe…

java连接sftp服务器实现上传下载

一、准备SFTP服务器 我目前使用的是freeSSHd.exe,下载后按照步骤一步步安装&#xff0c;最后俩弹窗&#xff0c;第一个选是&#xff0c;第二个选否。 二、基础配置 双击打开安装好的程序&#xff0c;在右下角找到图标&#xff0c;右键&#xff0c;setting 按照步骤配置 …

根据端口号查找服务位置

已知服务的IP和端口&#xff0c;查找该服务所在位置 1、打开命令提示符&#xff08;CMD&#xff09; WINR快捷键打开运行对话框&#xff0c;输入CMD&#xff0c;回车即可。 2、找到对应的PID或程序名称 输入netstat -ano|findstr 端口号&#xff0c;回车找到对应的PID&…

msvcp140.dll丢失怎么修复?《绝地求生》报错msvcp140.dll丢失修复方法

在我运行《绝地求生》游戏的时候&#xff0c;出现msvcp140.dll丢失的错误提示时&#xff0c;感到有些困扰和不安&#xff0c;不知道该如何解决这个问题。同时&#xff0c;我也会担心这个问题会对我使用电脑产生什么不利影响。在尝试解决这个问题之前&#xff0c;我开始意识到我…

ScrumMaster认证课-PSM,了解一下

在敏捷学习的道路上继续前行&#xff0c;Leangoo领歌的PSM课程已经开启&#xff0c;认证全球认可&#xff0c;还不用续证&#xff0c;可以了解一下。 Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架&#xff0c;旨在最短时间内交…

Java课题笔记~数据库连接池

一、数据库连接池 1.1 数据库连接池简介 数据库连接池是个容器&#xff0c;负责分配、管理数据库连接(Connection) 它允许应用程序重复使用一个现有的数据库连接&#xff0c;而不是再重新建立一个&#xff1b; 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数…

前端Vue入门-day05-自定义指令、插槽、路由入门

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 自定义指令 基本语法 (全局&局部注册) 全局注册 局部注册 指令的值 v-loading 指令封装 插槽 …

电子贺卡蓝牙芯片,支U盘/SD卡音频播放蓝牙IC,WT2605-32N-L009

喜庆的时刻&#xff0c;向亲朋好友送上一份特别的祝福&#xff0c;是传递情谊、增进感情的最佳方式。然而&#xff0c;传统贺卡的简单文字和图片已经无法满足我们对个性化、创意化的需求。现在&#xff0c;深圳唯创知音&#xff0c;带来了一款颠覆传统贺卡的全新蓝牙BLE方案——…

使用Windbg分析从系统应用程序日志中找到的系统自动生成的dump文件去排查问题

目录 1、尝试将Windbg附加到目标进程上进行动态调试&#xff0c;但Windbg并没有捕获到 2、在系统应用程序日志中找到了系统在程序发生异常时自动生成的dump文件 2.1、查看应用程序日志的入口 2.2、在应用程序日志中找到系统自动生成的dump文件 3、使用Windbg静态分析dump文…

ardupilot 如何安装intelhex模块

目录 文章目录 目录摘要1.下载资源1.下载需要的软件2.编译带bt的固件摘要 本节主要记录ardupilot如何安装intelhex模块,实现编译ardupilot的bootloader文件并生成bootloader文件和固件合并的.hex文件。 1.下载资源 1.下载需要的软件 下载网址 intelhex-2.3.0.tar.gz 下载…

笔记本触摸板没反应怎么办?只需要4个方法!快速解决!

“大家知道为什么笔记本触摸板没反应吗&#xff1f;我的鼠标不见了现在触摸板也没反应&#xff0c;根本就用不了电脑了&#xff0c;有什么方法可以解决吗&#xff1f;” 触摸板是笔记本电脑上最重要的输入设备之一&#xff0c;它可以提供便捷的操作方式。对于很多朋友来说&…

SQL 执行计划管理(SPM)

一、SPM 需求背景 任何数据库应用程序的性能在很大程度上都依赖于查询执行&#xff0c;尽管优化器无需用户干预就可以评估最佳计划&#xff0c;但是 SQL 语句的执行计划仍可能由于以下多种原因发生意外更改&#xff1a;版本升级、重新收集优化器统计信息、改变优化器参数或模式…