博客
关于我
自适应阈值(adaptiveThreshold)分割原理及实现
阅读量:798 次
发布时间:2023-04-15

本文共 2951 字,大约阅读时间需要 9 分钟。

自适应阈值法:解决光照不均图像分割的难题

在图像处理领域,OTSU算法和最大熵算法作为全局阈值分割的代表方法,虽然在许多场景下表现出色,但在面对光照不均(阴影、亮斑等)的图像时往往显得力不从心。这种现象在实践中经常出现,如下图所示:

此类问题的根本原因在于传统的全局阈值方法无法有效捕捉到图像局部的亮度变化特征。这种局限性促使我们探索一种更加灵活的解决方案——自适应阈值法。

自适应阈值法的核心思想

自适应阈值法(Adaptive Thresholding)与传统的全局阈值法有着本质的区别:它不是基于整个图像计算固定的阈值,而是根据图像不同区域的亮度分布,自适应地为每个局部区域计算最优的阈值。这种方法能够更好地适应复杂的光照条件,解决传统方法在处理光照不均图像时的不足。

具体而言,自适应阈值法通过以下方法实现局部阈值的计算:

  • 均值阈值法:计算某个邻域(局部区域)的平均值,并与给定常数 ( C ) 做偏移,得到局部的阈值。
  • 高斯加权平均法:类似均值法,但采用了高斯滤波对局部区域进行加权平均,能够更有效地平滑图像,减少噪声的影响。
  • 中值法:使用中值滤波算法,选择局部区域的中值作为阈值。
  • 值得注意的是,虽然均值法看似简单,但其在实践中表现出色,尤其在处理光照不均问题时能够提供较好的视觉效果。

    OpenCV中的自适应阈值法实现

    OpenCV为开发者提供了丰富的API来实现自适应阈值法,以下是相关函数的说明:

    void adaptiveThreshold(    InputArray src,    OutputArray dst,    double maxValue,    int adaptiveMethod,    int thresholdType,    int blockSize,    double C);

    参数说明

  • InputArray src:输入图像。
  • OutputArray dst:输出图像,与输入图像大小一致。
  • double maxValue:最大值,用于二值化操作。
  • int adaptiveMethod:决定阈值计算方法的参数:
    • ADAPTIVE_THRESH_MEAN_C:使用均值法加偏移。
    • ADAPTIVE_THRESH_GAUSSIAN_C:使用高斯加权平均法加偏移。
  • int thresholdType:阈值类型:
    • THRESH_BINARY:二值化处理(阈值以上设为最大值,以下设为0)。
    • THRESH_BINARY_INV:取反后的二值化处理。
  • int blockSize:局部邻域的大小,常用值为3、5、7等。
  • double C:偏移值,用于调整阈值。
  • 代码实现

    以下是一个基于OpenCV实现自适应阈值法的示例代码:

    #include 
    #include
    using namespace cv;using namespace std;void AdaptiveThreshold(Mat& src, Mat& dst, double Maxval, int Subsize, double c) { if (src.channels() > 1) { cvtColor(src, src, CV_BGR2GRAY); } // 选择不同的滤波方法 Mat smooth; if (c == 0) { blur(src, smooth, Size(Subsize, Subsize)); } else { GaussianBlur(src, smooth, Size(Subsize, Subsize), 0, 0); } // 偏移调整 smooth -= c; // 复制原图并应用阈值处理 src.copyTo(dst); for (int r = 0; r < src.rows; ++r) { const uchar* srcPtr = src.ptr(r); const uchar* smoothPtr = smooth.ptr(r); uchar* dstPtr = dst.ptr(r); for (int c = 0; c < src.cols; ++c) { if (srcPtr[c] > smoothPtr[c]) { dstPtr[c] = Maxval; } else { dstPtr[c] = 0; } } }}int main() { Mat src = imread("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Img\\Fig1049(a)(spot_shaded_text_image).tif"); if (src.empty()) { return -1; } if (src.channels() > 1) { cvtColor(src, src, CV_BGR2GRAY); } // 生成自适应阈值图像 Mat dst, dst2; AdaptiveThreshold(src, dst, 255, 21, 10); cv::adaptiveThreshold(src, dst2, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 21, 10); // 显示图像 namedWindow("src", CV_WINDOW_NORMAL); imshow("src", src); namedWindow("dst", CV_WINDOW_NORMAL); imshow("dst", dst); namedWindow("dst2", CV_WINDOW_NORMAL); imshow("dst2", dst2); waitKey(0); return 0;}

    代码解释

  • AdaptiveThreshold函数:这是自适应阈值法的核心函数,接收源图像和多个参数,返回处理后的图像。
  • 图像转换:如果输入图像是彩色图,使用cv::cvtColor将其转换为灰度图,以便后续处理。
  • 滤波处理:根据传入的参数选择不同的滤波方法(均值滤波或高斯滤波),生成平滑后的图像。
  • 偏移调整:将滤波后的图像与常数 ( C ) 做减法,得到最终的阈值图像。
  • 二值化处理:将源图像和阈值图像进行二值化处理,得到最终的自适应阈值图像。
  • 效果展示

    通过上述方法,处理后的图像效果显著改善,如下图所示:

    此方法在处理光照不均图像时,能够更好地保留细节信息,显著提升了图像的视觉质量。

    转载地址:http://egrfk.baihongyu.com/

    你可能感兴趣的文章
    Mysql 分页语句 Limit原理
    查看>>
    MySql 创建函数 Error Code : 1418
    查看>>
    MySQL 创建新用户及授予权限的完整流程
    查看>>
    mysql 创建表,不能包含关键字values 以及 表id自增问题
    查看>>
    mysql 删除日志文件详解
    查看>>
    mysql 判断表字段是否存在,然后修改
    查看>>
    MySQL 到底能不能放到 Docker 里跑?
    查看>>
    mysql 前缀索引 命令_11 | Mysql怎么给字符串字段加索引?
    查看>>
    mysql 协议的退出命令包及解析
    查看>>
    mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
    查看>>
    mysql 四种存储引擎
    查看>>
    MySQL 基础模块的面试题总结
    查看>>
    MySQL 备份 Xtrabackup
    查看>>
    mysql 多个表关联查询查询时间长的问题
    查看>>
    mySQL 多个表求多个count
    查看>>
    mysql 多字段删除重复数据,保留最小id数据
    查看>>
    MySQL 多表联合查询:UNION 和 JOIN 分析
    查看>>
    MySQL 大数据量快速插入方法和语句优化
    查看>>
    mysql 如何给SQL添加索引
    查看>>
    mysql 字段区分大小写
    查看>>