直方图均衡化

根据直方图的原理,记录一下代码实现流程。

一、计算原始图像的灰度直方图

  1. 首先获取图片大小
w = img.shape[0]#获取图片宽度
h = img.shape[1]#获取图片高度
  1. 定义数组
n = np.zeros((256), dtype=np.float)#定义数组保存每个灰度的数量
p = np.zeros((256), dtype=np.float)#定义数组保存每个灰度出现的概率P(rk)
c = np.zeros((256), dtype=np.float)#定义数组保存每个灰度出现的概率P(sk')
  1. 遍历图像的每个像素,得到每个像素的数量
# 遍历图像的每个像素,得到每个像素的数量
for x in range(0, img.shape[0]):
    for y in range(0, img.shape[1]):
        print(img[x][y])
        n[img[x][y]] += 1

二、计算原始图像的灰度分布频率

for i in range(0, 256):
    p[i] = n[i] / m

三、计算原始图像的灰度累积分布频率

c[0] = p[0]
for i in range(1, 256):
    c[i] = c[i - 1] + p[i]

四、计算rk

des = np.zeros((w, h, 3), dtype=np.uint8)
for x in range(0, w):
    for y in range(0, h):
        des[x][y] = 255 * c[img[x][y]]

灰度直方图均衡化完毕。

五、完整代码如下

import cv2
import numpy as np

img = cv2.imread('D:/project/intelligent image analysis/jetplane.png')#读图
########## Begin ##########

w = img.shape[0]#获取图片宽度
h = img.shape[1]#获取图片高度
m = w*h#获取图片大小
print('w',w)
print('h',h)
print('m',m)


n = np.zeros((256), dtype=np.float)#定义数组保存每个灰度的数量
p = np.zeros((256), dtype=np.float)#定义数组保存每个灰度出现的概率P(rk)
c = np.zeros((256), dtype=np.float)#定义数组保存每个灰度出现的概率P(sk')

# 遍历图像的每个像素,得到每个像素的数量
for x in range(0, img.shape[0]):
    for y in range(0, img.shape[1]):
        print(img[x][y])
        n[img[x][y]] += 1
print('n', n)

# 计算灰度分布率
for i in range(0, 256):
    p[i] = n[i] / m
print('p', p)

# 计算原始图像累计灰度分布率
c[0] = p[0]
for i in range(1, 256):
    c[i] = c[i - 1] + p[i]
print('c', c)

#得到rk
des = np.zeros((w, h, 3), dtype=np.uint8)
for x in range(0, w):
    for y in range(0, h):
        des[x][y] = 255 * c[img[x][y]]
print('des', des)

out = des
########## End ##########
cv2.imwrite('D:\project\intelligent image analysis\out.png', out)

需要自己填写的部分为"Begin"和"End"之间的部分。

六、错误记录

  1. 最开始统计原始图像灰度直方图时,输入代码如下:
#遍历图像的每个像素,得到统计分布直方图
for x in range(0,img.shape[0]):
for y in range(0,img.shape[1]):
n[img[x][y]] += 1
print n

然后运行时出现了下面这个错误:

IndentationError: expected an indented block

经过查阅,发现是格式不对,应该改为下面的格式:

for x in range(0, img.shape[0]):
    for y in range(0, img.shape[1]):
        n[img[x][y]] += 1
print('n', n)

详情参考这位大佬这位大佬的帖子。

  1. 计算原始图像灰度分布率和灰度累计分布率时,最开始代码如下:
for i in range(0,256):
	p[i] = n[i]/float(img.size)
print('p', p)

# 计算原始图像累计灰度分布率
c[0] = p[0]
for i in range(1, 256):
    c[i] = c[i - 1] + p[i]
print('c', c)

由于我将c打印了出来,于是在这里便看出了不对头。
n、p、c这三个数组的值如下图所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
显然c数组最后的值不满足加和为1。再回去找原因,发现可能是img.size的原因。查阅发现,它是像素长宽之积,也就是像素数量。然而,将它和图片长宽之积m=wh打印出来之后发现并不相等:
在这里插入图片描述
此处发现,长宽之积为512
512=262144,而img.size=786432=3wh。此处我输入为一张灰度图,只有一个通道,因而我需要的值为m。
经过查阅发现,begin之前的语句

img = cv2.imread('D:/project/intelligent image analysis/jetplane.png')#读图

默认输入为3通道图片,详情请参考这位大佬的帖子

将img.size更改为m后,再次打印n、p、c这三个数组,没有问题:
在这里插入图片描述
在这里插入图片描述
最终加和为1。

  1. 将sk’量化为sk时,原代码如下:
des = np.zeros((w, h), dtype=np.uint8)
for x in range(0, w):
    for y in range(0, h):
        des[x][y] = 255 * c[img[x][y]]
print('des', des)

运行之后出现如下错误:

ValueError: setting an array element with a sequence.

经查阅发现还是数组对不上的原因。将img[x][y]打印出来后发现,是一个三维数组(此处只截取了一部分),且三个维度数值都相同:
在这里插入图片描述
联想刚刚那位大佬所介绍的,我将第一行输入的图像改为单通道,即将begin之前的那一行改为:

img = cv2.imread('D:/project/intelligent image analysis/jetplane.png', 0)#读图

没有报错,数组变为一维:
在这里插入图片描述
des也正确输出:
在这里插入图片描述
图片也得到增强。
然而规定begin之前的代码不能被改动,那么此处我将des数组改为3维,如下:

des = np.zeros((w, h, 3), dtype=np.uint8)

代码正确运行,没有错误。des数组如下:
在这里插入图片描述
图片增强效果如下:
在这里插入图片描述
在这里插入图片描述

  1. 将输入图片改为一张3通道的彩色图片,增强效果如下:
    在这里插入图片描述
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值