OpenCV之图像直方图
1. 图像直方图
图像直方图是指对图像的像素点进行统计,计算各个像素值的频数并通过直方图的方式呈现出来的统计手段,将图像中像素值的分布情况可视化,直方图的统计在OpenCV中只需要调用一个API——calcHist(),直方图展示需要用到matplotlib,具体如下:
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
path = "C:\\Users\\27914\\Desktop\\images\\test2.jpg"
image = cv.imread(path)
colors = ("blue","green","red")
cv.imshow("image",image)
for i in range(3):
hist = cv.calcHist([image],[i],None,[256],[0,256])
plt.plot(hist,color = colors[i])
plt.xlim((0,256))
plt.show()
cv.waitKey(0)
cv.destroyAllWindows()
参数解释:images是传入的图像数据的列表,所以无论数量多少均要以列表的形式传入
channels是要计算的通道数构成的列表,也需要以列表的形式传入,mask为掩码,一般值为None,表示处理整张图像,也可自定义处理的图像范围,histsize是直方图要分成多少份,ranges是取值范围(左闭右开),最后两个为可选参数,hist为返回的值赋给谁,accumulate为布尔值,表示直方图是否要叠加。
上面例子的输出:
原图:
直方图:
可以看到在每个通道中都有一个波峰(有时可能会有多个),我们可以根据波峰的位置进行图像处理,比如图像的二值化处理,图像分割等
2. 图像直方图均衡化
对图像进行直方图均衡化处理,即是将图像像数值的分布更加均衡,但保留基本的图像信息,这样的操作可以使降低高噪声但会增强低噪声。OpenCV只支持对灰度图像进行直方图均衡化,故必须对图像进行色彩空间转换,直方图均衡化也比较简单,call一下API即可,
具体如下:
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
path = "C:\\Users\\27914\\Desktop\\images\\test2.jpg"
image = cv.imread(path,cv.IMREAD_GRAYSCALE)#必须为灰度图像
dst = cv.equalizeHist(image)
cv.imshow("image",image)
cv.imshow("result",dst)
hist1 = cv.calcHist([image],[0],None,[256],[0,256])
hist2 = cv.calcHist([dst],[0],None,[256],[0,256])
plt.plot(hist1,color = "red")
plt.plot(hist2,color = "blue")
plt.xlim((0,256))
plt.show()
cv.waitKey(0)
cv.destroyAllWindows()
直方图均衡化只需要将要处理的图像传入equalizeHist()即可,直方图均衡化对图像的影响如下:
原图:
均衡化后:
两者直方图对比(红色为原图,蓝色为处理后的图像)
直方图均衡化适用于图像有用信息与其他信息对比度较大的情况下,如果在某些区域对比度不高,均衡化后使图像的细节受到损害,因此可以采取局部的均衡化处理。
3. 二维的直方图
二维的图像直方图是指对两个通道的像素值的分布进行统计,实际上在运用时是对HSV色彩空间的图像求二维的直方图,因为在HSV色彩空间中只有H和S通道与色彩相关,同时统计两个通道可以对图像的颜色分布有进一步的信息提取,具体如下:
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
path = "C:\\Users\\27914\\Desktop\\images\\test2.jpg"
image = cv.imread(path)
hsv = cv.cvtColor(image,cv.COLOR_BGR2HSV)
hist = cv.calcHist([hsv],[0,1],None,[48,48],[0,180,0,256])
dst = cv.resize(hist,(400,400))
cv.normalize(dst,dst,0,255,cv.NORM_MINMAX)
dst = cv.applyColorMap(np.uint8(dst),cv.COLORMAP_JET)
cv.imshow("hist",dst)
plt.imshow(dst,interpolation="nearest")
plt.title("hist")
plt.show()
cv.waitKey(0)
cv.destroyAllWindows()
输出:
虽然名字叫二维的直方图,但是个人认为所得出的直方图应该是三维的,所统计的是不同颜色的不同深度在图像中的分布情况,其样式类似与热度图,可以在直方图中直截了当地看出图像中最重要的颜色是哪一种,依此可以进行图像的跟踪监测等操作
- 点赞
- 收藏
- 关注作者
评论(0)