目标
• 使用 OpenCV 或 Numpy 函数计算直方图
• 使用 Opencv 或者 Matplotlib 函数绘制直方图
• 将要学习的函数有:cv2.calcHist(),np.histogram()
作用:
通过直方图你可以对整幅图像的灰度分布有一个整体的 了解。直方图的 x 轴是灰度值(0 到 255),y 轴是图片中具有同一个灰度值的 点的数目。
BINS:把原来的 256 个值等分成 16 小组,取每组的 总和。而这里的每一个小组就被成为 BIN.
DIMS:表示我们收集数据的参数数目。在本例中,我们对收集到的数据 只考虑一件事:灰度值。所以这里就是 1。
RANGE:就是要统计的灰度值范围,一般来说为 [0,256],也就是说所 有的灰度值
第一种方法:plt.hist()
matplotlib.pyplot.hist(X,BINS) 能够绘制直方图,X是一维数据源,通常读入图片后需要用ravel函数将二维数组降为一维。
效果图
code
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
src = cv.imread("../../images/lena.jpg")
hsv = cv.cvtColor(src, cv.COLOR_BGR2HSV)
plt.hist(hsv.ravel(),256)
plt.show()
cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
cv.destroyAllWindows()
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
src = cv.imread("../../images/lena.jpg")
hsv = cv.cvtColor(src, cv.COLOR_BGR2HSV)
### 第二种方法
hist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
plt.imshow(hist, interpolation='nearest')
plt.show()
# cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
# cv.imshow('input image', src)
cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
cv.destroyAllWindows()
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
src = cv.imread("../../images/lena.jpg")
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv.calcHist([src],[i],None,[256],[0,256])
plt.plot(histr,color=col)
plt.xlim([0,256])
plt.show()
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow('input image', src)
cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
cv.destroyAllWindows()
掩膜是用选定的图像、图形或物体,对要处理的图像进行遮挡,来控制图像 处理的区域。
在数字图像处理中,我们通常使用二维矩阵数组进行掩膜。掩膜是由0和1组成一个二进制图像,利用该掩膜图像要处理的图像进行掩膜,其中1值的区域被处理,0 值区域被屏蔽,不会处理。
掩膜的主要用途是:
效果圖
注意,图像应为灰度图再进行绘制。图像直方图(Image Histogram)是用以表示数字图像中亮度分布的直方图。标绘了图像中每个亮度值的像素个数。这种直方图中,横坐标的左侧为较暗的区域,而右侧为较亮的区域。因此一张较暗图片的直方图中的数据多集中于左侧和中间部分,而整体明亮、只有少量阴影的图像则相反。
code
:
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
src = cv.imread("../../images/lena.jpg")
gray = cv.cvtColor(src,cv.COLOR_BGR2GRAY)#切记要转为灰度图
#create a mask
mask = np.zeros(gray.shape[:2],np.uint8)
mask[100:300,100:400] = 255#将部分mask设为255
masked_img = cv.bitwise_and(gray,gray,mask=mask)#这个标识的是将gray,与gray在mask的这部分上进行与操作,就可以得出那部分的图像
cv.imshow("masked_img",masked_img)
#将这两种直方图进行图形的显示
cal_fullHist = cv.calcHist([gray],[0],None,[256],[0,256])#channels: 如果输入图像是灰度图,它的值就是 [0];如果是彩色图像的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。
cal_maskHist = cv.calcHist([gray],[0],mask,[256],[0,256])#这里mask的大小,如果没有mask就直接设为None,有就直接设置就可以了
plt.subplot(221),plt.imshow(gray,"gray")#注意,前面三个的后面那个名字要是一样的,不然会出错。
plt.subplot(222),plt.imshow(mask,"gray")
plt.subplot(223),plt.imshow(masked_img,"gray")
plt.subplot(224),plt.plot(cal_fullHist),plt.plot(cal_maskHist)
plt.xlim([0,256])
plt.show()
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
cv.imshow('input image', src)
cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
cv.destroyAllWindows()
cv2.calcHist(images,channels,mask,histSize,ranges[,hist[,accumulate]])
- images: 原图像(图像格式为 uint8 或 float32)。当传入函数时应该 用中括号 [] 括起来,例如:[img]。
- channels: 同样需要用中括号括起来,它会告诉函数我们要统计那幅图 像的直方图。如果输入图像是灰度图,它的值就是 [0];如果是彩色图像 的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。
- mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。但是如 果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像,并 使用它。(后边有例子)
- histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。
- ranges: 像素值范围,通常为 [0,256]