一. 全局阈值分割
全局阈值分割指的是使用一个固定的阈值,大于这个阈值的设定为一个颜色,小于或者等于这个阈值的像素设定为另外一种颜色.
函数原型:
double threshold( InputArray src, OutputArray dst,
double thresh, double maxval, int type );
src:
要处理的图像,一般是灰度图像dst:
输出图像thres:
设定的阈值maxval:
灰度的最大值,一般为255,用来指明阈值分割中最大值的取值,主要指阈值二值化和反二值化中type:
阈值分割的方式
``
阈值分割案例
#include "MyOpencv.h"
int main(void)
{
Mat original = cv::imread("test_02.bmp", IMREAD_GRAYSCALE);
imshow("Original", original);
Mat dst;
// 阈值二值化
cv::threshold(original, dst, 127, 255, cv::THRESH_BINARY);
imshow("ThresBinary", dst);
// 阈值反二值化
cv::threshold(original, dst, 127, 255, cv::THRESH_BINARY_INV);
imshow("ThresBinaryInv", dst);
// 阈值截断
cv::threshold(original, dst, 127, 255, cv::THRESH_TRUNC);
imshow("ThresTrunc", dst);
// 阈值取零
cv::threshold(original, dst, 127, 255, cv::THRESH_TOZERO);
imshow("ThresToZero", dst);
// 阈值反取零
cv::threshold(original, dst, 127, 255, cv::THRESH_TOZERO_INV);
imshow("ThresToZeroInv", dst);
waitKey(0);
}
二. Otsu阈值分割(大律法)
① 大律法阈值分割的原理
对于图像I(x,y),前景(即目标)和背景的分割阈值记为T,属于前景的像素点数占整幅图像的比例记为w0,其平均灰度u0;背景像素点数占整幅图像的比例记为w1,其平均灰度记为u1.图像的总平均灰度记为u,类间方差记为g.假设图像的大小为M*N,图像中像素的灰度值小于阈值T的像素个数记为N0,像素灰度大于阈值T的像素个数记为N1,则有:
使用方式:
阈值分割的时候加上type里面加上标志: THRES_OTSU即可,最终进行阈值分割的阈值会返回
double T = cv::threshold(original, dst, 0, 255, cv::THRESH_OTSU);
cout << "大律法进行阈值分割的阈值: " << T << endl;
imshow("OtsuThresBinary", dst);
结果:
三. 自适应阈值(局部阈值)
① 自适应阈值分割的原理
在自适应阈值处理中,平滑算子的尺寸决定了分割出来的物体的尺寸,如果滤波器尺寸太小,那么估计出的局部阈值将不理想.凭经验,平滑算子的宽度必须大于被识别物理题的宽度,窗口的尺寸越大,平滑后结果越能更好地作为每个像素的阈值参考,也不能无限大.
假设输入的图像为I,宽度为W,高度为H,自适应阈值分割的步骤如下:
- 对图像进行平滑处理,平滑结果为f(I),其中平滑可以是均值平滑,高斯平滑
- 自适应阈值矩阵 Thresh = (1-ratio) * f(I), 一般令 ratio = 0.15
- 利用局部阈值分割规则
② 自适应阈值分割的函数原型
void cv::adaptiveThreshold ( InputArray src,
OutputArray dst,
double maxValue,
int adaptiveMethod,
int thresholdType,
int blockSize,
double C
)
算法思想: 局部二值化
step1:
对某个像素值,原来的S,取其周围N*N的区域,求区域均值或者高斯加权值,记为T.step2:
对图像,如果S>T,则该像素二值化为255,否则为0
可以出入参数C,C可以是任何数,当S>T-C,则把原像素二值化为255.
参数C的作用,其实就是改变计算后的阈值,比如计算后的阈值是12,如果加上一个C,其阈值就变成了12+C
③ 自适应阈值分割代码示例
#include "MyOpencv.h"
int main(void)
{
Mat original = cv::imread("test_03.bmp", cv::IMREAD_GRAYSCALE);
imshow("Original", original);
// 使用大律法进行阈值分割
Mat dst;
cv::threshold(original, dst, 0, 255, cv::THRESH_OTSU);
imshow("Otsu", dst);
// 使用固定阈值分割
cv::threshold(original, dst, 127, 255, cv::THRESH_BINARY);
imshow("ThresBinary", dst);
// 使用自适应阈平均阈值值分割,并且C为0
adaptiveThreshold(original, dst, 255, cv::ADAPTIVE_THRESH_MEAN_C,
cv::THRESH_BINARY, 19, 0);
imshow("Mean_C(0)", dst);
// 使用自适应阈值高斯均值,并且C为10
adaptiveThreshold(original, dst, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C,
cv::THRESH_BINARY, 5, 2);
imshow("Gaussian_Mean_C(10)", dst);
waitKey(0);
return 0;
}