OpenCV python 图像直方图均衡化 calcBackProject反向投影

导读
1 直方图介绍
2 图像直方图均衡化
3 比较不同图像的直方图的相似度
4 直方图反向投影

- [ ] 1、直方图介绍

opencv采用hist = cv.calcHist([image], [i], None, [256], [0, 256])计算直方图
def calcHist(images, channels, mask, histSize, ranges, hist=None, accumulate=None)

灰度直方图是灰度级的函数,描述的是图像中具有该灰度级的像元的个数。

OpenCV python 图像直方图均衡化 calcBackProject反向投影_第1张图片

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 将传入图像变成灰度图
# 对于每一级别的灰度,0到255
# 统计图里占有多少像素点
# 比如灰度14占有123个像素点
# 返回np矩阵,表示0到255灰度占有的像素点个数
def custom_hist(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    h, w = gray.shape
    hist = np.zeros([256], dtype=np.int32)
    for row in range(h):
        for col in range(w):
            pv = gray[row, col]
            hist[pv] += 1
    return np.array(hist)

# 将传入图像变成灰度图
# 调用cv.calcHist方法计算,和第一个函数一样的结果
def image_Cvt_and_Gray_hist(image):
    gray_img = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    hist = cv.calcHist([gray_img], [0], None, [256], [0, 256])
    return np.array(hist)

# 将传入图像的三个通道调用cv.calcHist方法分别计算直方图
# 返回三个通道的直方图信息
def image_hist(image):
    color = ('blue', 'green', 'red')
    all_hist=[]
    for i, color in enumerate(color):
        hist = cv.calcHist([image], [i], None, [256], [0, 256])
        all_hist.append(hist)
    return np.array(all_hist)


# 读取图像
src = cv.imread("D:/vcprojects/images/flower.png")

# 调用三个不一样的函数得到直方图
hist1=custom_hist(src)
hist2=image_Cvt_and_Gray_hist(src)
hist3=image_hist(src)

# 改变shape 使得好画图用
# hist2=hist2.reshape((256,))
hist2=hist2.flatten()
hist3=hist3.reshape((3,256,))
print(hist1.shape)
print(hist2.shape)
print(hist3[0].shape)

# 画图
plt.subplot(231)
plt.bar(range(256),hist1)
plt.title("self gray hist")

plt.subplot(232)
plt.bar(range(256),hist2)
plt.title("opencv gray calc")

plt.subplot(233)
plt.plot(range(256),hist2)
plt.title("opencv gray calc plot")

plt.subplot(234)
plt.plot(range(256),hist3[0],'b')
plt.title("opencv blue ch plot")
plt.subplot(235)
plt.plot(range(256),hist3[1],'g')
plt.title("opencv green ch plot")
plt.subplot(236)
plt.plot(range(256),hist3[2],'r')
plt.title("opencv red ch plot")
plt.show()

结果:
OpenCV python 图像直方图均衡化 calcBackProject反向投影_第2张图片

- [ ] 2、直方图均衡化
直方图表达出图像明暗比,直方图均衡化能够调节图像的对比度,让图像视觉效果更好。
接下来我们需要做出下面这图这效果。
OpenCV python 图像直方图均衡化 calcBackProject反向投影_第3张图片

首先搞一张低对比度的图:
OpenCV python 图像直方图均衡化 calcBackProject反向投影_第4张图片

opencv使用 equalizeHist_img = cv.equalizeHist(gray_img) 进行图像直方图均衡化

转化后的图形:
OpenCV python 图像直方图均衡化 calcBackProject反向投影_第5张图片
两者的直方图对比:
OpenCV python 图像直方图均衡化 calcBackProject反向投影_第6张图片
经过图像直方图均衡化后,图像对比度明显增强,直方图的区域也分散开了。

代码

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt



# 调用cv.calcHist方法计算,和第一个函数一样的结果
def Gray_hist(image):
    hist = cv.calcHist([image], [0], None, [256], [0, 256])
    return np.array(hist)


# 读取图像
src = cv.imread("test1.jpg")
gray_img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
cv.imshow("gray_img",gray_img)

# 画出原图的灰度图的直方图
hist1=Gray_hist(gray_img)
hist1=hist1.flatten()
plt.subplot(211)
plt.bar(range(256),hist1)
plt.title("gray_img hist")


equalizeHist_img = cv.equalizeHist(gray_img)
cv.imshow("equalizeHist_img",equalizeHist_img)
cv.imwrite("test2.jpg",equalizeHist_img)
hist2=Gray_hist(equalizeHist_img)
hist2=hist2.flatten()
plt.subplot(212)
plt.bar(range(256),hist2)
plt.title("equalizeHist_img hist")


duibi1 = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL)
print("HISTCMP_CORREL",duibi1)
duibi1 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR)
print("HISTCMP_CHISQR",duibi1)
duibi1 = cv.compareHist(hist1, hist2, cv.HISTCMP_INTERSECT)
print("HISTCMP_INTERSECT",duibi1)
duibi1 = cv.compareHist(hist1, hist2, cv.HISTCMP_BHATTACHARYYA)
print("HISTCMP_BHATTACHARYYA",duibi1)


plt.show()
cv.waitKey(0)
cv.destroyAllWindows()


  • 3、比较不同图像的直方图的相似度

官网介绍:https://docs.opencv.org/2.4/modules/imgproc/doc/histograms.html?highlight=cv.comparehist#cv.CompareHist

一共这么几种度量方式:

OpenCV python 图像直方图均衡化 calcBackProject反向投影_第7张图片
OpenCV python 图像直方图均衡化 calcBackProject反向投影_第8张图片

实验用的图的结果:

HISTCMP_CORREL -0.003136853862261312
HISTCMP_CHISQR 49340294.64136557
HISTCMP_INTERSECT 57006.0
HISTCMP_BHATTACHARYYA 0.9067574525038417
  • 4、直方图方向投影
    官网解释:https://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/back_projection/back_projection.html

通俗理解:
我有一个ROI图,这图的HSV中的色调(H),饱和度(S)我比较感兴趣,HSV是针对人的视觉效果来设计的,求出这个ROI的H和S的histogram分布。
我现在有另一张图target,我使用得到的histogram分布去搞这个图,target图里面每个像素点的H和S我都依照得到的histogram分布去改变,改变得最后结果是:有相似H和S的部分会被“显形”(针对人眼视觉),target图中不是一个风格的就不会“显形”。

如果我的target图是这个:
OpenCV python 图像直方图均衡化 calcBackProject反向投影_第9张图片

下面我采用不同的ROI去计算反向投影:
OpenCV python 图像直方图均衡化 calcBackProject反向投影_第10张图片
OpenCV python 图像直方图均衡化 calcBackProject反向投影_第11张图片
画出由H和S的histogram的图。下面这图是ROI卡车那个图和我们target图的。
OpenCV python 图像直方图均衡化 calcBackProject反向投影_第12张图片

下图是第一个小狗ROI和target的:
OpenCV python 图像直方图均衡化 calcBackProject反向投影_第13张图片

差不多就可以得出结论:
从ROI的H和S,那种色调和饱和度给人的感觉,去找到target的相似的区域显示出来。
这个东西很鸡肋,不能用于识别啥,玩一下就行了。

你可能感兴趣的:(OpenCV,opencv,图像直方图,均衡化)