1.直方图均衡化
直方图均衡化是利用图像直方图对对比度进行调整的方法,这种方法对于背景和前景都太亮或者太暗的图像非常有用。
通俗来讲,就是一张图像中某一个像素点会特别集中,这时候我们可以通过直方图均衡化来将其分布得更均匀,从而得到图像更加清晰的目的。(个人理解,如有错误,欢迎大家来指正)
直方图均衡化的代码有两种,第一种是直接均衡化,代码如下:
def equalHist_demo(image): # 直方图均衡化
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
dst = cv.equalizeHist(gray)
cv.imshow("equalHist_demo", dst)
其中主要用到equalizeHist这个API,其参数很简单,第一个是原图像,第二个是目标图像,效果为:
原图:
均衡化后:
可以明显地看出,图像的对比度变强了。
第二种便是局部均衡化,局部直方图均衡化主要是为了解决全局直方图均衡化中一些地方对比度过强的问题,代码如下:
def clahe_demo(image): # 局部直方图均衡化
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
"""
clipLimit颜色对比度的阈值, titleGridSize进行像素均衡化的网格大小,即在多少网格下进行直方图的均衡化操作
将图像划分为不重叠的8*8个区域
"""
dst = clahe.apply(gray) # 自适应直方图均衡化
cv.imshow("clahe_demo", dst)
局部均衡化后:
相比较于原图,对比度增强了一点。
2.直方图比较
直方图比较的应用有:
1.图像相似度比较
如果我们有两张图像,并且这两张图像的直方图一样,或者有极高的相似度,那么在一定程度上,我们可以认为这两幅图是一样的,这就是直方图比较的应用之一。
2.分析图像之间关系
两张图像的直方图反映了该图像像素的分布情况,可以利用图像的直方图,来分析两张图像的关系。
在直方图比较中,我们常用到的比较方法有:巴氏距离比较、相关性比较、卡方比较。
首先我们要读取两张图像,
src1 = cv.imread("D:/opencv3/image/linux.png")
src2 = cv.imread("D:/opencv3/image/windows10.png")
cv.imshow("image1", src1)
cv.imshow("image2", src2)
接着,我们就要进行直方图比较,
def create_rgb_hist(image): # 创建 RGB 三通道直方图(直方图矩阵)
h, w, c = image.shape
# 创建一个(16*16*16,1)的初始矩阵,作为直方图矩阵
# 16*16*16的意思为三通道每通道有16个bins
rgbHist = np.zeros([16 * 16 * 16, 1], np.float32)
bsize = 256 / 16
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]
# 人为构建直方图矩阵的索引,该索引是通过每一个像素点的三通道值进行构建
# 下降成16个bin,由256*256*256降维4096
index = np.int(b / bsize) * 16 * 16 + np.int(g / bsize) * 16 + np.int(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) # 创建第一幅图的rgb三通道直方图(直方图矩阵)
hist2 = create_rgb_hist(image2) # 创建第二幅图的rgb三通道直方图(直方图矩阵)
match1 = cv.compareHist(hist1, hist2, cv.HISTCMP_BHATTACHARYYA) # 巴氏距离比较
match2 = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL) # 相关性比较
match3 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR) # 卡方比较
print("巴氏距离: %s, 相关性: %s, 卡方: %s"%(match1, match2, match3))
两张原图为:
而经过比较后得到的值为:
我们用肉眼可以看出两张图像并不相似,因此我们可以用两张比较相似的图来比较看看效果,
新的两张图为:
经过比较后的结果为:
可以看出使用巴氏距离比较法时,数值越接近于0表示两图像越相似,
使用相关性比较法时,数值越接近于1表示两图像越相似,
使用卡方比较法时,数值越小表示两图像越相似。
完整代码
import cv2 as cv # 导入opencv模块
import numpy as np # 导入数学函数库
def equalHist_demo(image): # 直方图均衡化
"""
广泛应用于图像增强处理中,直方图均衡化就是用一定的算法使直方图大致平和的方法
简而言之,直方图均衡化是通过拉伸像素强度分布范围来增强图像对比度的一种方法
"""
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
dst = cv.equalizeHist(gray)
cv.imshow("equalHist_demo", dst)
def clahe_demo(image): # 局部直方图均衡化
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
"""
clipLimit颜色对比度的阈值, titleGridSize进行像素均衡化的网格大小,即在多少网格下进行直方图的均衡化操作
将图像划分为不重叠的8*8个区域
"""
dst = clahe.apply(gray) # 自适应直方图均衡化
cv.imshow("clahe_demo", dst)
def create_rgb_hist(image): # 创建 RGB 三通道直方图(直方图矩阵)
h, w, c = image.shape
# 创建一个(16*16*16,1)的初始矩阵,作为直方图矩阵
# 16*16*16的意思为三通道每通道有16个bins
rgbHist = np.zeros([16 * 16 * 16, 1], np.float32)
bsize = 256 / 16
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]
# 人为构建直方图矩阵的索引,该索引是通过每一个像素点的三通道值进行构建
# 下降成16个bin,由256*256*256降维4096
index = np.int(b / bsize) * 16 * 16 + np.int(g / bsize) * 16 + np.int(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) # 创建第一幅图的rgb三通道直方图(直方图矩阵)
hist2 = create_rgb_hist(image2) # 创建第二幅图的rgb三通道直方图(直方图矩阵)
match1 = cv.compareHist(hist1, hist2, cv.HISTCMP_BHATTACHARYYA) # 巴氏距离比较
match2 = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL) # 相关性比较
match3 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR) # 卡方比较
print("巴氏距离: %s, 相关性: %s, 卡方: %s"%(match1, match2, match3))
print("------------hello python!------------")
# src = cv.imread("D:/opencv3/image/rice.png")
# cv.namedWindow("input_image", cv.WINDOW_AUTOSIZE)
# cv.imshow("input_image", src)
# equalHist_demo(src)
# clahe_demo(src)
src1 = cv.imread("D:/opencv3/image/lena.png")
src2 = cv.imread("D:/opencv3/image/lenanoise.png")
# src1 = cv.imread("D:/opencv3/image/linux.png")
# src2 = cv.imread("D:/opencv3/image/windows10.png")
cv.imshow("image1", src1)
cv.imshow("image2", src2)
hist_compare(src1, src2)
cv.waitKey(0)
cv.destroyAllWindows() # 释放所有窗口