OpenCV::adaptiveThreshold 自适应阈值分割的源码分析

opencv 自适应二值化cv::adaptiveThreshold()函数详解(复杂背景下提取划痕) 文章目录前言一、opencv cv::adaptiveThreshold()函数1.函数原型:2.参数说明:3.函数原理:代码示例 前言 从以下复杂背景图片下提取划痕 假设采用全局阈值二值化, cv::threshold(src, globalBinayImage, 150, 255, cv::THRESH_BINARY_INV),很难得到最优的二值化效果,划痕没有完整提取出来,反而把背景也提取出来了: 这个时候就需要一种能够自适应的二值化算法上场了。 一、opencv cv::adaptiveThre 阅读详情

自适应阈值分割算法

  • 阈值分割算法或者二值化算法是用输入像素的值 III 与一个值 CCC 来比较,根据比较结果确定输出值。
  • 自适应阈值分割的每一个像素的比较值(阈值) CCC 都不同,阈值 CCC 由这个像素为中心的一个块范围计算在减去差值 delta 得到。

算法优势: 自适应阈值分割是在像素点的局部相邻区域内独立计算阈值, 再进行二值化分割, 尤其适用于明暗程度不一致的目标。

自适应阈值的计算方法

常用的两种方法:

  1. 平均值减去差值delta(使用盒过滤boxfilter,性能会非常不错)
  2. 高斯分布加权和减去差值delta (使用高斯滤波GaussionBlur)

举个例子:如果使用平均值方法,平均值mean为190,差值delta为30。那么灰度小于160的像素为0,大于等于160的像素为255。如下图:
在这里插入图片描述

如果是反向二值化,如下图:
在这里插入图片描述
delta选择负值也是可以的。

源码和注释

/** @brief 自适应二值化
*@param _src     要二值化的灰度图
*@param _dst     二值化后的图
*@param maxValue    二值化后要设置的那个值
*@param method 块计算的方法(ADAPTIVE_THRESH_MEAN_C 平均值,ADAPTIVE_THRESH_GAUSSIAN_C 高斯分布加权和)
*@param type     二值化类型(CV_THRESH_BINARY 大于为最大值,CV_THRESH_BINARY_INV 小于为最大值)
*@param blockSize    块大小(奇数,大于1)
*@param delta 差值(负值也可以)
*/
void cv::adaptiveThreshold(InputArray _src, OutputArray _dst, double maxValue,
    int method, int type, int blockSize, double delta)
{
    Mat src = _src.getMat();
 
    // 原图必须是单通道无符号8位
    CV_Assert(src.type() == CV_8UC1);
 
    // 块大小必须大于1,并且是奇数
    CV_Assert(blockSize % 2 == 1 && blockSize > 1);
    Size size = src.size();
 
    // 构建与原图像相同的图像
    _dst.create(size, src.type());
    Mat dst = _dst.getMat();
 
    if (maxValue < 0)
    {
        // 二值化后值小于0,图像都为0
        dst = Scalar(0);
        return;
    }

	CALL_HAL(adaptiveThreshold, cv_hal_adaptiveThreshold, src.data, src.step, dst.data, dst.step, src.cols, src.rows,
             maxValue, method, type, blockSize, delta);  // 硬件加速算法 cv_hal_adaptiveThreshold 未作实现,直接忽略
 
    // 用于比较的值
    Mat mean;
 
    if (src.data != dst.data)
        mean = dst;
 
    if (method == ADAPTIVE_THRESH_MEAN_C)
        // 计算平均值作为比较值
        boxFilter(src, mean, src.type(), Size(blockSize, blockSize),
        Point(-1, -1), true, BORDER_REPLICATE);
    else if (method == ADAPTIVE_THRESH_GAUSSIAN_C)
        // 计算高斯分布和作为比较值
        GaussianBlur(src, mean, Size(blockSize, blockSize), 0, 0, BORDER_REPLICATE);
    else
        CV_Error(CV_StsBadFlag, "Unknown/unsupported adaptive threshold method");
 
    int i, j;
 
    // 将maxValue夹到[0,255]的uchar范围区间,用作二值化后的值
    uchar imaxval = saturate_cast<uchar>(maxValue);
 
    // 根据二值化类型计算delta值
    int idelta = type == THRESH_BINARY ? cvCeil(delta) : cvFloor(delta);
 
    // 计算生成每个像素差对应的值表格,以后查表就可以。但像素差范围为什么是768,我确实认为512已经够了
    uchar tab[768];
 
    if (type == CV_THRESH_BINARY)
        for (i = 0; i < 768; i++)
            // i = src[j] - mean[j] + 255
            // i - 255 > -idelta ? imaxval : 0
            // = src[j] - mean[j] + 255 -255 > -idelta ? imaxval : 0
            // = src[j] > mean[j] - idelta ? imaxval : 0
            tab[i] = (uchar)(i - 255 > -idelta ? imaxval : 0);
    else if (type == CV_THRESH_BINARY_INV)
        for (i = 0; i < 768; i++)
            // i = src[j] - mean[j] + 255
            // i - 255 <= -idelta ? imaxval : 0
            // = src[j] - mean[j] + 255 - 255 <= -idelta ? imaxval : 0
            // = src[j] <= mean[j] - idelta ? imaxval : 0
            tab[i] = (uchar)(i - 255 <= -idelta ? imaxval : 0);
    else
        CV_Error(CV_StsBadFlag, "Unknown/unsupported threshold type");
 
    // 如果连续,加速运算
    if (src.isContinuous() && mean.isContinuous() && dst.isContinuous())
    {
        size.width *= size.height;
        size.height = 1;
    }
 
    // 逐像素计算src[j] - mean[j] + 255,并查表得到结果
    for (i = 0; i < size.height; i++)
    {
        const uchar* sdata = src.data + src.step*i;
        const uchar* mdata = mean.data + mean.step*i;
        uchar* ddata = dst.data + dst.step*i;
 
        for (j = 0; j < size.width; j++)
            // 将[-255, 255] 映射到[0, 510]然后查表
            ddata[j] = tab[sdata[j] - mdata[j] + 255];
    }
}

算法示例

Mat src = imread("d:\\src.jpg", 0);
cv::adaptiveThreshold(src, bw, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 17, 0);

在这里插入图片描述

opencv基础篇 ——(三)图像二值化 图像二值化是图像处理中常用的一种技术,用于将灰度图像转换为只包含两个像素值(通常是黑色和白色)的二值图像。这种处理通常用于简化图像、减少数据量以及强调感兴趣的目标。 阅读详情

相关推荐

【OpenCV3】阈值化操作——cv::threshold()与cv::adaptiveThreshold()详解

阈值化操作在图像处理中是一种常用的算法,比如图像的二值化就是一种最常见的一种阈值化操作。opencv2和opencv3中提供了两种阈值化操作接口,即cv::thread()与cv::adaptiveThreshold(),这里将对这两个接口进行介绍和对比。

guduruyu的专栏 5万+

opencv中自适应阈值(adaptiveThreshold()函数)介绍

1. 自适应阈值简介 自适应阈值(adaptiveThreshold())用于二值化处理图像,对于对比大的图像有较好效果,相对于固定阈值化操作(t’h)是指图像中每一个像素点是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。这样做的好处: 每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。 亮度较高的图像区域的二值化阈值通常会较高,而亮度较低的图像区域的二值化阈值则会相适应地变小。 不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。 1.2 项目目录

weixin_43977647的博客 4万+

OpenCV每日函数 杂项图像转换模块 (1) adaptiveThreshold自适应阈值函数

在进行阈值分割时,我们必须提供一个阈值来分割我们的前景和背景。Otsu 的阈值方法可以自动确定阈值的最佳值,然而,这种方法都是全局阈值技术,意味着使用相同的阈值来测试输入图像中的所有像素,从而将它们分割为前景和背景。 通常的做法是计算每个区域中像素强度的算术平均值或高斯平均值(还有一些其他方法,但算术平均值和高斯平均值是迄今为止最受欢迎的)。 在算术平均值中,邻域中的每个像素对计算阈值的贡献相同。并且在高斯均值中,远离区域(x, y)坐标中心的像素值对阈值的整体计算贡献较小。......

学以致用 知行合一 808

自适应阈值(adaptiveThreshold)分割原理及实现

背景介绍及原理 前面介绍了OTSU算法和最大熵算法,但这两种算法都属于全局阈值法,所以对于某些光照不均的图像,这种全局阈值分割的方法会显得苍白无力,如下图: 显然,这样的阈值处理结果不是我们想要的,那么就需要一种方法来应对这样的情况。 这种办法就是自适应阈值法(adaptiveThreshold),它的思想不是计算全局图像的阈值,而是根据图像不同区域亮...

小武的博客 9万+

【CAPL实用开发】--- 使用VN1640A测试Busoff快慢恢复

使用VN1640A测试Busoff快慢恢复,包含具体的CAPL代码实现。

LabVIEW、CAPL、python、车载以太网等学习分享,文章正在写 2094

WinForm轻松打造AntDesign现代化工具栏

摘要: 本文介绍如何在WinForm中利用AntdUI库实现AntDesign风格工具栏,包括安装配置、动态生成按钮/下拉菜单、布局优化及主题美化。通过AntButton、AntDropdown等控件结合事件绑定,可快速构建支持图标、工具提示、权限控制的现代化工具栏,并解决常见图标加载、布局错乱问题。最后提供代码示例与响应式设计技巧,助你打造高效美观的WinForm界面。 (字数:150)

java专栏 1593

自适应阈值化

自适应阈值化 微信公众号:幼儿园的学霸 目录 文章目录自适应阈值化目录背景介绍及原理原理权重选择说明自定义实现结果对比参考资料 背景介绍及原理 原理 图像阈值化的一般目的是从灰度图像中分离出目标区域和背景区域,然而仅仅通过设定全局固定阈值(对图像中的每个点其二值化的阈值都是相同的)的方法很难达到理想的分割效果。那么就需要一种方法来应对这样的情况。 这种办法就是自适应阈值法(adaptiveThreshold),它的思想不是计算图像的全局阈值,而是根据图像不同区域亮度分布,计算其局部阈值,对于图像不同区域

leonardohaig的博客 9985

手把手教你用WKT文件在Petrel中创建自定义坐标系统(附CGCS2000转换模板)

本文详细介绍了如何在Petrel软件中利用WKT文件创建自定义坐标系统,并重点提供了CGCS2000坐标系的完整转换模板与实战步骤。通过解析坐标系统的三大支柱(大地坐标系、投影坐标系、基准转换)和WKT文件结构,指导用户从零开始构建适用于本土化项目的坐标系统,确保地质建模与空间数据处理的精度与一致性。

gpt4scribbler的博客 277

自适应阈值法(图文总结)

概念: 该方法网上很多很简洁但是很难懂的公式,本文章将会由简单例子入手,一步步去理解那些公式,但是不做代码实现,毕竟只要搞懂了这个算法的思想,代码的实现其实千变万化,甚至用CV库的话根本不用写代码。 为啥出现这个二值化算法,OTSU的致命缺陷在哪里? 在大津算法OTSU中,由于采取的都是全局均值求出最佳全局阈值,但是在图片光照不均匀的场景,很容易把稍微模糊的边缘目标图像当作背景,为了避免这种场景,我们就可以考虑更为细腻的局部自适应阈值,它是根据图像不同区域亮度,不断计算更新局部阈值,同时不断“刷新”局部图像

whiteBearClimb的博客 1万+

MDK5 Debug调试方法总结

MDK5 Debug调试方法总结

m0_70748084的博客 2万+

VH6501干扰仪的使用

触发模式方法备注External Trigger(外部触发)使用VH6501的I/O口作为触发源Frame Trigger(报文触发)设定被干扰报文的触发位置,并发送干扰位序列/报文software Trigger(软件触发)配置好干扰序列后直接发送Error Frame Trigger(错误帧触发)基于错误帧标识位为触发条件触发干扰Direction Trigger(发送方向触发)根据TX/RX发送/接收方作为触发条件Inverted Trigger(反向触发)

帮助100万人颠覆负面潜意识,实现人生蜕变,培养1万名潜意识开发导师 9051

自适应阈值二值化算法

一、前言 当用照像机拍摄一副黑纸白字的纸张时,照相机获得的图像并不是真正的黑白图像。不管从什么角度拍摄,这幅图像实际上是灰度或者彩色的。除非仔细的设置灯光,否则照相机所拍摄的放在桌子上的纸张图像并不能代表原始效果。不像在扫描仪或打印机内部,想控制好桌子表面的光源是非常困难的。这个开放的空间可能会受到台灯、吊灯、窗户、移动的影子等影响。人类的视觉系统能自动补偿这些,但是机器没有考虑到这...

weixin_30881367的博客 1643

Plant Simulation新手入门:5步搞定生产线物流仿真(附模型库使用技巧)

本文为Plant Simulation新手提供了从零开始构建生产线物流仿真的五步入门指南。通过理念重塑、流程规划、对象连接、参数设置到数据分析的完整流程,帮助用户快速掌握这一强大仿真工具的核心逻辑。文章特别强调了模型库的高效使用技巧,助力工程师在虚拟环境中精准模拟和优化生产系统,提升规划效率。

efc123456的博客 333

OpenCV--042:自适应阈值算法

自适应阈值算法 利用图像局部阈值替换全局阈值进行图像计算的一种方法,具体针对光影变化过大的图片,或者范围内颜色差异不太明显的图片。自适应是指保证计算机能够通过判断和计算取得该图像区域的平均阈值进行迭代。 在图像阈值化操作中,更关注的是从二值化图像中,分离目标区域和背景区域,但是仅仅通过设定固定阈值很难达到理想的分割效果。而自适应阈值,则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。...

WaitFoF 3356

达梦慢sql和统计信息收集

各计划节点的执行顺序为:缩进越多的越先执行,同样缩进的上面的先执行,下面的后执行,上下的优先级高于内外。在建立索引的时候,要考虑索引的最左匹配原则(在使用 SQL 语句时,如果 where 部分的条件不符合最左匹配原则,可能导致索引失效,或者不能完全发挥建立的索引的功效);执行计划是 SQL 语句的执行方式,由查询优化器为语句设计的执行方式,交给执行器去执行。生产系统中,对于频繁变动的数据表,多次执行计划可能会出现不一致的问题,这往往是由于统计信息不准导致的,索引定期收集统计信息就很有必要了。

m0_37680131的博客 1714

基于ESP32的AI 古琴:基于音频指纹的民族乐器智能校准系统设计与实现

硬件选型兼顾实用性与低成本,接线简单易实现;基于 MFCC 的音频指纹算法,能有效识别古琴弦的音高特征;人机交互友好,新手可快速上手。

weixin_42300449的博客 307

c++图像处理-----自适应阈值操作:`cv::adaptiveThreshold()`

c++图像处理-----自适应阈值操作:`cv::adaptiveThreshold()`

qq_46107892的博客 1255

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

详解OpenCV的函数adaptiveThreshold(),并利用它实现图像的自适应二值化阈值分割

详解OpenCV的函数adaptiveThreshold(),并利用它实现图像的自适应二值化阈值分割

昊虹AI笔记 5万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

自适应阈值化方法

1.均值方法 为每一点单独计算阈值,块内均值作为阈值 2.高斯方法 为每一点单独计算阈值,块内加权均值作为阈值 3.otsu otsu法(最大类间方差法,有时也称之为大津算法)使用的是聚类的思想,把图像的灰度数按灰度级分成2个部分,使得两个部分之间的灰度值差异最大,每个部分之间的灰度差异最小,通过方差的计算来寻找一个合适的灰度级别 来划分。  所以 可以在二值化的时候 采用otsu算法来

nxxyq的专栏 1930

OpenCV adaptiveThreshold 自适应阈值

依据《学习OpenCV3》和OpenCV的官方文档,对自适应阈值adaptiveThreshold函数进行了详细解析,并且配以例程演示。

MechMaster 1400

OpenCV-自适应阈值函数cv::adaptiveThreshold

函数原型:void adaptiveThreshold( InputArray src, OutputArray dst,double maxValue, int adaptiveMethod,int thresholdType, int blockSize, double C );

翟天保的博客 1万+

【Opencv--自适应图像二值化】cv2.adaptiveThreshold()

【Opencv--自适应图像二值化】cv2.adaptiveThreshold()

Danger的博客 8517

OpenCV-Python(15):图像阈值处理

图像阈值是图像分割中常用的一种方法,通过将图像中的像素值与一个特定的阈值进行比较,将像素分为两个类别:小于阈值的像素被归为一类,大于等于阈值的像素被归为另一类。全局阈值法:将图像中的所有像素都与一个全局阈值进行比较,从而将图像分为两个类别。常用的全局阈值法有基于直方图的Otsu算法和基于最大类间方差的Kapur算法。自适应阈值法:将图像分为许多小的区域,在每个小区域内分别计算一个局部阈值,根据每个像素与其对应的局部阈值的比较结果进行分割。

图灵追幕者博客录 2043

Opencv threshold函数、adaptiveThreshold函数详解和示例

二值化方法可选择的标志及含义标志参数作用灰度值大于阈值的为最大值,其他值为0灰度值大于阈值的为0,其他值为最大值灰度值大于阈值的为阈值,其他值不变灰度值大于阈值的不变,其他值为0灰度值大于阈值的为0,其他值不变大津法自动寻求全局阈值三角形法自动寻求全局阈值为了方便讲解,我们使用如下的一个图像,红色表示图像,黑色是图像的边界,蓝色是阈值原图公式:对于原图,如果我们进行二值化操作,那么蓝色的线以上的,都变成最大值,蓝色的线以下的线都变成0。

m0_63893772的博客 1955

022-OpenCV4(C++)自适应阈值

022-OpenCV4(C++)自适应阈值

AlexanderMiao的博客 1575

OpenCV学习笔记(四)——阈值处理

阈值处理基础知识及常用函数。

简简单单的学习笔记,致力于帮助更多前进路上的朋友~ 1600
上一篇: Data Structures in C++:图
下一篇: C++刷题笔记:栈和队列
\lambda
博客等级 码龄11年 200粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值