导读
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)
灰度直方图是灰度级的函数,描述的是图像中具有该灰度级的像元的个数。
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()
结果:
- [ ] 2、直方图均衡化
直方图表达出图像明暗比,直方图均衡化能够调节图像的对比度,让图像视觉效果更好。
接下来我们需要做出下面这图这效果。
首先搞一张低对比度的图:
opencv使用 equalizeHist_img = cv.equalizeHist(gray_img) 进行图像直方图均衡化
转化后的图形:
两者的直方图对比:
经过图像直方图均衡化后,图像对比度明显增强,直方图的区域也分散开了。
代码
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()
一共这么几种度量方式:
实验用的图的结果:
HISTCMP_CORREL -0.003136853862261312 HISTCMP_CHISQR 49340294.64136557 HISTCMP_INTERSECT 57006.0 HISTCMP_BHATTACHARYYA 0.9067574525038417
官网解释: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图是这个:
下面我采用不同的ROI去计算反向投影:
画出由H和S的histogram的图。下面这图是ROI卡车那个图和我们target图的。
下图是第一个小狗ROI和target的:
差不多就可以得出结论:
从ROI的H和S,那种色调和饱和度给人的感觉,去找到target的相似的区域显示出来。
这个东西很鸡肋,不能用于识别啥,玩一下就行了。
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!