图像二值化

简介

图像二值化( Image Binarization)就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。

原理

图像的二值化处理就是将图像上的点的灰度值为0或255,也就是将整个图像呈现出明显的黑白效果。即将256个亮度等级的灰度图像通过适当的阈值选取而获得仍然可以反映图像整体和局部特征的二值化图像。在数字图像处理中,二值图像占有非常重要的地位,特别是在实用的图像处理中,以二值图像处理实现而构成的系统是很多的,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像,这样子有利于在对图像做进一步处理时,图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值,使处理变得简单,而且数据的处理和压缩量小。为了得到理想的二值图像,一般采用封闭、连通的边界定义不交叠的区域。所有灰度大于或等于阈值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。 如果某特定物体在内部有均匀一致的灰度值,并且其处在一个具有其他等级灰度值的均匀背景下,使用阈值法就可以得到比较的分割效果。如果物体同背景的差别表现不在灰度值上(比如纹理不同),可以将这个差别特征转换为灰度的差别,然后利用阈值选取技术来分割该图像。动态调节阈值实现图像的二值化可动态观察其分割图像的具体结果。

API

全局阈值化:threshold

public static double threshold(Mat src, Mat dst, double thresh, double maxval, int type)

  • 参数一:src,待二值化的多通道图像,只能是CV_8U和CV_32F两种数据类型
  • 参数二:dst,二值化后的图像,与输入图像具有相同的尺寸、类型和通道数
  • 参数三:thresh,二值化的阈值
  • 参数四:maxval,二值化过程的最大值,此函数只在THRESH_BINARY和THRESH_BINARY_INV两种二值化方法中才使用
  • 参数五:type,二值化类型

二值化类型

// C++: enum ThresholdTypes
public static final intTHRESH_BINARY = 0,THRESH_BINARY_INV = 1,THRESH_TRUNC = 2,THRESH_TOZERO = 3,THRESH_TOZERO_INV = 4,THRESH_MASK = 7,THRESH_OTSU = 8,THRESH_TRIANGLE = 16;

bledata-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="normal">

THRESH_OTSU和THRESH_TRIANGLE

这两种标志是获取阈值的方法,并不是阈值的比较方法的标志,这两个标志可以和前面5种标志一起使用,例如“THRESH_BINARY| THRESH_OTSU”。前面5种标志在调用函数时都需要人为的设置阈值,如果对图像不了解设置的阈值不合理,会对处理后的效果造成严重的影响,这两个标志分别表示利用大津法(OTSU)和三角形法(TRIANGLE)结合图像灰度值分布特性获取二值化的阈值,并将阈值以函数返回值的形式给出。因此如果函数最后一个参数设置了这两个标志中的任何一个,那么函数第三个参数thresh将由系统自动给出,但是在调用函数的时候仍然不能缺省,只是程序不会使用这个数值。目前,只有针对CV_8UC1图像可使用这两种标志位。

大津法(OTSU):最适用于双波峰

大津法又叫最大类间方差法、最大类间阈值法(OTSU)。它的基本思想是,用一个阈值将图像中的数据分为两类,一类中图像的像素点的灰度均小于这个阈值,另一类中的图像的像素点的灰度均大于或者等于该阈值。如果这两个类中像素点的灰度的方差越大,说明获取到的阈值就是最佳的阈值(方差是灰度分布均匀性的一种度量,背景和前景之间的类间方差越大,说明构成图像的两部分的差别越大,当部分前景错分为背景或部分背景错分为前景都会导致两部分差别变小。因此,使类间方差最大的分割意味着错分概率最小。)。则利用该阈值可以将图像分为前景和背景两个部分。而我们所感兴趣的部分一般为前景。

三角形法(TRIANGLE):最适用于单个波峰,最开始用于医学分割细胞等

三角法求阈值最早见于Zack的论文《Automatic measurement of sister chromatid exchange frequency》主要是用于染色体的研究,该方法是使用直方图数据,基于纯几何方法来寻找最佳阈值,它的成立条件是假设直方图最大波峰在靠近最亮的一侧,然后通过三角形求得最大直线距离,根据最大直线距离对应的直方图灰度等级即为分割阈值,图示如下:

在直方图上从最高峰处bmx到最暗对应直方图bmin(p=0)%构造一条直线,从bmin处开始计算每个对应的直方图b到直线的垂直距离,知道bmax为止,其中最大距离对应的直方图位置即为图像二值化对应的阈值T。
有时候最大波峰对应位置不在直方图最亮一侧,而在暗的一侧,这样就需要翻转直方图,翻转之后求得值,用255减去即得到为阈值T。扩展情况的直方图表示如下:

算法步骤

  1. 图像转灰度
  2. 计算图像灰度直方图
  3. 寻找直方图中两侧边界
  4. 寻找直方图最大值
  5. 检测是否最大波峰在亮的一侧,否则翻转
  6. 计算阈值得到阈值T,如果翻转则255-T

局部阈值化:adaptiveThreshold

局部自适应阈值是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。这样做的好处在于每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。亮度较高的图像区域的二值化阈值通常会较高,而亮度较低的图像区域的二值化阈值则会相适应地变小。不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。

public static void adaptiveThreshold(Mat src, Mat dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C)

  • 参数一:src,待二值化的图像,图像只能是CV_8UC1数据类型
  • 参数二:dst,二值化后的图像,与输入图像具有相同的尺寸、类型
  • 参数三:maxValue,二值化的最大值
  • 参数四:adaptiveMethod,自适应阈值算法,分为均值法ADAPTIVE_THRESH_MEAN_C和高斯法ADAPTIVE_THRESH_GAUSSIAN_C这两种。
  • 参数五:thresholdType,选择图像二值化方法的标志,只能是THRESH_BINARY和THRESH_BINARY_INV
  • 参数六:blockSize,自适应确定阈值的像素邻域大小,一般为3,5,7的奇数
  • 参数七:C,从平均值或者加权平均值中减去的常数,可以为正,也可以为负

自适应阈值算法

// C++: enum AdaptiveThresholdTypes
public static final intADAPTIVE_THRESH_MEAN_C = 0,ADAPTIVE_THRESH_GAUSSIAN_C = 1;

bledata-draft-node="block" data-draft-type="table" data-size="normal" data-row-style="normal">

操作

private fun threshold(type: Int) {val ret = Mat()Imgproc.threshold(mGray, ret, 127.toDouble(), 255.toDouble(), type)showMat(ret)title = getTypeName(type)
}private fun adaptiveMean() {val ret = Mat()Imgproc.adaptiveThreshold(mGray,ret,255.toDouble(),Imgproc.ADAPTIVE_THRESH_MEAN_C,Imgproc.THRESH_BINARY,55,0.0)showMat(ret)title = "ADAPTIVE_THRESH_MEAN_C"
}

结果

源码

onlyloveyd/LearningAndroidOpenCV​github.com

扫码关注

二值化图像的欧拉数_Android OpenCV(八):图像二值化相关推荐

  1. matlab中的中值滤波medfilt2()和opencv中的中值滤波medianblur()是不同的

    matlab中的中值滤波medfilt2()和opencv中的中值滤波medianblur()做出的结果不同,如图所示: Opencv处理结果如下: Matlab处理结果如下: Opencv处理过程中 ...

  2. pythonopencv读取图像属性_2、OpenCV Python 图像属性获取

    __author__ = "WSX" import cv2 as cv import numpy as np image = cv.imread("1.JPG" ...

  3. 4.3【图像镜像】-------------基于Opencv实现-----图像的镜像变换

     [1]理论知识:         镜像变换又分为水平镜像和垂直镜像,水平镜像即将图像左半部分和右半部分以图像竖直中轴线为中心轴进行兑换,而竖直镜像则是将图像上半部分和下半部分以图像水平中轴线为中 ...

  4. python图像融合算法_Python OpenCV 实现图像融合

    原标题:Python OpenCV 实现图像融合 来自:https://www.linuxmi.com/python-opencv-image-blending.html 在本文中,我们将讨论Pyth ...

  5. python opencv 图像切割_Python 使用 OpenCV 进行图像神经风格迁移

    Neural Style Transfer with OpenCV src: https://www. pyimagesearch.com/2018/ 08/27/neural-style-trans ...

  6. python 图像无缝拼接_Python+OpenCV实现图像的全景拼接的代码

    环境:python3.5.2 + openCV3.4 1.算法目的 将两张相同场景的场景图片进行全景拼接. 2.算法步骤 本算法基本步骤有以下几步: 步骤1:将图形先进行桶形矫正 没有进行桶形变换的图 ...

  7. 8.openCV 裁剪图像

    8.openCV 裁剪图像 一.使用 OpenCV 裁剪图像 二.项目结构和代码讲解 1.项目结构 2.代码讲解 三.代码下载 一.使用 OpenCV 裁剪图像 在本教程的第一部分,我们将讨论如何将 ...

  8. 基于Opencv的图像卡通化

    基于Opencv的图像卡通化 基于Opencv的图像卡通化 铅笔素描效果 国画效果 抽象效果 基于Opencv的图像卡通化 主要工具是高斯滤波器.细节增强滤波器.双边滤波.拉普拉斯滤波器. 铅笔素描效 ...

  9. OpenCV扫描图像对象的实例(附完整代码)

    OpenCV扫描图像对象的实例 OpenCV扫描图像对象的实例 OpenCV扫描图像对象的实例 #include <opencv2/core.hpp> #include <openc ...

最新文章

  1. java 定义变量时 赋值与不赋值_探究Java中基本类型和部分包装类在声明变量时不赋值的情况下java给他们的默认赋值...
  2. 下载 嵌入式qt实战教程pdf_Qt之JSON教程-实战篇
  3. ubuntu下使用openocd+jlink进行STM32开发调试
  4. ResultSet转换为List的方法
  5. 分析日志下载时间脚本
  6. 嵌入式系——软件管理工程
  7. 使用docker部署skywalking
  8. 华为C语言编程规范(精华总结)
  9. 【模电】0013 反馈放大电路基础
  10. 来看一看 Google 给你的标签是什么
  11. Python操作MyS QL
  12. Java基础教程:dubbo源码解析-服务暴露与发现
  13. java-net-php-python-jsp学生社团信息演示录像2019计算机毕业设计程序
  14. 【C语言】—— qsort()函数的使用
  15. 机器视觉与图像处理研究必备
  16. 基于BLG7289的数码管显示
  17. 中国动物疫病诊断试剂行业研究与投资前景报告(2022版)
  18. 暗夜精灵3060配cuda11.3+pytorch1.10.2
  19. 印度狂妄,华为和中兴在印度5G设备市场面临不确定性,三星却已占领市场
  20. UG模具设计讲述模具常见问题描叙

热门文章

  1. 不同坐标系下角速度_技术 | 西安80坐标与地方坐标系的转换方法技巧
  2. 2.5 指数加权平均的偏差修正-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授
  3. keil 多文件组织方法
  4. 【viterbi维特比译码】卷积码为(2,1,7)标准卷积码和维特比译码的FPGA实现
  5. matlab-画个拱桥和倒影?
  6. 一个基于Node.js的本地快速测试服务器
  7. Android Message解析
  8. Hive 和普通关系数据库的异同
  9. Android-Material-Examples
  10. Node.js笔记 - 修改文件后自动重启node服务