1-threshold(全局阈值法)
全局阈值法对于某些光照不均的图像,这种全局阈值分割的方法会显得苍白无力。
对图像中的像素进行阈值处理,进行分割,常用于二值化处理。可以把阈值化操作理解成一个用1X1的核进行卷积(比较),对每一个箱数进行非线性操作:
double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)
- src 原始数组 (单通道 , 8-bit of 32-bit 浮点数).
- dst 输出数组,必须与 src 的类型一致,或者为8-bit.
- thresh 阈值
- max_value 使用 THRESH_BINARY 和 THRESH_BINARY_INV 的最大值.
- threshold_type 阈值类型
2-OTSU算法(最大类间方差法,对于多峰值图像效果明显)
大津法(OTSU)是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出。从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景图像的类间方差最大。
它被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响,因此在数字图像处理上得到了广泛的应用。它是按图像的灰度特性,将图像分成背景和前景两部分。因方差是灰度分布均匀性的一种度量,背景和前景之间的类间方差越大,说明构成图像的两部分的差别越大,当部分前景错分为背景或部分背景错分为前景都会导致两部分差别变小。因此,使类间方差最大的分割意味着错分概率最小。
应用:是求图像全局阈值的最佳方法,应用不言而喻,适用于大部分需要求图像全局阈值的场合。
优点:计算简单快速,不受图像亮度和对比度的影响。
3-THRESH_TRIANGLE(三角法,最适用于单个波峰,最开始用于医学分割细胞等)
三角法求阈值最早见于Zack的论文《Automatic measurement of sister chromatid exchange frequency》主要是用于染色体的研究,该方法是使用直方图数据,基于纯几何方法来寻找最佳阈值,它的成立条件是假设直方图最大波峰在靠近最亮的一侧,然后通过三角形求得最大直线距离,根据最大直线距离对应的直方图灰度等级即为分割阈值,图示如下:
对上图的详细解释:
在直方图上从最高峰处bmx到最暗对应直方图bmin(p=0)%构造一条直线,从bmin处开始计算每个对应的直方图b到直线的垂直距离,知道bmax为止,其中最大距离对应的直方图位置即为图像二值化对应的阈值T。
扩展情况:
有时候最大波峰对应位置不在直方图最亮一侧,而在暗的一侧,这样就需要翻转直方图,翻转之后求得值,用255减去即得到为阈值T。扩展情况的直方图表示如下:
4-adaptiveThreshold(局部阈值法)
前面介绍了OTSU算法和最大熵算法,但这两种算法都属于全局阈值法,所以对于某些光照不均的图像,这种全局阈值分割的方法会显得苍白无力,如下图:
这种办法就是自适应阈值法(adaptiveThreshold),它的思想不是计算全局图像的阈值,而是根据图像不同区域亮度分布,计算其局部阈值,所以对于图像不同区域,能够自适应计算不同的阈值,因此被称为自适应阈值法。(其实就是局部阈值法)
如何确定局部阈值呢?可以计算某个邻域(局部)的均值、中值、高斯加权平均(高斯滤波)来确定阈值。值得说明的是:如果用局部的均值作为局部的阈值。
void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue,
int adaptiveMethod, int thresholdType, int blockSize, double C)
说明下各参数:
InputArray src:源图像
OutputArray dst:输出图像,与源图像大小一致
int adaptiveMethod:在一个邻域内计算阈值所采用的算法,有两个取值,分别为 ADAPTIVE_THRESH_MEAN_C 和 ADAPTIVE_THRESH_GAUSSIAN_C 。
ADAPTIVE_THRESH_MEAN_C的计算方法是计算出领域的平均值再减去第七个参数double C的值。
ADAPTIVE_THRESH_GAUSSIAN_C的计算方法是计算出领域的高斯均值再减去第七个参数double C的值。
int thresholdType:这是阈值类型,只有两个取值,分别为 THRESH_BINARY 和THRESH_BINARY_INV 具体的请看官方的说明,这里不多做解释。
int blockSize:adaptiveThreshold的计算单位是像素的邻域块,这是局部邻域大小,3、5、7等。
double C:这个参数实际上是一个偏移值调整量,用均值和高斯计算阈值后,再减或加这个值就是最终阈值。
5-示例代码
// opencv-44.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("right06.jpg");
if (src.empty()) {
return -1;
}
cout << src.channels() << endl;
/* namedWindow("src image", WINDOW_NORMAL);
namedWindow("threshhold", WINDOW_NORMAL);
namedWindow("adaptiveThreshold", WINDOW_NORMAL);*/
imshow("src image", src);
Mat grayImage;
cvtColor(src, grayImage, COLOR_BGR2GRAY);
//1-
Mat th;
threshold(grayImage, th, 100, 255, THRESH_BINARY );
imshow("threshhold", th);
//2-
Mat thOTSU;
threshold(grayImage, thOTSU, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("threshhold OTSU", thOTSU);
//3-
Mat ath;
adaptiveThreshold(grayImage, ath, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 51, 0);
imshow("adaptiveThreshold", ath);
waitKey(0);
return 0;
}