IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> OpenCV基础教程(5)—— 阈值分割 -> 正文阅读

[人工智能]OpenCV基础教程(5)—— 阈值分割

5. 阈值分隔

5.1 全局阈值分隔

全局阈值分割指的是将灰度值大于 thresh(阈值)的像素设为白色,小于或者等于 thresh 的像素设为黑色;或者反过来,将大于 thresh 的像素设为黑色,小于或者等于 thresh 的像素设为白色,两者的区别只是呈现形式不同。

OpenCV提供的函数如下:

double cv::threshold(cv::InputArray src, cv::OutputArray dst, double thresh, double maxval, int type)

src:单通道矩阵,数据类型为 CV_8U 或者 CV_32F。type = THRESH_OTSU 或 THRESH_TRIANGLE 时,src 只支持 uchar 类型。

dst:输出矩阵,即阈值分割后的矩阵

thresh:阈值

maxVal:在图像二值化显示时,一般设置为 255

type:阈值分隔类型

使用方法如下:

//输入矩阵为 5 行 3列
Mat src = (Mat_<uchar>(5, 3) << 123, 234, 68, 33, 51, 17,
48, 98, 234, 129, 89, 27, 45, 167, 134);
//第一种情况:手动设置阈值
double the = 150;
Mat dst;
threshold(src, dst, the, 255, THRESH_BINARY);
//第二种情况:Otsu 算法
double otsuThe=0;
Mat dst_Otsu;
otsuThe = threshold(src, dst_Otsu, otsuThe, 255, THRESH_OTSU + THRESH_BINARY);
//第三种情况:TRIANGLE 算法
double triThe=0;
Mat dst_tri;
triThe = threshold(src, dst_tri, 0, 255, THRESH_TRIANGLE + THRESH_BINARY);
return 0;

5.1.1 利用熵算法计算阈值

信息熵(entropy)的概念来源于信息论,假设信源符号 𝑢 有 𝑁 种取值,记为
u 1 , u 2 , ? ? , u N u_1,u_2,\cdots,u_N u1?,u2?,?,uN?
且每一种信源符号出现的概率,记为
p 1 , p 2 , ? ? , p N p_1,p_2,\cdots,p_N p1?,p2?,?,pN?
那么该信源符号的信息熵,记为
entropy ( u ) = ? ∑ i = 1 N p i log ? p i \text{entropy}(u)=-\sum\limits_{i=1}^{N}{{{p}_{i}}\log {{p}_{i}}} entropy(u)=?i=1N?pi?logpi?
图像也可以看作一种信源,假设输入图像为 I \mathbf{I} I normHis t I \text{normHis}{{\text{t}}_{\mathbf{I}}} normHistI?代表**归一化**的图像灰度直方图,那么对于 8 位图可以看成由 256 个灰度符号,且每一个符号出现的概率为 normHis t I ( k ) \text{normHis}{{\text{t}}_{\mathbf{I}}}(k) normHistI?(k)组成的信源,其中 0 ? 𝑘 ? 255。

利用熵计算阈值的步骤如下:

第一步:计算 I \mathbf{I} I的累加概率直方图,又称零阶累积矩,记为
cumuHist ( k ) = ∑ i = 0 k normHis t I ( k ) , k ∈ [ 0 , 255 ] \text{cumuHist}(k)=\sum\limits_{i=0}^{k}{\text{normHis}{{\text{t}}_{\mathbf{I}}}(k)},k\in [0,255] cumuHist(k)=i=0k?normHistI?(k),k[0,255]
第二步:计算各个灰度级的熵,记为
entropy ( t ) = ? ∑ k = 0 t normHis t I ( k ) log ? ( normHis t I ( k ) ) , t ∈ [ 0 , 255 ] \text{entropy}(t)\text{=}-\sum\limits_{k=0}^{t}{\text{normHis}{{\text{t}}_{\mathbf{I}}}(k)\log (\text{normHis}{{\text{t}}_{\mathbf{I}}}(k))},t\in [0,255] entropy(t)=?k=0t?normHistI?(k)log(normHistI?(k)),t[0,255]
第三步:计算使 f ( t ) = f 1 ( t ) + f 2 ( t ) f(t)={{f}_{1}}(t)+{{f}_{2}}(t) f(t)=f1?(t)+f2?(t)最大化的 t t t值,该值即为得到的阈值,其中
KaTeX parse error: No such environment: align at position 8: \begin{?a?l?i?g?n?}? & {{f}_{1}}(…

5.2 局部阈值分隔(自适应阈值分隔)

背景:光照不均的情况下,全局阈值分隔的效果不是很理想。在这种情况下,使用局部阈值(自适应阈值)进行分隔可以产生好的效果。

局部阈值分隔不再像全局阈值一样,对整个矩阵只有一个阈值,而是针对输入矩阵的每一个位置的值都有相对应的阈值,这些阈值构成了和输入矩阵同等尺寸的矩阵 t h r e s h \mathbf{thresh} thresh


局部阈值分隔的核心是计算阈值矩阵,方法如下:

第一步:对图像进行平滑处理,平滑结果记为 f smooth ( I ) {{f}_{\text{smooth}}}(\mathbf{I}) fsmooth?(I),其中平滑可以是均值平滑、高斯平滑、中值平滑,但是平滑算子的宽和高必须都是奇数。

第二步:自适应阈值矩阵 T h r e s h = ( 1 ? ratio ) ? f smooth ( I ) \mathbf{Thresh}=(1-\text{ratio})\cdot {{f}_{\text{smooth}}}(\mathbf{I}) Thresh=(1?ratio)?fsmooth?(I),一般令 ratio = 0.15 \text{ratio}=0.15 ratio=0.15

第三步:利用局部阈值分隔的规则进行阈值分隔。


在自适应阈值处理中,平滑算子的尺寸决定了分割出来的物体的尺寸,如果滤波器尺寸太小,那么估计出的局部阈值将不理想。凭经验,平滑算子的宽度必须大于被识别物体的宽度,平滑算子的尺寸越大,平滑后的结果越能更好地作为每个像素的阈值的参考,当然也不能无限大。

OpenCV提供的自适应阈值函数如下:

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

src:单通道矩阵,数据类型为 CV_8U

dst:输出矩阵,即阈值分割后的矩阵

maxValue:与函数 Threshold 类似,一般取 255

adaptiveMethod:

? ADAPTIVE_THRESH_MEAN_C:采用均值平滑

? ADAPTIVE_THRESH_GAUSSIAN_C:采用高斯平滑

thresholdType:THRESH_BINARY、THRESH_BINARY_INV

blockSize:平滑算子的尺寸,且为奇数

C:比例系数。这个参数实际上是一个偏移值调整量,用均值和高斯计算阈值后,再减或加这个值就是最终阈值。

5.3 二值图的逻辑运算

“与”运算

void cv::bitwise_and(cv::InputArray src1, cv::InputArray src2, cv::OutputArray dst, cv::InputArray mask = noArray())

“或”运算

void cv::bitwise_or(cv::InputArray src1, cv::InputArray src2, cv::OutputArray dst, cv::InputArray mask = noArray())

效果如下:

image-20211018205933188

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-11-10 12:23:57  更:2021-11-10 12:26:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 6:17:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码