函数原型
double threshold( InputArray src, OutputArray dst, double thresh, double maxval, int type );
参数说明
InputArray类型的src,输入图像。
OutputArray类型的dst,输出图像。
double类型的thresh,阈值的具体值。
double类型的maxval,阈值最大值。
int类型的type,阈值操作的类型,0为THRESH_BINARY(标准的二值化阈值法,大于thresh的设为maxval,小于的设为0),1为THRESH_BINARY_INV(反向二值化),2为THRESH_TRUNC(截断阈值法,大于thresh的设为thresh,小于则不变),3为THRESH_TOZERO(零化阈值法,大于thresh的不变,小于则零化),4为THRESH_TOZERO_INV(反向零化),7为THRESH_MASK(没测试出来什么用法,都是黑屏),8为THRESH_OTSU(大津算法,适合双峰直方图的图像,通过分析最大的背景前景类间方差,自动调节阈值),16为THRESH_TRIANGLE(三角法,适合单峰直方图图像,建立谷底和峰顶直线,距离直线垂直距离最大的直方图位置,即阈值thresh)。
测试代码
#include <iostream> #include "opencv2/core.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" using namespace cv; using namespace std; int main() { cv::Mat src = imread("test.jpg", 0); cv::Mat th1,th2,th3,th4,th5; // 最大类间差法,也称大津算法 threshold(src, th1, 0, 255, THRESH_OTSU); // 常规阈值分割法 threshold(src, th2, 100, 255, THRESH_BINARY); // 截断阈值分割法 threshold(src, th3, 80, 255, THRESH_TRUNC); // 零化阈值分割法 threshold(src, th4, 100, 255, THRESH_TOZERO); // 三角法 threshold(src, th5, 0, 255, THRESH_TRIANGLE); imshow("original", src); imshow("otsu", th1); imshow("binary", th2); imshow("trunc", th3); imshow("zero", th4); imshow("triangle", th5); waitKey(0); return 0; }
测试效果
图1 灰度图
图2 大津算法效果图
图4 截断阈值分割法效果图
图5 零化阈值分割法效果图
图6 三角法效果图
图3 常规阈值分割法效果图
一般来说,opencv提供的阈值函数可以适用大多数场景,针对特殊场景,可以根据自身需求自行设计阈值算法。另外,大津算法针对图像灰度接近的场景挺有效的,用其他算法可能无法精确分离;三角法在图像对比度较大的场景比较好用,可以较好地识别出目标区域,但是这个区域可能偏大些,一般配合边缘渐变算法使边缘平滑过渡~
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!