文章目录
- 绘制直方图
- 1.矩阵扁平化
- 2.plt.hist()
- 3.绘制原图的等高线
- 4.彩色图片直方图
- 直方图均衡化
- 1.np.histogram()
- 2.均衡化
- 3.调用cv2.equalizeHist()
- 4.彩色图直方图均衡化
绘制直方图
1 2 3 4 5 6 | 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列
1 | b=im.flatten() |
2.plt.hist()
bins是柱子的数目
其他具体参数:
https://www.cnblogs.com/denny402/p/5096790.html
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
没有归一化的
1 2 3 4 5 6 | 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>) |
归一化的:
1 | n, bins, patches = plt.hist(im.flatten(), bins=255, density=1) |
看看返回值是什么:
n: 直方图向量,是否归一化由参数设定,就是每个柱子高度
bins: 返回各个bin的区间范围
patches: 返回每个bin里面包含的数据,是一个list(n和bins两个返回值的合并)
3.绘制原图的等高线
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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.彩色图片直方图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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类似
1 | imhist, bins = np.histogram(im, 255, density=True) |
矩阵不用flatten()了,得到的结果imhist与上述plt.hist的返回值n是一样的
2.均衡化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | -*- 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()只提供灰度值图片的处理
1 2 3 4 5 6 7 8 9 10 11 12 | 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.彩色图直方图均衡化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #彩色直方图均衡化 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) |
颜色发生畸变
采用以下方式
https://www.jianshu.com/p/9a9000d226b6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 直方图均衡化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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) |