【转】Emgu CV on C# (五) —— Emgu CV on 局部自适应阈值二值化
局部自适应阈值二值化
相对全局阈值二值化,自然就有局部自适应阈值二值化,本文利用Emgu CV实现局部自适应阈值二值化算法,并通过调节block大小,实现图像的边缘检测。
一、理论概述(转载自《OpenCV_基于局部自适应阈值的图像二值化》)
局部自适应阈值则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。这样做的好处在于每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。亮度较高的图像区域的二值化阈值通常会较高,而亮度较低的图像区域的二值化阈值则会相适应地变小。不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。常用的局部自适应阈值有:1)局部邻域块的均值;2)局部邻域块的高斯加权和。
二、程序实现
1、关键函数
关键函数 CvInvoke.cvAdaptiveThreshold Method
函数功能:
Transforms grayscale image to binary image. Threshold calculated individually for each pixel. For the method CV_ADAPTIVE_THRESH_MEAN_C it is a mean of blockSize x blockSize pixel neighborhood, subtracted by param1. For the method CV_ADAPTIVE_THRESH_GAUSSIAN_C it is a weighted sum (gaussian) of blockSize x blockSize pixel neighborhood, subtracted by param1.
函数原型:
public static void cvAdaptiveThreshold(
IntPtr src,
IntPtr dst,
double maxValue,
ADAPTIVE_THRESHOLD_TYPE adaptiveType,
THRESH thresholdType,
int blockSize,
double param1
)
第一个参数src表示输入图像,必须为单通道灰度图。
第二个参数dst表示输出的边缘图像,为单通道黑白图。
第三个参数maxValue表示采用CV_THRESH_BINARY 和CV_THRESH_BINARY_INV门限类型的最大值。
第四个参数adaptiveType表示局部二值化阈值的取值方法,自适应阈值算法使用:CV_ADAPTIVE_THRESH_MEAN_C 或 CV_ADAPTIVE_THRESH_GAUSSIAN_C,ADAPTIVE_THRESHOLD_TYPE枚举类型
| Member name | Value | Description |
|---|---|---|
| CV_ADAPTIVE_THRESH_MEAN_C | 0 | indicates that "Mean minus C" should be used for adaptive threshold. |
| CV_ADAPTIVE_THRESH_GAUSSIAN_C | 1 | indicates that "Gaussian minus C" should be used for adaptive threshold. |
第五个参数thresholdType表示取阈值类型:必须是下者之一
CV_THRESH_BINARY,CV_THRESH_BINARY_INV
第六个参数block_size代表用来计算阈值的象素邻域大小,例如:3,5,7…
第七个参数表示均值或高斯加权平均值所需要减去的一个常数,类似一个人工干预的阈值调整。
对方法 CV_ADAPTIVE_THRESH_MEAN_C,先求出块中的均值,再减掉param1。
对方法 CV_ADAPTIVE_THRESH_GAUSSIAN_C ,先求出块中的加权和(gaussian), 再减掉param1。
2、编程实现
采用均值法设定局部适应阈值,块大小为25,参数取值为5.
//局部二值化
Image<Gray, Byte> adaptivethreshimg = new Image<Gray, Byte>(graymi.width, graymi.height);
CvInvoke.cvAdaptiveThreshold(grayimg, adaptivethreshimg, 255, Emgu.CV.CvEnum.ADAPTIVE_THRESHOLD_TYPE.CV_ADAPTIVE_THRESH_MEAN_C, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY, 25, 5);
pictureBox4.Image = adaptivethreshimg.ToBitmap();


采用本文算法获取的二值化图像

第五个参数本文用的是Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY,刚好与原文相反,因此一个是白底,一个是黑底。
转载请标明出处,原文地址:http://www.cnblogs.com/MobileBo/p/3923599.html
三、结果分析
1、边缘提取作用
有人提出cvAdaptiveThreshold的作用不是二值化而是提取对象边缘的观点
参考文献:http://wuyiwangyi.blog.163.com/blog/static/3214949520093834537412/
关键是里面的block_size参数,该参数是决定局部阈值的block的大小,当block很小时,如block_size=3 or 5 or 7时,“自适应”的程度很高,即容易出现block里面的像素值都差不多,这样便无法二值化,而只能在边缘等梯度大的地方实现二值化,结果显得它是边缘提取函数。当把block_size设为比较大的值时,如block_size=21 or 31 or 41时,cvAdaptiveThreshold便是二值化函数啦~
2、block_size取值问题
编程过程中,发现block_size一般取奇数,如果取偶数会报错,错误内容是"blockSize % 2 == 1 && blockSize > 1"。当然,编程文档说明提示是3,5,7,...,并没有要求是奇数,是这种算法在原理上就要这么要求吗?还是编程需要?我无法解答。
网上说源代码要求就是 if( size <= 1 || (size&1) == 0 )
CV_ERROR( CV_StsOutOfRange, "Neighborhood size must be >=3 and odd (3, 5, 7, ...)" );
个人感觉是图像处理算法本身导致的,与编程无关。
原文:http://www.cnblogs.com/MobileBo/p/3923599.html
【转】Emgu CV on C# (五) —— Emgu CV on 局部自适应阈值二值化的更多相关文章
- [转载+原创]Emgu CV on C# (五) —— Emgu CV on 局部自适应阈值二值化
局部自适应阈值二值化 相对全局阈值二值化,自然就有局部自适应阈值二值化,本文利用Emgu CV实现局部自适应阈值二值化算法,并通过调节block大小,实现图像的边缘检测. 一.理论概述(转载自< ...
- [转载+原创]Emgu CV on C# (四) —— Emgu CV on 全局固定阈值二值化
重点介绍了全局二值化原理及数学实现,并利用emgucv方法编程实现. 一.理论概述(转载,如果懂图像处理,可以略过,仅用作科普,或者写文章凑字数) 1.概述 图像二值化是图像处理中的一项基本技术,也 ...
- 机器学习实战基础(十二):sklearn中的数据预处理和特征工程(五) 数据预处理 Preprocessing & Impute 之 处理分类特征:处理连续性特征 二值化与分段
处理连续性特征 二值化与分段 sklearn.preprocessing.Binarizer根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量.大于阈值的值映射为1,而小于或等于阈值的值 ...
- 【opencv】cv::Mat转std::vector<cv::Point2d> (注意两容器中数据类型的一致性)
获取cv::Mat大小: mymat.size() 获取cv::Mat指定位置的值:需指定数据类型,且注意数据类型应与存入时的数据类型一致,否则会导致不抛出异常的数据错误 mymat.at<,i ...
- 超越OpenCV速度的MorphologyEx函数实现(特别是对于二值图,速度是CV的4倍左右)。
最近研究了一下opencv的 MorphologyEx这个函数的替代功能, 他主要的特点是支持任意形状的腐蚀膨胀,对于灰度图,速度基本和CV的一致,但是 CV没有针对二值图做特殊处理,因此,这个函数对 ...
- 【Visual C++】游戏开发五十六 浅墨DirectX教程二十三 打造游戏GUI界面(一)
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/16384009 作者:毛星云 ...
- Emgu学习之(五)——图像模糊处理
Visual Studio Community 2015 工程和代码:http://pan.baidu.com/s/1Qia0Q 内容 在这篇文章中将提到以下内容: 中值模糊 高斯模糊 图像模糊能有效 ...
- HTML5+JS 《五子飞》游戏实现(二)路线分析和资源准备
上一节 里沃特与我们分享了<五子飞>的下棋规则,可能有些伙伴看得不清楚,像我们码农还是看到代码比较靠谱.下面就把可以走棋的路线跟大家说一下. 假设从左上角开始,以0开始编号,往右数(没看第 ...
- 第十五章:Python の Web开发基础 (二) JavaScript与DOM
本課主題 JavaScript 介绍 DOM 介绍 JavaScript 介绍 JavaScript 是一门编程语言,它可以让网页动起来的,JavaScript 的变量有两种,一个是局部变量:一个是全 ...
随机推荐
- JavaScript日期(参考资料)
构造函数1.new Date() 如果没有参数,则Date的构造器会依据系统设置的当前时间来创建一个Date对象.2.new Date(value) value代表自1970年1月1日00:00:00 ...
- ES6——Class 的基本使用
Class 语法. class 关键字声明一个类,之后以这个类来实例化对象. const Miaov=function(a,b){ this.a=a; this.b=b; return this; } ...
- C# print pos winform
先将pos机设置为默认 控制面板->打印机和传真->右键->服务器属性 首先创建 ClassPrint 对象 using System; using System.Drawing; ...
- @ManyToOne和@OneToMany 注解
(1)ManyToOne(多对一)单向:不产生中间表,但可以用@Joincolumn(name=" ")来指定生成外键的名字,外键在多的一方表中产生! (2)OneToMany( ...
- Android : 按 Back 按钮不返回处于后台的 Activity
在一个项目中,我有一种情况下启动一个新 Activity 后,按 Back 按钮时不想返回到后台的 Activity. 具体方法是, 在启动新的 Activity 的时候: Intent intent ...
- GO学习笔记 - map
map是GO语言中的一种高级数据类型,特点是key和value对应,这和Delphi中的Dictionary一样!map的声明格式:map[key数据类型]value数据类型.使用map前,必须用ma ...
- docker安装配置
########################################## #docker安装配置 #环境centos7 #配置docker阿里源 echo '#Docker [docker ...
- BZOJ 1934--善意的投票(最小割)
1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 2354 Solved: 1471[Submit][ ...
- wamp集成多个版本php (php7.0)
https://www.cnblogs.com/ypf5208/p/5510274.html
- 8102 年的现代 Web 开发最佳实践(笑)
简评:8102 年了,现在 web 开发的最佳实践是什么,让本文来告诉你.原文只提到一部分,可以查看 reddit 上对此文的评论查看补充的最佳实践 https://old.reddit.com/r/ ...