灰度直方图是灰度级的函数,描述的是图像中具有该灰度级的像素的个数:横坐标是灰度级,纵坐标是该灰度出现的频率.
当一副图像被压缩为直方图后,所有的空间信息都丢失了.如果图像由两个不连续的区域组成,并且每个区域的直方图已知,则整幅图像的直方图是该两个区域的直方图之和.
边界阈值选择
直方图有一个应用就是它可以确定图像二值化的阈值。
假定一幅图像背景是浅色的,其中有一个深色物体.物体的深色像素产生了直方图的左峰,背景产生了右峰.物体边界附近具有两个峰值之间灰度级的像素数目相对较少,从而产生了两峰之间的谷.选择谷作为灰度阈值将得到合理的物体的边界.
灰度图绘制:
def plt_hist(img):
plt.hist(img.ravel(), 256, [0, 256])
plt.show()
三色折线图代码:
def img_hist(img):
color = ("blue", "green", "red")
for i, color in enumerate(color):
hist = cv.calcHist([img], [i], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.xlim([0, 25])
plt.show()
全局二值化:
def threshold_binary(src):
#把BGR图像转化成灰度图像
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
#获得灰度直方图以便调整算法的使用
plt.hist(src.ravel(), 256, [0, 256])
plt.show()
#几种二值化方法
ret, binary = cv.threshold(gray, 50, 255, cv.THRESH_BINARY)#指定阈值50
print("二值阈值: %s" % ret)
cv.imshow("threshold_binary", binary)
ret_otsu, binary_otsu = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
print("二值阈值_otsu: %s" %ret_otsu)
cv.imshow("threshold_binary_otsu", binary_otsu)
ret_tri, binary_tri = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE)
print("二值阈值_tri: %s" % ret_tri)
参考博客