文章目录
- 绘制直方图
- 1.矩阵扁平化
- 2.plt.hist()
- 3.绘制原图的等高线
- 4.彩色图片直方图
- 直方图均衡化
- 1.np.histogram()
- 2.均衡化
- 3.调用cv2.equalizeHist()
- 4.彩色图直方图均衡化
绘制直方图
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
im = np.array(Image.open('lina2.png').convert('L'))
plt.hist(im.flatten(),255)
plt.show()
1.矩阵扁平化
注意:要将像素矩阵扁平化
220行220列变成一行48400列
b=im.flatten()
2.plt.hist()
bins是柱子的数目
其他具体参数:
n, bins, patches = plt.hist(arr, bins=50, normed=1, facecolor=‘green’, alpha=0.75)
hist的参数非常多,但常用的就这五个,只有第一个是必须的,后面四个可选
arr: 需要计算直方图的一维数组
bins: 直方图的柱数,可选项,默认为10
normed: 是否将得到的直方图向量归一化。默认为0 现在好像改成了density
facecolor: 直方图颜色
alpha: 透明度
返回值 :
n: 直方图向量,是否归一化由参数设定
bins: 返回各个bin的区间范围
patches: 返回每个bin里面包含的数据,是一个list
没有归一化的
plt.hist(im.flatten(),bins=10,color='y',range=(100,200))
Out[5]:
(array([3175., 2690., 3897., 3903., 4223., 4622., 2712., 2226., 1292.,
1735.]),
array([100., 110., 120., 130., 140., 150., 160., 170., 180., 190., 200.]),
<a list of 10 Patch objects>)
归一化的:
n, bins, patches = plt.hist(im.flatten(), bins=255, density=1)
看看返回值是什么:n: 直方图向量,是否归一化由参数设定,就是每个柱子高度
bins: 返回各个bin的区间范围
patches: 返回每个bin里面包含的数据,是一个list(n和bins两个返回值的合并)
3.绘制原图的等高线
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
# read image to array
im = np.array(Image.open('lina2.png').convert('L'))
# create a new figure
plt.subplot(1,3,1)
plt.imshow(im)
# don’t use colors
plt.subplot(1,3,2);plt.gray()
# show contours with origin upper left corner
#在Lina图上绘制等高线
plt.contour(im, origin='image')
plt.axis('equal')
plt.axis('off')
plt.subplot(133)
# #注意要将图像扁平化
plt.hist(im.flatten(),255)
plt.show()
4.彩色图片直方图
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("lina2.png",1)
(b, g, r) = cv2.split(img)
plt.figure("lena")
ar=np.array(r).flatten()
plt.hist(ar, bins=256, density=1,facecolor='r',edgecolor='r')
ag=np.array(g).flatten()
plt.hist(ag, bins=256, density=1, facecolor='g',edgecolor='g')
ab=np.array(b).flatten()
plt.hist(ab, bins=256, density=1, facecolor='b',edgecolor='b')
plt.show()
直方图均衡化
1.np.histogram()
用法与plt.hist类似
imhist, bins = np.histogram(im, 255, density=True)
矩阵不用flatten()了,得到的结果imhist与上述plt.hist的返回值n是一样的
2.均衡化
-*- coding: utf-8 -*-
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import cv2
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def histeq(im, nbr_bins=256):
# 对一副灰度图像进行直方图均衡化
# 该函数有两个输入参数,一个是灰度图像,一个是直方图中使用小区间的数目
# 函数返回直方图均衡化后的图像,以及用来做像素值映射的累计分布函数
# 计算图像的直方图
imhist, bins =np.histogram(im.flatten(), nbr_bins, normed=True)
cdf = imhist.cumsum() # cumulative distribution function最后一个值接近于1,可以近似为1
cdf = 255 * cdf / cdf[-1] # 归一化,函数中使用累计分布函数的最后一个元素(下标为-1,目标是
# 将其归一化到0-1范围 )
# 使用累计分布函数的线性插值,计算新的像素值
im2 = np.interp(im.flatten(), bins[:-1], cdf) # im2 is an array
return im2.reshape(im.shape), cdf
im = np.array(Image.open('lina2.png').convert('L'))
im2, cdf = histeq(im)
im20 = Image.fromarray(im) # 未直方图均衡化的图像
im21 = Image.fromarray(im2) # 直方图均衡化后的 将array转化为图像
plt.figure(num='lina')
plt.subplot(2, 2, 1)
plt.title("Before the experiment");plt.axis('off')
plt.imshow(im, plt.cm.gray)
plt.subplot(2,2,2)
plt.hist(im.flatten(),255)
plt.title("未均衡化的直方图");plt.axis('off')
plt.subplot(2, 2, 3)
plt.title("After the experiment") ; plt.axis('off')
plt.imshow(im2, plt.cm.gray)
plt.subplot(2, 2, 4)
plt.title("均衡化后的直方图") ; plt.axis('off')
plt.hist(im2.flatten(),255)
plt.show()
3.调用cv2.equalizeHist()
但是cv2.equalizeHist()只提供灰度值图片的处理
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import cv2
lina=cv2.imread('lina2.png',0)
dst = cv2.equalizeHist(lina)
plt.subplot(223);plt.imshow(dst,'gray');plt.title('after')
plt.subplot(224);plt.hist(dst.flatten(),255)
plt.subplot(221);plt.imshow(lina,'gray');plt.title('before')
plt.subplot(222);plt.hist(lina.flatten(),255)
plt.show()
4.彩色图直方图均衡化
#彩色直方图均衡化
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("lina2.png",1)
cv2.imshow("src", img)
# 彩色图像均衡化,需要分解通道 对每一个通道均衡化
(b, g, r) = cv2.split(img)
bH = cv2.equalizeHist(b)
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
# 合并每一个通道
result = cv2.merge((bH, gH, rH))
cv2.imshow("dst", result)
cv2.waitKey(0)
颜色发生畸变
采用以下方式
import numpy as np
import cv2
def hisEqulColor(img):
ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
channels = cv2.split(ycrcb)
print (len(channels))
cv2.equalizeHist(channels[0], channels[0])
cv2.merge(channels, ycrcb)
cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR, img)
return img
im = cv2.imread('lina2.png')
cv2.imshow('im1', im)
cv2.waitKey(0)
eq = hisEqulColor(im)
cv2.imshow('image2',eq )
cv2.waitKey(0)
cv2.imwrite('lena2.jpg',eq)
5.YUV 直方图均衡化
import cv2
import numpy as np
img = cv2.imread("lina2.png", 1)
imgYUV = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
cv2.imshow("src", img)
channelsYUV = cv2.split(imgYUV)
channelsYUV[0] = cv2.equalizeHist(channelsYUV[0])
channels = cv2.merge(channelsYUV)
result = cv2.cvtColor(channels, cv2.COLOR_YCrCb2BGR)
cv2.imshow("dst", result)
cv2.waitKey(0)