当前位置: 首页 > news >正文

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

本次实验主要从基于统计、函数映射的图像增强方法和基于滤波的图像增强方法两种方法中对一些图像增强的算法进行实现。主要的编程语言为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库,这些的使用让我们更加地了解图像处理的方式。同时通过对这些库的练习也让我更加熟练地直接操作图像的像素点。理论课中讲解的关于图像增强方法的知识,在代码编辑实现过程中均得以体现,通过实验对理论知识理解也更加深入。总而言之,此次的实验让我对图像增强方法以及图像的处理方法有了更加深入的了解。

相关文章:

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

本次实验主要从基于统计、函数映射的图像增强方法和基于滤波的图像增强方法两种方法中对一些图像增强的算法进行实现。主要的编程语言为python&#xff0c;调用了python自带的PIL图像库用于读取图像&#xff0c;利用numpy进行图像运算&#xff0c;最后使用opencv第三方库进行对…...

ES6:Generator函数详解

ES6&#xff1a;Generator函数详解 1、 概念2、yield表达式2.1 yield 语句与 return 语句区别2.2 Generator函数不加yield语句&#xff0c;这时变成了一个单纯的暂缓执行函数2.3 yield 表达式只能用在 Generator 函数里面&#xff0c;用在其它地方都会报错2.4 yield 表达式如果…...

前端小练-产品宣传页面

文章目录 前言页面结构固定钉头部轮播JS特效 完整代码总结 前言 经过一个月的爆肝&#xff0c;花费了一个月&#xff08;期间还花费了将近半个月的时间打比赛&#xff0c;还要备研&#xff09;算是把数二高数的内容强化了一遍&#xff0c;接下来刷熟练度即可&#xff0c;可惜的…...

arm学习之stm32设备树学习-中断控制led灯亮灭+字符设备指令控制led灯亮灭

中断控制led灯亮灭 驱动文件源码 led-key.c #include<linux/init.h> #include<linux/module.h> #include<linux/of.h> #include<linux/of_gpio.h> #include<linux/gpio.h> #include<linux/of_irq.h> #include<linux/interrupt.h> s…...

快速开发框架若依的基础使用详解

Hi I’m Shendi 快速开发框架若依的基础使用详解 最近在为公司制作新的项目&#xff0c;经过了一段时间的技术沉淀&#xff0c;我开始尝试接触市面上用的比较多的快速开发框架&#xff0c;听的最多的当属若依吧 于是就选用了若依 介绍 为什么选&#xff1f;目的是为了提高开发…...

RabbitMQ 教程 | 第4章 RabbitMQ 进阶

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…...

小程序如何从分类中移除商品

​有时候商家可能需要在商品分类中删除某些商品&#xff0c;无论是因为商品已下架、库存不足还是其他原因。在这篇文章中&#xff0c;我们将介绍如何从分类中移除商品。 方式一&#xff1a;分类管理中删除商品。 进入小程序管理后台&#xff0c;找到分类管理&#xff0c;在分…...

P1219 [USACO1.5] 八皇后 Checker Challenge

题目 思路 非常经典的dfs题&#xff0c;需要一点点的剪枝 剪枝①&#xff1a;行、列&#xff0c;对角线的标记 剪枝②&#xff1a;记录每个皇后位置 代码 #include<bits/stdc.h> using namespace std; const int maxn105; int a[maxn];int n,ans; bool vis1[maxn],vis…...

如何在不使用脚本和插件的情况下手动删除 3Ds Max 中的病毒?

如何加快3D项目的渲染速度&#xff1f; 3D项目渲染慢、渲染卡顿、渲染崩溃&#xff0c;本地硬件配置不够&#xff0c;想要加速渲染&#xff0c;在不增加额外的硬件成本投入的情况下&#xff0c;最好的解决方式是使用渲云云渲染&#xff0c;在云端批量渲染&#xff0c;批量出结…...

SpringCloud Gateway 在微服务架构下的最佳实践

作者&#xff1a;徐靖峰&#xff08;岛风&#xff09; 前言 本文整理自云原生技术实践营广州站 Meetup 的分享&#xff0c;其中的经验来自于我们团队开发的阿里云 CSB 2.0 这款产品&#xff0c;其基于开源 SpringCloud Gateway 开发&#xff0c;在完全兼容开源用法的前提下&a…...

Android studio修改app图标

步骤如下&#xff1a; 1.右键app名称→New→ImageAsset 2. 进行下面的配置 图源&#xff1a;https://blog.csdn.net/Qingshan_z/article/details/126661650 3.配置分辨率 4.图标自动保存在mipmap文件夹下 再启动就更换成功了&#xff01;&#xff01;&#xff01; 参考&…...

<C++> 三、内存管理

1.C/C内存分布 我们先来看下面的一段代码和相关问题 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";const char *pChar3 "abcd";int *ptr1…...

大模型开发(十五):从0到1构建一个高度自动化的AI项目开发流程(上)

全文共5600余字&#xff0c;预计阅读时间约13~20分钟 | 满满干货(附全部代码)&#xff0c;建议收藏&#xff01; 本文目标&#xff1a;提出一种利用大语言模型(LLMs)加快项目的开发效率的解决思路&#xff0c;本文作为第一部分&#xff0c;主要集中在如何完整的执行引导Chat模…...

HarmonyOS 开发基础(二)组件拼凑简单登录页面

一、简单登录页面 Entry Component /* 组件可以基于struct实现&#xff0c;组件不能有继承关系&#xff0c;struct可以比class更加快速的创建和销毁。*/ struct Index {State message: string Hello Worldbuild() {// https://developer.harmonyos.com/cn/docs/documentation/…...

flutter minio

背景 前端 经常需要上传文件 图片 视频等等 到后端服务器&#xff0c; 如果到自己服务器 一般会有安全隐患。也不方便管理这些文件。如果要想使用一些骚操作 比如 按照前端请求生成不同分辨率的图片&#xff0c;那就有点不太方便了。 这里介绍以下 minio&#xff0c;&#xff0…...

ChatGPT:人工智能交互的新时代

ChatGPT的背景和发展&#xff1a; ChatGPT是OpenAI公司在GPT-3基础上的进一步升级。GPT&#xff08;Generative Pre-trained Transformer&#xff09;是一种基于Transformer架构的深度学习模型&#xff0c;它能够处理自然语言&#xff0c;实现自动对话、写作等任务。而ChatGPT在…...

C. Binary String Copying - 思维

分析&#xff1a; 赛时我是直接模拟的&#xff0c;tle然后mle&#xff0c;补提&#xff0c;发现规律&#xff0c;每一个改变的字符串都只会对应一个需要改变的区间&#xff0c;例如第一个样例前两个101100 -> 011100和101100 -> 011100&#xff0c;对应区间在确定改变的范…...

哈工大计算机网络课程网络安全基本原理详解之:密钥分发中心与公钥认证中心

哈工大计算机网络课程网络安全基本原理详解之&#xff1a;密钥分发中心与公钥认证中心 在介绍密钥分发中心的概念前&#xff0c;先来回顾一下之前介绍的身份认证协议AP4.0&#xff1a;利用随机数R来避免“回放攻击”&#xff0c;并借助于对称加密算法来保证R的加密传输和解密&…...

md5sum

概念作用及原理 md5sum是一种常用的哈希算法&#xff0c;用于计算数据的MD5哈希值。MD5&#xff08;Message Digest Algorithm 5&#xff09;是一种广泛使用的加密散列函数&#xff0c;用于将任意长度的数据映射为固定长度的哈希值&#xff08;通常是128位&#xff09;。这个哈…...

图文档数字化:实现高效管理的几大步骤

在当今数字化时代&#xff0c;企业越来越意识到数字化管理对于图文档的重要性。传统的纸质文件管理往往效率低下&#xff0c;容易出现丢失和混乱的情况。为了提高工作效率、降低成本并确保数据安全&#xff0c;许多企业选择采用PDM&#xff08;产品数据管理&#xff09;系统来实…...

服务器磁盘占用过高分析

使用命令 du -sh查看出占用较大的目录&#xff0c;如下&#xff1a; 目录大小处理办法/usr/local/mysql/data16G转移部分文件/usr/local/nacos2.1G维持现状/logs4.4G删除部分文件/var1.9G删除部分文件 du -sh命令使用示例&#xff1a; du -sh /* 查看根目录各文件(夹)占用大小…...

【C语言】通讯录3.0 (文件存储版)

前言 通讯录是一种记录联系人信息的工具&#xff0c;包括姓名、电话号码、电子邮件地址、住址等。 文章的一二三章均于上一篇相同&#xff0c;可以直接看第四章改造内容。 此通讯录是基于通讯录2.0&#xff08;动态增长版&#xff09;的基础上进行增加文件操作功能&#xff0c…...

【C#常用操作】

excel相关操作 using Excel Microsoft.Office.Interop.Excel;public Excel.Application app; public Excel.Workbooks wbs; public Excel.Workbook wb; public Excel.Worksheets wss; public Excel.Worksheet ws;/// <summary> /// 取得打开excel句柄 /// </summary…...

深入理解CountDownLatch计数器

入理解CountDownLatch计数器 其他知识点 Java 多线程基础 深入理解aqs ReentrantLock用法详解 深入理解信号量Semaphore 深入理解并发三大特性 并发编程之深入理解CAS 深入理解CountDownLatch Java 线程池 使用用法 CountDownLatch用法详解 CountDownLatch实现原理 下面例子来…...

从SQL注入绕过最新安全狗WAF中学习fuzz

前言 SQL注入并不是很精通&#xff0c;通过实战绕过WAF来进行加强SQL注入能力&#xff0c;希望对正在学习的师傅能有一丝帮助。 安装 安装前言 我是本地搭建的环境进行测试的 环境是windows11phpstudy2018sqli-labs phpstudy的安装我不再复述&#xff0c;这里简单说一下安全…...

C语言每日一题:12《数据结构》相交链表。

题目&#xff1a; 题目链接 思路一&#xff1a; 1.如果最后一个节点相同说明一定有交点。 2.使用两个循环获取一下长度&#xff0c;同时可以获取到尾节点。 3。注意初始化lenA和lenB为1&#xff0c;判断下一个节点是空是可以保留尾节点的。长度会少一个&#xff0c;尾节点没有…...

【Spring框架】SpringMVC

目录 什么是Spring MVC实现客户端和程序之间的“连接”1.1 RequestMapping1.2GetMapping1.3PostMapping 获取参数2.1.1 获取单个参数2.1.2 获取多个参数2.1.3 获取对象2.2 后端参数重命名2.3 RequestBody 接收JSON对象2.4 获取URL中参数PathVariable2.5 上传⽂件RequestPart2.6…...

HDFS中namenode安全模式

HDFS中namenode安全模式 安全模式的现象探究step1step2step3step4 安全模式的概述控制进入时间和离开条件安全模式自动进入离开安全模式手动进入离开 安全模式的现象探究 step1 HDFS集群在停机状态下&#xff0c;使用hdfs -daemon命令逐个进程启动集群&#xff0c;观察现象首…...

blender凹凸感和置换形变

一、怎么做出凹凸感 需要三个部分的内容&#xff1a; 1、一个基础的纹理&#xff1a;告诉计算机需要用一个什么样的纹理做凹凸&#xff0c;纹理一般采用黑白&#xff0c;在计算机里面&#xff0c;从 0 - 1之间的值可以用从黑到白之间不同的灰度来表示因此&#xff0c;有一张黑白…...

力扣 343. 整数拆分

题目来源&#xff1a;https://leetcode.cn/problems/integer-break/description/ C题解1&#xff1a;动态规划。dp[i] 代表数字i拆分后得到的最大乘积。递归公式为拆分后两个数的最大乘积相乘&#xff0c;即 dp[i] max(dp[i], dp[j] * dp[i-j])。对于n2或3需要另外讨论。 cla…...