本文的基础是OpenCV的函数threshold(),关于函数threshold()的详细介绍,大家可以参考下面这篇博文:
 https://www.hhai.cc/thread-162-1-1.html
一、图像的OTSU阈值化
 在阈值化处理中,OTSU是一种常用的算法,中文译为大津法或最大类间方差法。
 它是1979年由日本学者大津展之提出的一种对图像进行二值化的高效算法,是在判别与最小二乘法原理的基础上推导出来的。
 它的基本思路是把直方图在某一阈值处分割成两组,当被分成的两组间方差为最大时,这一阈值为“决定阈值”。
OTSU的算法步骤如下:
 ⑴统计灰度级中每个像素在整幅图像中的个数。
 ⑵计算每个像素在整幅图像的概率分布。
 ⑶对灰度级进行遍历搜索,计算当前灰度值下前景背景类间概率。
 ⑷通过目标函数计算出类内与类间方差下对应的阈值。
 更具体的原理介绍大家可以参考下面这篇博文:
 https://blog.csdn.net/weixin_44227356/article/details/116031602
图像的OTSU阈值化可以直接由函数threshold()实现,具体实现的代码我已经写在下面这篇博文中了:
 https://www.hhai.cc/thread-162-1-1.html【打开页面后搜索“当type取值为THRESH_OTSU 、THRESH_TRIANGLE时的示例代码”】
在上面链接的博文中我已经说了,函数threshold()的Python版才会返回进行阈值化时所使用的阈值,C++版本则不会,所以在OpenCV-C++环境下,函数threshold()使用OTSU算法进行阈值化处理时用的阈值我们是不知道的。如果想知道OTSU算法的阈值是多少,只有自己根据OTSU算法的原理写出代码进行计算。
 这里昊虹君根据OTSU算法的原理写了一个计算OTSU阈值计算的函数,
 具体的代码请大家访问本博文的原文获取,
 本博文原文链接如下:
 https://www.hhai.cc/thread-165-1-1.html
 运行结果如下:
 
 上面的阈值与我们在Python-OpenCV环境下使用函数threshold()得到的OTSU阈值是一样的:
 
 上面这张截图来源于下面这篇博文:
 https://www.hhai.cc/thread-162-1-1.html
二、图像的双阈值化
 有时候图像中有明显的双分界特征,我们考虑用双阈值法进行阈值化操作。
 所谓双阈值化是指对于两个阈值thresh1<thresh2,将大于thresh1且小于thresh2的灰度值设定为maxval,其余的灰度值设为0。
 其数学表达式如下:
 
    
     
      
       
        d
       
       
        s
       
       
        t
       
       
        (
       
       
        x
       
       
        ,
       
       
        y
       
       
        )
       
       
        =
       
       
        
         {
        
        
         
          
           
            
             
              m
             
             
              a
             
             
              x
             
             
              v
             
             
              a
             
             
              l
             
            
           
          
          
           
            
             
              t
             
             
              h
             
             
              r
             
             
              e
             
             
              s
             
             
              h
             
             
              2
             
             
              >
             
             
              s
             
             
              r
             
             
              c
             
             
              (
             
             
              x
             
             
              ,
             
             
              y
             
             
              )
             
             
              >
             
             
              t
             
             
              h
             
             
              r
             
             
              e
             
             
              s
             
             
              h
             
             
              1
             
            
           
          
         
         
          
           
            
             0
            
           
          
          
           
            
             
              其
             
             
              它
             
            
           
          
         
        
       
      
      
       dst(x,y)=\left\{\begin{matrix} maxval & thresh2>src(x,y)>thresh1 \\0 & 其它 \end{matrix}\right.
      
     
    dst(x,y)={maxval0thresh2>src(x,y)>thresh1其它
 可以用函数threshold()实现图像的双阈值化,其C++代码如下:
//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术
//OpenCV版本 OpenCV3.0
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
	cv::Mat A1 = (cv::Mat_<uchar>(2, 3) << 0, 10, 50,
		80, 150, 255);
	cout << "A1中的数据为:\n" << A1 << endl << endl;
	double low_threshold = 70;
	double high_threshold = 180;
	double maxval1 = 222;
	Mat B1, B2, B3, B4, B5;
	// 小阈值对图像或矩阵进行阈值化操作
	threshold(A1, B1, low_threshold, maxval1, THRESH_BINARY);
	cout << "B1中的数据为:\n" << B1 << endl << endl;
	// 大阈值对图像或矩阵进行阈值化操作
	threshold(A1, B2, high_threshold, maxval1, THRESH_BINARY_INV);
	cout << "B2中的数据为:\n" << B2 << endl << endl;
	// 矩阵与运算得到阈值化结果
	cv::bitwise_and(B1, B2, B3);
	cout << "B3中的数据为:\n" << B3 << endl << endl;
	return(0);
}
运行结果如下图所示:
 
 从上面的运行结果我们可以看出,原矩阵中介于阈值70到180之间的灰度值被置为了222,其它灰度值被置为了0。
二、图像的半阈值化
 如果图像中有明显的目标与背景的差异特征,那么进行阈值化操作时,可以使用半阈值化进行操作。
 半阈值化操作时,大于thresh的灰度值不变,其余灰度值置为0。
 半阈值化的数学表达式如下:
 
 函数threshold(),当参数type取值为“THRESH_TOZERO”时,实际上就是作的图像的半阈值化操作。
 示例代码之前在博文https://www.hhai.cc/thread-162-1-1.html中就已经给出了,这里就不再给了。



















