图像增强之灰度变换和直方图均衡化(附代码python+opencv)

news2025/7/18 8:20:01

一、图像增强的概念和分类

概念:图像增强是采用一系列技术去改善图像的视觉效果,或将图像转换成一种更适合于人或机器进行分析和处理的形式。例如采用一系列技术有选择地突出某些感兴趣的信息,同时抑制一些不需要的信息,提高图像的使用价值。
分类:图像增强方法由增强的作用域出发,可分为空间域增强和频率域增强两种。
空间域增强是直接对图像的各像素进行处理;
频率域增强是对图像进行傅里叶变换后的频谱成分进行处理,然后逆傅里叶变换获得所需的图像。

  1. 空间域增强
    点运算:灰度变换、直方图修正(均衡化和规定化)
    局部运算:图像平滑、图像锐化

  2. 频率域增强
    高通滤波、低通滤波、同态滤波

二、灰度变换

  • 灰度变换和二值化的区别:
  • 灰度变换是调整调整图像的灰度动态范围或图像对比度
  • 二值化是将图像的每个像素点调至0或255,只呈现白色或黑色

二值化的代码:方法一:固定阈值二值化

# function:将灰度图片转为二值化图片,方法一:固定阈值二值化
import cv2 as cv

gray_img = cv.imread('./img/gray_img.png')

# 二值化函数
ret, erzhihua_img = cv.threshold(gray_img, 100, 255, cv.THRESH_BINARY)

cv.imshow('erzhihua_img', erzhihua_img)
cv.imwrite('./img/erzhihua_img.png', erzhihua_img)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述
方法二:算术平均的自适应二值化

# function:算术平均的自适应二值化
import cv2 as cv

# 这里很奇怪,不能直接传灰度图片的imread路径,要直接是灰度图片,像下面这样
img = cv.imread('./img/img.png')
gray_img = cv.cvtColor(img, cv.COLOR_RGB2GRAY)

# 二值化函数
erzhihua_img = cv.adaptiveThreshold(gray_img, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 11, 2)

cv.imshow('erzhihua_img', erzhihua_img)
cv.imwrite('./img/erzhihua1_img.png', erzhihua_img)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述
方法三:高斯加权均值法自适应二值化

# function:高斯加权均值法自适应二值化
import cv2 as cv

# 这里很奇怪,不能直接传灰度图片的imread路径,要直接是灰度图片,像下面这样
img = cv.imread('./img/img.png')
gray_img = cv.cvtColor(img, cv.COLOR_RGB2GRAY)

# 二值化函数
erzhihua_img = cv.adaptiveThreshold(gray_img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 11, 8)

cv.imshow('erzhihua_img', erzhihua_img)
cv.imwrite('./img/erzhihua2_img.png', erzhihua_img)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

灰度变换通俗理解为将直方图的动态范围从小变大。

在这里插入图片描述
简单的将图像变灰:方法一

import cv2 as cv

img = cv.imread('./img/img.png')
cv.imshow('rgb_img', img)

gray_img = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
cv.imshow('gray_img', gray_img)

cv.imwrite('./img/gray_img.png', gray_img)

cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述
方法2:

import cv2 as cv

gray1_img = cv.imread('./img/img.png', 0)

cv.imshow('gray1_img', gray1_img)

cv.imwrite('./img/gray1_img.png', gray1_img)

cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

1、线性变换

将a ~ b映射到a’ ~ b’,当ab比a’b’小的时候,做的是灰度的拉伸,将图像变得更清晰,对比度越大,下图斜线的斜率是>1。

在这里插入图片描述

2、分段线性变换

拉伸感兴趣的灰度区间。

在这里插入图片描述

3、非线性变换

在这里插入图片描述
对数变换代码:

import cv2 as cv
import copy
import math

# 读入原始图像
img = cv.imread('./img/img.png', 1)

# 灰度化处理:此灰度化处理用于图像二值化
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 对数变换
logc = copy.deepcopy(gray)
rows = img.shape[0]
cols = img.shape[1]
for i in range(rows):
    for j in range(cols):
        logc[i][j] = 10 * math.log(1 + logc[i][j])

# 通过窗口展示图片 第一个参数为窗口名 第二个为读取的图片变量

cv.imshow('logc', logc)
cv.imwrite('./img/logc_img.png', logc)

cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

4、伽马变换

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 代码中的系数为gamma的倒数,一般为2.2

gamma变换代码1:

import cv2 as cv
import numpy as np


# gamma correction
def gamma_correction(img, c=1, g=2.5):
    out = img.copy()
    out /= 255.
    out = (1 / c * out) ** (1 / g)
    out *= 255
    out = out.astype(np.uint8)
    return out


# Read image
img = cv.imread('./img/img.png').astype(np.float)

# Gammma correction
out = gamma_correction(img)

# Save result
cv.imshow("result", out)
cv.imwrite("./img/gamma1.jpg", out)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述
gamma变换代码2:

import cv2 as cv
import copy

# 读入原始图像
img = cv.imread('./img/img.png', 1)

# 伽马变换
gamma = copy.deepcopy(img)
rows = img.shape[0]
cols = img.shape[1]
for i in range(rows):
    for j in range(cols):
        gamma[i][j] = 3 * pow(gamma[i][j], 0.5)

cv.imshow('gamma', gamma)
cv.imwrite("./img/gamma2.jpg", gamma)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

三、直方图均衡化

在这里插入图片描述
在这里插入图片描述

计算过程:Sk计到Sk并需要离散化一下(近似),就把原图当中的0~7对应过来了(注意不一定是一一对应)

在这里插入图片描述
结果:近似的
在这里插入图片描述
均衡化的图像:
在这里插入图片描述
直方图均衡化代码:(最普通的均衡化)

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('./img/img.png', 0)
# flatten() 将数组变成一维
hist, bins = np.histogram(img.flatten(), 255, [0, 255])
# 计算累积分布图
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max() / cdf.max()
# 作图
plt.figure(figsize=(14, 14), dpi=100)
plt.subplot(1, 2, 1)
plt.plot(cdf_normalized, color='b')
plt.hist(img.flatten(), 255, [0, 255], color='r')
plt.xlim([0, 255])
plt.title('before')
plt.legend(('cdf', 'histogram'), loc='upper left')
# plt.show()

equ = cv2.equalizeHist(img)  # 该函数的输入只能是灰度图,equalizeHist只能显示单通道函数
res = np.hstack((img, equ))

# 计算均衡化后的直方图
hist1, bins1 = np.histogram(res.flatten(), 255, [0, 255])
cdf1 = hist1.cumsum()
cdf1_normalized = cdf1 * hist1.max() / cdf1.max()

plt.subplot(1, 2, 2)
plt.plot(cdf1_normalized, color='b')
plt.hist(res.flatten(), 255, [0, 255], color='r')
plt.xlim([0, 255])
plt.legend(('cdf', 'histogram'), loc='upper left')
plt.title('after')
plt.savefig('./img/zhifangtu.png')
plt.show()

# stacking images side-by-side
cv2.imshow('img', res)
cv2.imwrite('./img/zhifangtu_img.png', res)
cv2.waitKey()
cv2.destroyAllWindows()

直方图对比:
在这里插入图片描述
结果对比:
在这里插入图片描述
CLAHE 有限对比适应性直方图均衡化(自适应直方图均衡化):将直方图分成一小块一小块的,每一块进行直方图均衡化:
代码:

# function:CLAHE直方图均衡化
import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('./img/img.png', 0)

# flatten() 将数组变成一维
hist, bins = np.histogram(img.flatten(), 255, [0, 255])
# 计算累积分布图
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max() / cdf.max()
# 作图
plt.figure(figsize=(14, 14), dpi=100)
plt.subplot(1, 2, 1)
plt.plot(cdf_normalized, color='b')
plt.hist(img.flatten(), 255, [0, 255], color='r')
plt.xlim([0, 255])
plt.title('before')
plt.legend(('cdf', 'histogram'), loc='upper left')

clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
cl1 = clahe.apply(img)

# 计算均衡化后的直方图
hist1, bins1 = np.histogram(cl1.flatten(), 255, [0, 255])
cdf1 = hist1.cumsum()
cdf1_normalized = cdf1 * hist1.max() / cdf1.max()

plt.subplot(1, 2, 2)
plt.plot(cdf1_normalized, color='b')
plt.hist(cl1.flatten(), 255, [0, 255], color='r')
plt.xlim([0, 255])
plt.legend(('cdf', 'histogram'), loc='upper left')
plt.title('after')
plt.savefig('./img/clahe.png')
plt.show()

cv2.imwrite('./img/clahe_1.jpg', cl1)
cv2.waitKey()
cv2.destroyAllWindows()

直方图对比:
在这里插入图片描述
结果对比:
在这里插入图片描述
彩色图片的均衡化:先进行通道数分解,再合成
代码:

# 彩色图像均衡化
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('./img/img.png', 1)

# 原图像直方图
# flatten() 将数组变成一维
hist, bins = np.histogram(img.flatten(), 255, [0, 255])
# 计算累积分布图
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max() / cdf.max()
# 作图
plt.figure(figsize=(14, 14), dpi=100)
plt.subplot(1, 2, 1)
plt.plot(cdf_normalized, color='b')
plt.hist(img.flatten(), 255, [0, 255], color='r')
plt.xlim([0, 255])
plt.title('before')
plt.legend(('cdf', 'histogram'), loc='upper left')

(b, g, r) = cv2.split(img)  # 通道分解
bH = cv2.equalizeHist(b)
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
result = cv2.merge((bH, gH, rH), )  # 通道合成
res = np.hstack((img, result))

# 计算均衡化后的直方图
hist1, bins1 = np.histogram(res.flatten(), 255, [0, 255])
cdf1 = hist1.cumsum()
cdf1_normalized = cdf1 * hist1.max() / cdf1.max()

plt.subplot(1, 2, 2)
plt.plot(cdf1_normalized, color='b')
plt.hist(res.flatten(), 255, [0, 255], color='r')
plt.xlim([0, 255])
plt.legend(('cdf', 'histogram'), loc='upper left')
plt.title('after')
plt.savefig('./img/zhifangtu_rgb_1.png')
plt.show()

cv2.imshow('dst', res)
cv2.imwrite('./img/zhifangtu_rgb.png', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

直方图对比:
在这里插入图片描述
结果对比:
在这里插入图片描述

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

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

相关文章

(JVM)双亲委派机制

Java 虚拟机对 class 文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的 class 文件加载到内存生成 class 对象。而且加载某个类的 class 文件时,Java 虚拟机采用的是双亲委派模式,即把请求交由父类处理,它是一种任…

文档基础模型引领文档智能走向多模态大一统

编者按:自2019年以来,微软亚洲研究院在文档智能领域进行了诸多探索,开发出一系列多模态任务的文档基础模型 (Document Foundation Model),包括 LayoutLM (v1、v2、v3) 、LayoutXLM、MarkupLM 等。这些模型在诸如表单、收据、发票、…

MySQL中find_in_set函数的使用

1.语法 FIND_IN_SET(str,strlist) (1)str 要查询的字符串 (2)strlist 字段名; 参数以”,”分隔 如 (1,2,6,8) 查询字段(strlist)中包含(str)的结果,返回结果为null或记录 假如字符串str在由N个子链组成的…

5G无线技术基础自学系列 | 物理上行控制信道

素材来源:《5G无线网络优化实践》 一边学习一边整理内容,并与大家分享,侵权即删,谢谢支持! 附上汇总贴:5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 PUCCH用于传输上行控制信息(U…

岭回归、Lasso回归和弹性网络

减少过拟合的一个好方法是对模型进行正则化(即约束模型):它拥有的自由度越少,则过拟合数据的难度就越大。正则化多项式模型的一种简单方法是减少多项式的次数。 对于线性模型,正则化通常是通过约束模型的权重来实现的。…

记一次生产中使用CompletableFuture遇到的坑

为什么使用CompletableFuture 业务功能描述:有一个功能是需要调用基础平台接口组装我们需要的数据,在这个功能里面我们要调用多次基础平台的接口,我们的入参是一个id,但是这个id是一个集合。我们都是使用RPC调用,一般…

【22年11月12日更新】搭建宝塔面板、青龙面板“京东代挂”

本文章仅供学习 一、青龙面板是什么? 青龙面板可以运行某东脚本,你在某宝、某度等各个渠道搜索“京东代挂”,都是用青龙面板。 二、搭建宝塔面板 1.更新 yum 包 首先下载finalshell通过账号密码连接服务器,然后输入 yum up…

零基础程序员想要学好.Net,跟着这7个步骤学习就可以了

作为一个初学者程序员,很喜欢问的一个问题就是:零基础如何自学编程?在后台也有很多读者私信我,问我这个问题,其实这个问题比较大,不是一两句就可以说清楚的。 所以,今天结合我个人的经历&#x…

注意力机制详解(Attention详解)

注意力机制与人眼类似,例如我们在火车站看车次信息,我们只关注大屏的车次信息,而忽略大屏外其他内容,从而导致钱包被偷。。。 注意力机制只关注重点信息,忽略不重要的信息,关注最核心的内容。 主要就是这…

推荐系统实战2——EasyRec 推荐框架环境配置

推荐系统实战2——EasyRec 推荐框架环境配置学习前言先验条件EasyRec仓库地址EasyRec环境配置一、EasyRec的下载二、EasyRec的初始化三、EasyRec的安装四、一些额外的情况学习前言 EasyRec是阿里巴巴开源的推荐系统框架。生命苦短,从建好的推荐系统框架开始学&…

【C++】STL简介 -- string 的使用及其模拟实现

文章目录一、STL 简介1、什么是 STL2、STL 的版本3、STL 的六大组件4、STL 的重要性5、如何学习 STL二、string 类的使用1、什么是 string2、string 类模板3、构造函数4、Iterators5、Capacity6、Element Access7、Modify8、String Operations9、Non-member function overloads…

Arduino程序设计(二) 按键控制LED灯

按键控制LED灯程序设计前言一、按键控制LED灯——内部上拉(基础)二、按键控制LED灯——外部上拉(基础)三、按键控制LED灯(进阶)总结参考文献前言 本文主要介绍三种按键控制LED灯的实现方式,分别…

PatchCore原理与代码解读

paper:Towards Total Recall in Industrial Anomaly Detection code:GitHub - amazon-science/patchcore-inspection 存在的问题 目前无监督缺陷检测常用的一种方法是直接利用在ImageNet上预训练的模型中的表示,而不专门进行目标分布的迁…

从零开始将图片信息和空间信息绑定,并在前端展示到地图

作者:xiaoyan 关键词:前端查询时展示和空间数据绑定的图片资源 本文适合零基础入门 背景:iServer支持空间查询,可以将空间数据属性表中的属性查询出来,如通过SQL语句查询出某地大楼实际层高,或者查询出某…

RHCE实验--配置nfs服务

1、开放/nfs/shared目录,供所有用户查询资料; 2、开放/nfs/upload目录,供所有用户上传下载资料; 服务器与客户端都写好yum源以及挂载光盘,然后安装服务包 [rootserver ~]# yum install rpcbind -y [rootserver ~]# y…

Vue3基础

Vue 官网 https://cn.vuejs.org/ https://v3.cn.vuejs.org/ https://staging-cn.vuejs.org/api/ 1、环境 1.1、nodejs node node -vnpm #当前版本 npm -v #升级npm版本 npm install -g npm1.2、vue #安装vue npm install -g vue-cli #安装最新版本 npm install -g vu…

LQ0197 锦标赛【程序填空】

题目来源:蓝桥杯2014初赛 C A组E题 题目描述 本题为代码补全填空题,请将题目中给出的源代码补全,并复制到右侧代码框中,选择对应的编译语言(C/Java)后进行提交。若题目中给出的源代码语言不唯一&#xff0…

Python简单实现人脸识别检测, 对照片进行评分

大家好,今天和大家说说如何用Python简单实现人脸识别检测, 对照片进行排名,看看自己有多漂亮。 [开发环境]: Python 3.8 Pycharm 2021.2 [模块使用]: requests >>> pip install requeststqdm >>> pip install tqdm 简单实现进度条效果…

Arduino从零开始(1)——按钮控制LED

0.前言 本文主要介绍Arduino对于开关和条件判断函数的使用。 目录 0.前言 1.介绍 2.按钮控制LED 2.1下拉模式: 2.2上拉模式 3.扩展实验: 1.介绍 前篇介绍了点亮LED,这次案例我们尝试通过一个简单的传感器——按钮,来实现…

Ubuntu20.04离线安装Vmware tools

参考连接:在 Linux 虚拟机中手动安装 VMware Tools 从 Workstation Pro 菜单栏中选择虚拟机 > 安装 VMware Tools。 如果安装了早期版本的Vmware tools,则菜单项是更新Vmware tools如果这个安装Vmware tools 是灰色的,进行如下的处理方式…