【转】Emgu 图像阈值
原文地址:http://www.cnblogs.com/CoverCat/p/5043833.html
转载,备查
Visual Studio Community 2015 工程和代码:http://pan.baidu.com/s/1o7lxYSM
内容
在这篇文章中将提到以下内容:
- 全局阈值
- 自适应阈值
- Otsu's二值化
在图像处理中,会希望忽略掉一些灰度细节,只保留主体的轮廓,对灰度图像进行阈值化处理能达到这个目的。
“其基本的思想是,给定一个数组和一个阈值,然后根据数组中的每个元素的值是低于还是高于阈值而进行一些处理”——《学习OpenCV(中文版)》,这里说的“数组”即为图像数据,
而“进行一些处理”说的是进行分类,只有两类,根据值不同分到不同的类中。
准备工作
- 创建工程——参考Emgu学习之(一)——Emgu介绍创建一个名为“Threshold”WinForm项目
- 在Form1.cs中引用命名空间:
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
- 界面:在Form1中添加1行2列的TableLayoutPanel容器,然后添加2个Emgu.CV.UI.ImageBox控件(参考Emgu学习之(二)——图像读取、显示、保存),添加后界面如下:

- 设置imageBox1和imageBox2的SizeMode属性为StretchImage
全局阈值
全局阈值指的是整个图像数据使用一个阈值进行筛选分类,OpenCV提供cvThreshold()方法进行阈值化操作,在Emgu中对应的方法名称为Threshold。
Threshold方法接受一个类型为ThresholdType的参数,ThresholdType是一个枚举类型,其枚举值为:
Binary = ,
BinaryInv = ,
Trunc = ,
ToZero = ,
ToZeroInv = ,
Mask = ,//这里不做介绍
Otsu = //后面会做介绍
- Binary(二进制阈值化)——二进制阈值化是指将大于阀值的像素点设置为最大值,而小于阀值的像素点设置为0,即:
value = value > threshold ? max_value : 0

- BinaryInv(反向二进制阈值化)——与二进制阈值化正好相反,反向二进制阈值化是在像素点的值大于阀值时像素点设置为0,反之则设置为最大值,即:
value = value > threshold ? 0 : max_value

- Trunc(截断阈值化)——截断阈值化是指当像素点的值大于阀值时,像素点的值设置为阀值,反之则保留像素值本身,即:
value = value > threshold ? threshold : value

- ToZero(超阈值归零化)——超阈值归零化是指当像素点的值大于阀值时,像素点保留原值,反之则设置为0,即:
value = value > threshold ? value : 0

- ToZeroINV(低于阈值归零化)——与超阈值归零化相反,低于阈值归零化是指当像素点的值大于阀值时,像素点值被设置为0,反之则保留像素点原值,即:
value = value > threshold ? 0 : value

从上边描述我们可以看出二进制阈值化/反二进制阈值化需要一个max_value(最大值)的参数,同时,二进制阈值化/反二进制阈值化处理后图像数据中只存在两种
可能的值:0和max_value,这种图像称为二值化图像。
“在数字图像处理中,二值图像占有非常重要的地位,首先,图像的二值化有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮
廓。其次,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像。所有灰度大于或等于阈值的像素被判定为属于特定物体,其灰度值为255表示,
否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。”——百度百科
下面的代码显示了如何使用二进制阈值化处理,如果你要使用不是二进制阈值化处理,那么max_value可以不用在意设什么值。
{
using (var image = new Image<Bgr, Byte>(Properties.Resources.chess3))
{
var grayImage = image.Convert<Gray, Byte>();//转为灰度图
var threshImage = grayImage.CopyBlank();
CvInvoke.Threshold(
grayImage,
threshImage,
, //阀值
, //最大值
ThresholdType.Binary);//二进制阈值化
imageBox1.Image = grayImage;
imageBox2.Image = threshImage;
}
}
效果如下: Binary -> BinaryInv -> Trunc -> ToZero -> ToZeroInv

自适应阈值
全局阈值是整幅图像使用一个阀值,这并不能适应所有的情况。自适应阈值是图像的不同的区域使用不同的阀值,而阀值是对这个区域计算得来的,OpenCV提供cvAdaptiveThreshold()
函数进行自适应阈值化处理,这个函数提供两种计算阀值的方法,分别为CV_ADAPTIVE_THRESH_MEAN_C和CV_ADAPTIVE_THRESH_GAUSSIAN_C。
“在这两种情况下,自适应阈值T(x,y)在每个像素点都不同。通过计算像素点周围的b x b区域的加权平均,然后减去一个常数来得到自适应阈值, b有参数block_size指定,常数有param1
指定。如果使用CV_ADAPTIVE_THRESH_MEAN_C方法,那么对区域的所有像素平均加权。如果使用了CV_ADAPTIVE_THRESH_GAUSSIAN_C放,那么区域中的(x,y)周围的像素
根据高斯函数按照它们离中心点的距离进行加权计算。”——《学习OpenCV(中文版)》
Emgu中CVInvoke类提供了AdaptiveThreshold静态方法进行自适应阈值处理,这个方法的原型为:
public static void AdaptiveThreshold(
IInputArray src, //原图像
IOutputArray dst, //结果图像
double maxValue, //二进制阈值化/反二进制阈值化处理使用到的最大值
CvEnum.AdaptiveThresholdType adaptiveType, // 自适应阈值计算方式:MeanC或GaussianC
CvEnum.ThresholdType thresholdType, //阈值化方式,必须为二进制阈值化和反二进制阈值化之一(Binary / BinaryInv)
int blockSize, //计算使用的区域矩阵大小:3,5,7,9...
double param1) //常数
同时,Image类也提供了一个封装了AdaptiveThreshold方法的ThresholdAdaptive方法,下面的代码中使用的几位Image类的ThresholdAdaptive方法:
private void Form1_Load(object sender, EventArgs e)
{
var grayImage = new Image<Gray, Byte>(Properties.Resources.chess3);
//CvInvoke.AdaptiveThreshold(grayImage, threshImage, 255, AdaptiveThresholdType.GaussianC, ThresholdType.BinaryInv, 12, 5);
var threshImage = grayImage.ThresholdAdaptive(
new Gray(),
AdaptiveThresholdType.MeanC,
ThresholdType.Binary,
,
new Gray()); imageBox1.Image = grayImage;
imageBox2.Image = threshImage;
}
执行效果为:MeanC -> GaussianC

Otsu二值化
在全局阈值的代码中,我们使用150作为二进制阈值化的阀值,但是这个阀值是我随意选择的,我并不确定这个阀值是否是合适的阈值。而如果使用Otsu二值化方法,它可以根据
图像的直方图计算出一个阀值。使用Otsu方法用到的是全局阈值提到过的Threshold方法,只是在传入的ThresholdType值为Otsu,代码如下:
var grayImage = new Image<Gray, Byte>(Properties.Resources.chess3);
var threshImage = grayImage.CopyBlank();
CvInvoke.Threshold(
grayImage,
threshImage,
,
,
ThresholdType.Otsu); imageBox1.Image = grayImage;
imageBox2.Image = threshImage;
运行效果:

【转】Emgu 图像阈值的更多相关文章
- opencv学习之路(13)、图像阈值化threshold
一.图像阈值化简介 二.固定阈值 三.自适应阈值 #include<opencv2/opencv.hpp> using namespace cv; void main(){ Mat src ...
- [python-opencv]图像二值化【图像阈值】
图像二值化[图像阈值]简介: 如果灰度图像的像素值大于阈值,则为其分配一个值(可以是白色255),否则为其分配另一个值(可以是黑色0) 图像二值化就是将灰度图像上的像素值设置为0或255,也就是将整个 ...
- Emgu学习之(四)——图像阈值
http://www.cnblogs.com/CoverCat/p/5043833.html Visual Studio Community 2015 工程和代码:http://pan.baidu.c ...
- opencv2函数学习之threshold:实现图像阈值化
在opencv2中,threshold函数可以进行阈值化操作. double threshold( const Mat& src, Mat& dst, double thresh,do ...
- 图像阈值化-threshold、adaptivethreshold
在图像处理中阈值化操作,从一副图像中利用阈值分割出我们需要的物体部分(当然这里的物体可以是一部分或者整体).这样的图像分割方法是基于图像中物体与背景之间的灰度差异,而且此分割属于像素级的分割.open ...
- opencv之图像阈值化处理
一.函数简介 1.threshold-图像简单阈值化处理 函数原型:threshold(src, thresh, maxval, type, dst=None) src:图像矩阵 thresh:阈值 ...
- opencv图像阈值操作
使用threshold方法和adaptivethreshold方法对图像进行阈值分割操作. 1.使用threshold方法,设置一个阈值,将大于阈值的值变换为最大值,小于阈值的值变换为0. #-*- ...
- OpenCV学习笔记(7)——图像阈值
简单阈值,自适应阈值,Otsu's二值化等 1.简单阈值 当像素值高于阈值时,我们给这个像素赋予一个新值,否则给他赋予另一个值.这个函数就是cv2.threshhold().这个函数的第一个参数就是原 ...
- 读《Adaptive Thresholding Using the Integral Image》自适应图像阈值
图像的二值化问题总是一个问题.虽然使用深度学习的方法取得了不小的进展,但是传统的方法还是值得借鉴. 刚好随机游走到这篇文章 挖个07年的坟 地址:http://people.scs.carleton ...
随机推荐
- 【Spring】26、利用Spring的AbstractRoutingDataSource解决多数据源,读写分离问题
多数据源问题很常见,例如读写分离数据库配置. 1.首先配置多个datasource <bean id="dataSource" class="org.apache. ...
- Kite(几何+镜面对称)
C. Kite Time Limit: 1000ms Case Time Limit: 1000ms Memory Limit: 65536KB Vova bought a kite co ...
- Starting zookeeper ... already running as process 1805错误
启动zookeeper的时候,报Starting zookeeper ... already running as process 1805错误 上面这个错误意思为以作为进程1805运行.系统检测到你 ...
- Python简单的网络编程
OSI 模型介绍 应用层 -- 对接受的数据进行解释.加密与解密.压缩与解压缩 会话层 -- 通过传输层(端口号: 传输端口和接受端口) 建立数据传输的通路 传输层 -- 定义了一些传输数据的协议和端 ...
- 【读书笔记】iOS-后台运行模式
苹果在关于后台模式的文档中称:“这个配置项应该尽可能少的使用,而且最好只给那些提供通知服务的应用使用.如果有在后台运行的替代方法,就应该使用替代方法.比如,如果应用能使用显著位置变化接口来接受位置变动 ...
- 移动端reset
* { margin: 0; padding: 0;}article, aside, details, figcaption, figure, footer, header, hgroup, main ...
- Salesforce的报表和仪表板
报表是现代企业中最常用到的功能之一.Salesforce中提供了强大的报表和仪表板功能. 报表和仪表板简介 报表是一组数据展示,用户可以自定义规则,只有符合相应规则的数据才会显示出来. Salesfo ...
- Linux 改动inittab文件及忘记密码等导致无法进入系统的解决办法
改动inittab文件及忘记密码等导致无法进入系统的解决办法[摘] by:授客 QQ:1033553122 inittab是linux的系统启动模式配置文件,在”/etc“文件目录下没,其内容是: # ...
- (后端)java回调机制
转自强哥: 所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调用C中的某个函数B,对于C来说,这个B便叫做回调函数.例如Win32下的窗口过程函数就是一个典型的回调函数. ...
- JQuery实战中遇到的两个小问题$(document).ready() 、bind函数的参数传递问题
一.$(document).ready() 与 window.onload的区别 1.执行时间 window.onload 必须等到页面内所有元素(包括图片 css js等)加载完毕后才会执行. $( ...