说明:文章将包含简短的理论介绍,重点还是在具体的实践部分
1.理论介绍
阈值化
Gauss最优阈值:
Gauss思想:
假设灰度直方图的概率分布模型可由两个不同的正态分布相加得到,那么两个正态分布的交点便为最优阈值点。
具体算法:
其中p(g)为灰度直方图,g为像素值。
(图片来源:http://blog.csdn.net/sky_in_my_mind/article/details/72730595)
OTSU大津算法:
思想:
是一种基于全局的二值化算法,它是根据图像的灰度特性,基于灰度直方图,将图像分为前景和背景两个部分,当取最佳阈值时,两部分之间的类间方差最大。
多光谱阈值化:
思想:
一种分割方法在每个谱段中(如R、G、B)独立地确定阈值,然后综合起来形成单一的分割图像。
2.具体的实践部分
使用OpenCV实现图像的阈值分割
具体的函数:
(1)cv2.threshold:全局阈值化,需要给定阈值
double threshold(
InputArray src, // 输入图像
OutputArray dst, // 输出图像
double thresh, // 阈值
double maxValue, // 向上最大值
int thresholdType // 阈值化操作的类型
);
二值化操作的类型,包含以下6种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV;
(补充)大津算法 cv2.THRESH_OTSU:输入任意阈值均无影响
#-*- coding: utf-8 -*-
"""
实现大津法
"""
import cv2
import time
img = cv2.imread("qipange.jpg", -1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
time0 = time.time()
retval, dst = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
time1 = time.time()
total = (time1 - time0)
print("otsu need time: ",total,"s")
cv2.imshow("src", img)
cv2.imshow("gray", gray)
cv2.imshow("dst", dst)
cv2.waitKey(0)
但是,这种方法由于是全局阈值,对于亮度分布差异较大的图像,常常无法找到一个合适的阈值。如下所示,对棋盘格进行二值化操作,由于图像右上角区域和图像下部的亮度差异较为大,无法找到一个合适的阈值,将棋盘上的所有棋盘格给区分开来。
因此,需要采用一种局部的自适应阈值化
(2)cv2.adaptiveThreshold:
局部自适应阈值二值化函数根据图片一小块区域的值来计算对应区域的阈值。支持两种自适应方法:平均和高斯。在两种情况下,自适应阈值T(x, y)通过计算每个像素周围bxb大小像素块的加权均值并减去常量C得到。其中,b由blockSize给出,大小必须为奇数;如果使用平均的方法,则所有像素周围的权值相同;如果使用高斯的方法,则(x,y)周围的像素的权值则根据其到中心点的距离通过高斯方程得到。
void adaptiveThreshold(
InputArray src, // 输入图像
OutputArray dst, // 输出图像
double maxValue, // 向上最大值
int adaptiveMethod, // 自适应方法,平均或高斯
int thresholdType, // 阈值化类型
int blockSize, // 块大小
double C // 常量
);
ADAPTIVE_THRESH_GAUSSIAN_C的计算方法是计算出领域的高斯均值再减去第七个参数double C的值
官方文档的参考代码:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('qipange.jpg',0)
img = cv2.medianBlur(img,5)
ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,11,2)
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY,11,2)
titles = ['Original Image', 'Global Thresholding (v = 127)',
'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]
for i in xrange(4):
plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
结果:
参考资料:
1.OpenCV官方教程:https://docs.opencv.org/3.2.0/d7/d4d/tutorial_py_thresholding.html
2.相关博客:http://blog.csdn.net/guduruyu/article/details/68059450
http://blog.csdn.net/sinat_21258931/article/details/61418681