学习视频可参见python+opencv3.3视频教学 基础入门
outline
图像直方图定义
def plot_demo(image):
#image.ravel()将numpy数组扁平化为一维数组,会改变原数组
#flatten()也是扁平化成一维数组,但是不会改变原数组
plt.hist(image.ravel(),256,[0,256]) # 256为bins数量,[0, 256]为范围,即灰度范围
plt.show()
希望一幅图像的像素占有全部可能的灰度级且分布均匀,能够具有 高对比度;
基本思想是把原始图的直方图变换为均匀分布的形式,这样就增加 了像素灰度值的动态范围,从而达到增强图像整体对比度的效果
直方图均衡化的前提条件是图像是灰度图
全局直方图均衡化
局部自适应直方图均衡化
巴氏距离
相关性
卡方
测试用例:
def create_rgb_hist(image):
h, w, c = image.shape
rgbhist=np.zeros([16*16*16,1],np.float32) #rgb三通道的数值压缩到一通道
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]
index = 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=cv.compareHist(hist1,hist2,method=cv.HISTCMP_BHATTACHARYYA)
#相关性
match2 = cv.compareHist(hist1, hist2, method=cv.HISTCMP_CORREL)
#卡方
match3 = cv.compareHist(hist1, hist2, method=cv.HISTCMP_CHISQR)
print("巴式距离:%s, 相关性:%s, 卡方:%s" % (match1, match2, match3))
测试结果:
巴式距离:0.9928062493065918, 相关性:-0.00022964846595475527, 卡方:76225.92207299198
反向投影就是首先计算某一特征的直方图模型,然后使用模型去寻找图像中存在的特征。反向投影在某一位置的值就是原图对应位置像素值在原图像中的总数目。
反向投影原理
2d直方图显示测试用例
def hist2d_demo(image):
hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
hist = cv.calcHist([image], [0, 1], None, [180, 360], [0, 180, 0, 256]) # 计算直方图
print(hist.shape)
# cv.imshow("hist2d_demo", hist)
plt.imshow(hist, interpolation="nearest") # 直方图显示
plt.title("2D Histogram")
plt.show()
直方图反向投影测试用例
def back_projection_demo():
"""
反向投影可以用来做图像分割,或者在图像中找寻我们感兴趣的部分。
它会输出与输入图像(待搜索)同样大小的图像,其中的每一个像素值代表了输入图像上对应点属于目标对象的概率。
输出图像中像素值越高(越白)的点就越可能代表我们要搜索的目标 (在输入图像所在的位置)。
直方图投影经常与camshift 算法等一起使用。
步骤:
1. 准备一张包含我们要查找目标的图像创建直方图。最好使用颜色直方图,因为一个物体的颜色要比它的灰度能更好的被用来进行图像分割与对象识别。
2. 把这个颜色直方图投影到输入图像中寻找我们的目标,
3. 设置适当的阈值对概率图像进行二值化
"""
sample = cv.imread("./images/huang.png")
target = cv.imread("./images/lena.jpg")
roi_hsv = cv.cvtColor(sample, cv.COLOR_BGR2HSV)
target_hsv = cv.cvtColor(target, cv.COLOR_BGR2HSV)
cv.imshow("sample", sample)
cv.imshow("target", target)
roiHist = cv.calcHist([roi_hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
# 归一化:原始图像,结果图像,映射到结果图像中的最小值,最大值,归一化类型
# cv.NORM_MINMAX对数组的所有值进行转化,使它们线性映射到最小值和最大值之间
cv.normalize(roiHist, roiHist, 0, 255, cv.NORM_MINMAX)
dst = cv.calcBackProject([target_hsv], [0, 1], roiHist, [0, 180, 0, 256], 1)
cv.imshow("backProjectionDemo", dst)