(一)图像直方图
要画直方图必须要安装matplotlib库,Matplotlib 是一个 Python 的 2D绘图库。
图像直方图是反映一个图像像素分布的统计表,其横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的。纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比。图像是由像素构成,因为反映像素分布的直方图往往可以作为图像一个很重要的特征。直方图的显示方式是左暗又亮,左边用于描述图像的暗度,右边用于描述图像的亮度
python代码
import cv2
from matplotlib import pyplot as plt
def plot_demo(image):
# numpy的ravel函数功能是将多维数组降为一维数组
plt.hist(image.ravel(), 256, [0, 256])
plt.show("直方图")
def image_hist_demo(image):
color = {"blue", "green", "red"}
# enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据下标和数据,一般用在 for 循环当中。
for i, color in enumerate(color):
hist = cv2.calcHist([image], [i], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.xlim([0, 256])
plt.show()
if __name__ == "__main__":
img = cv2.imread("img6.jpg")
cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE)
cv2.imshow("input image", img)
plot_demo(img)
image_hist_demo(img)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
(二)直方图应用
直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法,是图像增强的一个手段
python代码
import cv2
__author__ = "boboa"
# 全局直方图均衡化
def equal_hist_demo(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
dst = cv2.equalizeHist(gray)
cv2.imshow("equal_hist_demo", dst)
# 局部直方图均衡化
def clahe_demo(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGRA2GRAY)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
dst = clahe.apply(gray)
cv2.imshow("clahe_demo", dst)
if __name__ == "__main__":
img = cv2.imread("img7.jpg")
cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE)
cv2.imshow("input image", img)
equal_hist_demo(img)
clahe_demo(img)
cv2.waitKey(0)
cv2.destroyAllWindows()
全局直方图均衡化运行结果:
局部直方图均衡化运行结果:
直方图比较:对输入的两张图像进行直方图均衡化及直方图计算步骤后,可以对两个图像的直方图进行对比,并通过对比的结果得到一些我们想要的结论。
python代码
import cv2
import numpy as np
__author__ = "boboa"
def create_rgb_hist(image):
h, w, c = image.shape
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]
index = (b/bsize)*16*16 + (g/bsize)*16 + (r/bsize)
rgbHist[(index), 0] = rgbHist[(index), 0]+1
return rgbHist
def hist_compare(image1, image2):
hist1 = create_rgb_hist(image1)
hist2 = create_rgb_hist(image2)
match1 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_BHATTACHARYYA)
match2 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
match3 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CHISQR)
# 巴氏距离越小越相似,相关性越大越相似,卡方越大越不相似
print("巴氏距离", match1)
print("相关性", match2)
print("卡方", match3)
if __name__ == "__main__":
img1 = cv2.imread("img5.jpg")
img2 = cv2.imread("img6.jpg")
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
hist_compare(img1, img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果
(三)直方图反向投影
根据样本的直方图,找到图像与样本相似的地方,即反向投影技术。Opencv中文网站这样说:所谓反向投影就是首先计算某一特征的直方图模型,然后使用模型去寻找图像中存在的该特征。
python代码
import cv2
from matplotlib import pyplot as plt
__author__ = "boboa"
def hist2d_demo(image):
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
hist = cv2.calcHist([image], [0, 1], None, [180, 256], [0, 180, 0, 256])
cv2.imshow("hist2d", hist)
plt.imshow(hist, interpolation="nearest")
plt.title("2d histogram")
plt.show()
def back_projection_demo(): # 直方图反向投影
sample = cv2.imread("sample.jpg")
target = cv2.imread("target.jpg")
roi_hsv = cv2.cvtColor(sample, cv2.COLOR_BGR2HSV)
target_hsv = cv2.cvtColor(target, cv2.COLOR_BGR2HSV)
cv2.imshow("sample", sample)
cv2.imshow("target", target)
roihist = cv2.calcHist([roi_hsv], [0, 1], None, [32, 32], [0, 180, 0, 256])
cv2.normalize(roihist, roihist, 0, 255, cv2.NORM_MINMAX) # 归一化
dst = cv2.calcBackProject(target_hsv, [0, 1], roihist, [0, 180, 0, 256], 1)
cv2.imshow("backproject", dst)
if __name__ == "__main__":
img = cv2.imread("target.jpg")
# cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE)
# cv2.imshow("input image", img)
# hist2d_demo(img)
back_projection_demo()
cv2.waitKey(0)
cv2.destroyAllWindows()
反向投影用于在输入图像(通常较大)中查找特定图像(通常较小或者仅1个像素,以下将其称为模板图像)最匹配的点或者区域,也就是定位模板图像出现在输入图像的位置。