Opencv 基本操作八 不均匀光照下的图像二值化探讨

news2024/11/16 3:42:03

在进行图像二值化时总是存在一些明部、暗部的干扰,单一的使用opencv提供的原始二值化方法很难做到预期效果。一般我们都会采用分块二值化(将图像切为多个局部进行二值化)、对比度提升(对值域进行线性或者非线性变换、直方图均衡化)、局部二值化(Bernsen 算法、 Niblack 算法、Sauvola算法、 Chow 和 Kaneko 算法等)的方式进行二值化。这些手段限制了思路的发挥,不一定适用于所有场景。这里对可搜集的二值化方法进行汇总。共统计出4种二值化方法:1、颜色空间转换,2、多次二值化,3、背景光补偿,4、梯度信息补充。本博文介绍了各个方法的案例、核心思想、基本步骤和适用范围。

1、颜色空间转化

rgb影像转灰度图后,在进行二值化时会遗失部分颜色信息,而在某些任务中颜色信息又是进行二值化的必须依赖。如,按照颜色提取图中的特定物体等。
具体案例:https://bbs.csdn.net/topics/390735437?page=1
原始思路:rgb=>gray=>otsu二值化

新思路:rgb=>hsv=>h通道otsu二值化

此外,对于hsv颜色空间,还可以对h*v进行二值化,这样子可以提取出图像中颜色显著的部分。

核心思想:通过转换颜色空间,对明度、亮度、颜色饱和度等信息进行二值化。
基本步骤:
1、进行颜色空间转换,使颜色突出的部分区域在指定通道(明度、亮度、颜色饱和度)上比较突出;(如hsv的h和v通道,lab的l通道)
2、对指定通道进行二值化
适用范围:以颜色显著变换为主的形态分割

2、多次二值化

对于一些存在亮部和暗部的图像,使用一个二值化阈值进行操作是无法得到理想结果的,需要使用多个阈值进行二值化。

具体案例:https://blog.csdn.net/weixin_55984718/article/details/125769347
执行效果:
核心思想:进行2次OTSU分别提取出亮部和暗部的二值化阈值,然后根据2个阈值进行逐像素的二值化。
基本步骤:
1、基于OTSU得到二值化阈值t1和mask ;
2、获取mask中暗部的二值化阈值t2 ;
3、针对亮部和暗部区域分别使用不同的阈值 ;(足像素进行二值化)

适用范围:存在一个阴影或者亮部干扰的图像

3、背景光补偿法

在对书籍文本进行二值化化时,通常由于反光、数据表面不平使原始图像上存在亮斑和暗斑,这使得单一二值化阈值不再适用。

具体案例:https://blog.csdn.net/u013162930/article/details/47755363
执行效果:原图和求出的背景光补偿图

核心思想:通过邻域确定背景光补偿值,最终使图像的光照处于一个统一稳定的的水平,然后再进行二值化
基本步骤:
1、逐像素计算其邻域的最大值,作为背景值,然后计算出背景光补偿值
2、根据背景光补偿图对原图光照进行补偿,使图像的光照处于一个统一稳定的的水平
3、对图像进行otsu二值化
像数值和领域锚值差异小,补偿值接近0;原图过亮,补偿值为负数;原图过暗,补偿值为正数

适用范围:其计算背景光的方式使其仅能用于文本的二值化,若能从全局角度计算出背景光补偿值,则可以用于其他复杂场景
注1:还有另外一种背景光补偿法,其基于全局均值(锚值)和局部均值(当前值)做差得到补偿值 可以参考 https://harry.blog.csdn.net/article/details/54019994
注2:该方法作者提到了sauvola二值算法,其实现在https://blog.csdn.net/lcalqf/article/details/71479650

sauvola二值算法的使用效果可以参考,比起章节二中的多次二值化是要好一些
http://www.zhihuishi.com/source/248.html#download

4、梯度信息补充

在某些光照环境下,亮与暗为一个基于对比的相对关系,某些像数值在亮部区域算暗,而在暗部区域算亮。

例如上图,若适用单一阈值进行处理则会得到以下结果:

具体案例:https://blog.woyou.cool/post/%e4%b8%8d%e5%9d%87%e5%8c%80%e5%85%89%e7%85%a7%e4%b8%8b%e7%9a%84%e5%9b%be%e5%83%8f%e4%ba%8c%e5%80%bc%e5%8c%96%e5%a4%84%e7%90%86%e6%96%b9%e6%a1%88/
核心思想:通过边缘梯度信息对二值化结果再次进行分割判断
基本步骤:
1、先求出原图的边缘梯度信息(包含xy方向)
2、对原图进行二值化
3、使用边缘梯度信息分割二值图
4、根据均值选择连通域

适用范围:其基于梯度信息对二值化结果进行优化,只能用于提取面积较大的图形(对于字符的提取是不行的)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/442743.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#串口通信从入门到精通(2)——串口相关参数介绍

1、端口号(Port) 我们使用一个串口的时候,首先是要打开这个串口,那么我们怎么知道电脑上现在支持几个串口呢?对应的端口号又是什么呢? 由于我的电脑系统是window11,下面就以window11为例介绍如…

网络请求实战-缓存、缓存清理和HTTP缓存

目录 缓存介绍 清空策略(FIFO) 实战:fifo的memory函数 实战:LRU算法 HTTP缓存 Cache-Control 强制缓存 协商缓存 协商缓存-2(用的最多的) 小结 缓存介绍 早期cpu,内存设计上都有缓存…

开发常用的 Linux 命令4(系统、进程和其它)

开发常用的 Linux 命令4(系统、进程和其它) 作为开发者,Linux是我们必须掌握的操作系统之一。因此,在编写代码和部署应用程序时,熟练使用Linux命令非常重要。这些常用命令不得不会,掌握这些命令&#xff0…

【JUC】volatile和JMM

【JUC】volatile和JMM 文章目录 【JUC】volatile和JMM1. volatile1.1 特点1.2 内存语义 2. 内存屏障2.1 分类2.2 什么叫保证有序性?2.3 内存屏障的4种插入策略 3. volatile特性3.1 保证可见性3.2 volatile读写过程3.3 没有原子性3.4 指令禁重排(有序性) 4. 正确使用…

python标识符概念及规范

在python中 能取名字的东西非常非常多 例如 我们之前学的变量 以及后面要接触的 函数 类,等等,等等 而我们给这些取的名字 被统称为 标识符 而 python中 标识符的命名也是有限制的 主要有三种 1 内容限定 2 大小写铭感 3 不能使用关键字 内容限定来讲…

leetcode6_N字形变换

如有错误,感谢不吝赐教、交流 leetcode6 题目描述 将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。 比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下: P A H N A P L S I…

HTB-SecNotes

HTB-SecNotes 信息收集8808端口80端口通过CSRF获取通过二次注入 立足tyler -> administrator 信息收集 8808端口 Windows IIS 10.0 可以从官方文档查看10.0版本可能的操作系统。 80端口 通过CSRF获取 目录扫描发现需要登陆后继续进一步操作啊。 对其进行简单的SQL注入测…

数据库基础篇 《7.单行函数》

目录 1. 函数的理解 1.1 什么是函数 1.2 不同DBMS函数的差异 ​编辑1.3 MySQL的内置函数及分类 ​编辑 2. 数值函数 2.1 基本函数 ​编辑 2.2 角度与弧度互换函数 2.3 三角函数 ​编辑 2.4 指数与对数 ​编辑 2.5 进制间的转换 ​编辑3. 字符串函数 ​编辑…

SAM(segment anything model)分割一切 Demo测试及API调用

SAM 分割一切 一,SAM介绍1.1 介绍1.2 项目链接 二,Demo-Test:2.1 Demo功能介绍2.1.1,首页就是这个SAM,点击try demo,可以选择它的自带图片,也可以自己添加。2.1.2 , 自己上传图片测试&#xff1…

[java基础]面向对象(五)

访问控制修饰符:--------------保护数据的安全(隐藏数据、暴露行为),实现封装 public:公开的,任何类 private:私有的,本类 protected:受保护的,本类、派生类、同包类 默认的&…

learn_C_deep_3 (最名不符实的关键字 - static、static关键字总结、基本数据类型、最冤枉的关键字 - sizeof)

目录 最名不符实的关键字 - static stati修饰全局变量和函数 static修饰局部变量 static关键字总结 几个问题 1.c语言要设置全局变量和函数可以跨文件使用的原因 2.C程序地址空间是什么样的? 3.局部变量为什么具有临时性 4.全局变量为什么具有全局性 5.为…

vue-cli版本号始终是2.9.6,且无法删除,安装更新无效的问题。

参考博客 目录 1.问题出现原因2.我的解决办法:删除原脚手架&删除原vuevue.cmd 1.问题出现原因 从各种博客我得知,这种问题出现在2处: 没有卸载原来的脚手架原来的vue和vue.cmd没删除干净 2.我的解决办法:删除原脚手架&…

[oeasy]python0135_命名惯用法_name_convention

命名惯用法 回忆上次内容 上次 了解了isidentifier的细节 关于 关键字关于 下划线 如何查询 变量所指向的地址? id 如何查询 已有的各种变量? locals 如果 用一个变量a的值 给另一个变量b 赋值是什么样的过程 呢??🤔…

当,Kotlin Flow与Channel相逢

前言 之前的文章已经分析了Flow的相关原理与简单使用,Flow之所以用起来香,Flow便捷的操作符功不可没,而想要熟练使用更复杂的操作符,那么需要厘清Flow和Channel的关系。 本篇文章构成: 1. Flow与Channel 对比 1.1 Fl…

AVL树(C++实现)

文章目录 AVL树的概念AVL树结点定义AVL树的插入AVL树的旋转左单旋右单旋左右单旋右左双旋 AVL树的验证AVL树的性能AVL树及测试完整代码 AVL树的概念 二叉搜索树虽然可以缩短查找的效率,但如果数据有序或接近有序,那么二叉搜索树将退化为单支树,查找元素则相当于在顺序表中搜索…

从零手写Resnet50实战——利用 torch 识别出了虎猫和萨摩耶

大家好啊,我是董董灿。 自从前几天手写了一个慢速卷积之后(从零手写Resnet50实战—手写龟速卷积),我便一口气将 Resnet50 中剩下的算法都写完了。 然后,暴力的,按照 Resnet50 的结构,将手写的…

【Flowable】Flowable基础表结构

1.表结构讲解 表结构创建文件:flowable-engine-6.3.0.jar!\org\flowable\db\create\flowable.mysql.create.engine.sql 工作流程的相关操作都是操作存储在对应的表结构中,为了能更好的弄清楚Flowable的实现原理和细节,我们有必要先弄清楚Fl…

Python边缘检测之prewitt, sobel, laplace算子

文章目录 滤波算子简介具体实现测试 滤波算子简介 ndimage中提供了卷积算法,并且建立在卷积之上,提供了三种边缘检测的滤波方案:prewitt, sobel以及laplace。 在convolve中列举了一个用于边缘检测的滤波算子,统一维度后&#xf…

es6 const的使用

1.const用来定义常量&#xff0c;赋值知乎不能再赋值&#xff0c;再次赋值会报错。 <script>//1.定义常量&#xff0c;赋值后不能再赋值&#xff0c;在赋值报错const count 1// count 2</script> ​ 2.const不能只声明不赋值&#xff0c;会报错。 <script>…