Python+OpenCV:全局直⽅图均衡化、局部直⽅图⾃适应均衡化、直⽅图⽐较
(Python版)
1. 全局直⽅图均衡化
cv2.equalizeHist(src, dst=None)函数只能处理单通道的数据,src为输⼊图像对象矩阵,必须为单通道的uint8类型的矩阵数据。直⽅图均衡化可以看作是图像增强的⼀个⼿段,⽰例代码如下:
import cv2 as cv
src = cv.imread("D:/Open CV/opencv/sources/samples/data/rice_01.jpg")
# 1. 全局直⽅图均衡化
def globalEqualHist(image):
# 如果想要对图⽚做均衡化,必须将图⽚转换为灰度图像
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
dst = cv.equalizeHist(gray)# 在说明⽂档中有相关的注释与例⼦
# equalizeHist(src, dst=None)函数只能处理单通道的数据,src为输⼊图像对象矩阵,必须为单通道的uint8类型的矩阵数据
# dst: 输出图像矩阵(src的shape⼀样)
cv.imshow("global equalizeHist", dst)
# print(len(image.shape))  # 彩⾊图像的shape长度为3
# print(len(gray.shape))  # 灰度图像的shape长度为2
# print(gray.shape)  # 灰度图像只有⾼、宽
globalEqualHist(src)
cv.imshow("original image", src)
cv.waitKey(0)
cv.destroyAllWindows()
运⾏效果如下:
由运⾏的效果图,我们可以看出经过equalizeHist()函数的处理,图像的对⽐度在全局上已经得到了增强。但是如果选择其他的图像,采⽤全局直⽅图均衡化的函数就不⼀定能够得到很好地效果了,例如,选择⼀张帅哥的图像做全局直⽅图均衡化处理:
import cv2 as cv
import numpy as np
src = cv.imread("./images/handsomeboy01.jpg")
# 1. 全局直⽅图均衡化
def globalEqualHist(image):
# 如果想要对图⽚做均衡化,必须将图⽚转换为灰度图像
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
dst = cv.equalizeHist(gray)# 在说明⽂档中有相关的注释与例⼦
# dst: 输出图像矩阵(src的shape⼀样)
cv.imshow("global equalizeHist", dst)
globalEqualHist(src)
cv.imshow("original image", src)
cv.waitKey(0)
cv.destroyAllWindows()
运⾏效果如下:
很明显,这种情况下经过全局的均衡化处理之后反⽽不是我们想要得到的图像,因为它将图像的关键部分处理的相当不清楚。所以此时,就不能利⽤全局均衡化了,⽽需要使⽤局部直⽅图⾃适应均衡化。
2. 局部直⽅图⾃适应均衡化
相⽐全局直⽅图均衡化,⾃适应直⽅图均衡化将图像划分为不重叠的⼩块,在每⼀块进⾏直⽅图均衡化,如果⼩块内有噪声,则影响就会很⼤,需要通过限制对⽐度来进⾏抑制。即通过对⽐度⾃适应直⽅图均衡化。如果限制对⽐度的阈值设置为40,那么在图像中像素值出现次数⼤于40的次数就会将⼤于40的部分像素点去掉,平均成其它的像素点。
⽰例代码如下:
import cv2 as cv
import numpy as np
src = cv.imread("./images/handsomeboy01.jpg")
def localEqualHist(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
clahe = cv.createCLAHE(clipLimit=5, tileGridSize=(7,7))
dst = clahe.apply(gray)
局部直方图均衡化
cv.imshow("clahe image", dst)
globalEqualHist(src)
cv.imshow("original image", src)
cv.waitKey(0)
cv.destroyAllWindows()
此时如果选择我们刚才的那张帅哥的图⽚的话,就会出现以下效果:
此时的效果就⾮常的好了。
3. 直⽅图⽐较
直⽅图⽐较可以通过cv2中的API: cv2.HISTCMP_BHATTACHARYYA()计算两张图像的巴⽒距离;cv2.HISTCMP_CORREL()计算图像之间的相关性;cv2.HISTCMP_CHISQR()计算卡⽅。
# 直⽅图⽐较
def create_rgb_hist(image):
h, w, c = image.shape
rgbHist = np.zeros([16*16*16,1], np.float32)
bsize =256/16
# enumerate() 函数可以永健⼀个可遍历的数据对象(如列表、元组或字符串)组合为⼀个索引序列,同时列出数据以及对应的下标,⼀般⽤在for循环中。# range()函数⽤于创建⼀个整数列表
for row in range(h):
for col in range(w):
b = image[row, col,0]
g = image[row, col,1]
r = image[row, col,2]
index = np.int((b/bsize)/16*16+(g/bsize)*16+(r/bsize))
rgbHist[np.int(index),0]= rgbHist[np.int(index),0]+1
return rgbHist
def hist_compare(image1, image2):
hist1 = create_rgb_hist(image1)
hist2 = create_rgb_hist(image2)
match1 = cvpareHist(hist1, hist2, cv.HISTCMP_BHATTACHARYYA)
match2 = cvpareHist(hist1, hist2, cv.HISTCMP_CORREL)
match3 = cvpareHist(hist1, hist2, cv.HISTCMP_CHISQR)
print("巴⽒距离: %s, 相关性: %s, 卡⽅: %s"%(match1, match2, match3))
cv.imshow("image1", image1)
cv.imshow("image2", image2)
image1 = cv.imread("./images/raindropGirl.jpg")
image2 = cv.imread("./images/raindropGirl01.jpg")
hist_compare(image1, image2)
cv.waitKey(0)
cv.destroyAllWindows()
运⾏结果如下:
通过巴⽒距离就可以看出⼆者的相似度还是⾮常⼤的。巴⽒距离越⼩,代表图像越相似。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。