数字图像处理(10): OpenCV 图像阈值化处理_binarization threshold-程序员宅基地

技术标签: Python 学习笔记  Python图像处理  数字图像处理  数字图像处理专栏  阈值处理  Python  

目录

1 什么是阈值化- threshold()

2 二进制阈值化

3 反二进制阈值化

4 截断阈值化

5 反阈值化为0

6 阈值化为0

7 小结

参考资料


1 什么是阈值化- threshold()

图像的二值化或阈值化 (Binarization) 旨在提取图像中的目标物体,将背景以及噪声区分开来。通常会设定一个阈值 T,通过阈值 T 将图像的像素划分为两类:大于阈值 {\color{Red} T} 的像素群和小于阈值 {\color{Red} T} 的像素群。

灰度转换处理后的图像中,每个像素都只有一个灰度值,其大小表示明暗程度。二值化处理可以将图像中的像素划分为两类颜色,常用的二值化算法如下所示:

                                                                            \left\{ {\begin{array}{*{20}{c}} {Y = 0}&, \\ {Y = 255}&, \end{array}\begin{array}{*{20}{c}} {gray < T} \\ {gray > = T} \end{array}} \right.

其中,当灰度Gray小于阈值T时,其像素设置为0,表示黑色;

           当灰度Gray大于或等于阈值T时,其Y值为255,表示白色。

Python OpenCV中提供了阈值函数 threshold() 实现二值化处理,其函数形式及参数如下图所示:

retval, dst = cv2.threshold(src, thresh, maxval, type)

其中,参数:

retval:阈值        

dst: 处理结果

src,:原图像

thresh:阈值

maxval:最大值

type:类

 

常用的方法如下表所示,其中函数中的参数Gray表示灰度图,参数127表示对像素值进行分类的阈值,参数255表示像素值高于阈值时应该被赋予的新像素值,最后一个参数对应不同的阈值处理方法。

 

对应OpenCV提供的五张图如下所示,第一张为原图,后面依次为:

二进制阈值化反二进制阈值化截断阈值化反阈值化为0 和 阈值化为0

 

二值化处理广泛应用于各行各业,比如生物学中的细胞图分割、交通领域的车牌设别等。在文化应用领域中,通过二值化处理将所需民族文物图像转换为黑白两色图,从而为后面的图像识别提供更好的支撑作用。下图表示图像经过各种二值化处理算法后的结果,其中“BINARY”是最常见的黑白两色处理。下面将依次对5种阈值化处理方法进行介绍以及实验对比。


 

2 二进制阈值化

二进制阈值化方法先要选定一个特定的阈值量,比如127。新的阈值产生规则如下:

                                                             dst(x,y) = \left\{ {\begin{array}{*{20}{c}} {\max Val}&,\\ 0&, \end{array}\begin{array}{*{20}{c}} {if{\rm{ }}src(x,y) > thresh}\\ {otherwise} \end{array}} \right.

(1) 大于等于127的像素点的灰度值设定为最大值(如8位灰度值最大为255);

(2) 灰度值小于127的像素点的灰度值设定为0 ;

例如,163->255,86->0,102->0,201->255

使用关键字为:cv2.THRESH_BINARY

例如:r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_BINARY)

 

代码如下:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)

#灰度图像处理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#二进制阈值化处理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_BINARY)
print (r)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:(R, B两个通道均使用了阈值处理


 

3 反二进制阈值化

反二进制阈值化方法与二进制阈值化方法相似,先要选定一个特定的灰度值作为阈值,比如127。新的阈值产生规则如下公式所示:

                                                           dst(x,y) = \left\{ {\begin{array}{*{20}{c}} 0&,\\ {\max Val}&, \end{array}\begin{array}{*{20}{c}} {if{\rm{ }}src(x,y) > thresh}\\ {otherwise} \end{array}} \right.

(1) 大于127的像素点的灰度值设定为0(以8位灰度图为例);

(2) 小于该阈值的灰度值设定为255;

例如,163->0,86->255,102->255,201->0。

使用关键字为: cv2.THRESH_BINARY_INV

例如:r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_BINARY_INV)

 

代码如下:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)

#灰度图像处理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#反二进制阈值化处理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_BINARY_INV)
print (r)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:


 

4 截断阈值化

截断阈值化方法需要选定一个阈值,图像中大于该阈值的像素点被设定为该阈值,小于该阈值的保持不变,比如127。新的阈值产生规则如下:

                                                          dst(x,y) = \left\{ {\begin{array}{*{20}{c}} {threshold}&,\\ {src(x,y)}&, \end{array}\begin{array}{*{20}{c}} {if{\rm{ }}src(x,y) > thresh}\\ {otherwise} \end{array}} \right.

(1) 大于等于127的像素点的灰度值设定为该阈值127;

(2) 小于该阈值的灰度值不改变;

例如,163->127,86->86,102->102,201->127。

使用关键字为: cv2.THRESH_TRUNC

例如:r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TRUNC)

 

代码如下:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)

#灰度图像处理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#截断阈值化处理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TRUNC)
print (r)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:[ 该处理方法相当于把图像中比较亮(大于127,偏向于白色)的像素值处理为阈值。]


 

5 反阈值化为0

反阈值化为0 方法先选定一个阈值,比如127,接着对图像的灰度值进行如下处理:

                                                           dst(x,y) = \left\{ {\begin{array}{*{20}{c}} 0&,\\ {src(x,y)}&, \end{array}\begin{array}{*{20}{c}} {if{\rm{ }}src(x,y) > thresh}\\ {otherwise} \end{array}} \right.

(1) 大于等于阈值127的像素点变为0 ;

(2) 小于该阈值的像素点值保持不变;

例如,163->0,86->86,102->102,201->0。

使用关键字为: cv2.THRESH_TOZERO_INV 

例如:r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TOZERO_INV)

 

代码如下:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)

#灰度图像处理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#反阈值化为0处理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TOZERO_INV)
print (r)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:


 

6 阈值化为0

阈值化为0 方法先选定一个阈值,比如127,接着对图像的灰度值进行如下处理:

                                                         dst(x,y) = \left\{ {\begin{array}{*{20}{c}} {src(x,y)}&,\\ 0&, \end{array}\begin{array}{*{20}{c}} {if{\rm{ }}src(x,y) > thresh}\\ {otherwise} \end{array}} \right.

 

(1) 大于等于阈值127的像素点,值保持不变;

(2) 小于该阈值的像素点值设置为0 ;

例如,163->163,86->0,102->0,201->201。

使用关键字为: cv2.THRESH_TOZERO

例如:r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TOZERO)

 

代码如下:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)

#灰度图像处理
GrayImage = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

#阈值化为0处理
r, b = cv2.threshold(GrayImage, 127, 255, cv2.THRESH_TOZERO)
print (r)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", b)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:(该方法把比较亮的部分不变,比较暗的部分处理为0。)


 

7 小结

把上面提及的五种阈值处理方法(二进制阈值化反二进制阈值化截断阈值化反阈值化为0 和 阈值化为0)放在一起进行对比

代码如下所示:(注意一个窗口多张图像的用法

#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt

#读取图像
img = cv2.imread("zxp.jpg", cv2.IMREAD_UNCHANGED)
lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
GrayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#阈值化处理
ret,thresh1=cv2.threshold(GrayImage,127,255,cv2.THRESH_BINARY)
ret,thresh2=cv2.threshold(GrayImage,127,255,cv2.THRESH_BINARY_INV)
ret,thresh3=cv2.threshold(GrayImage,127,255,cv2.THRESH_TRUNC)
ret,thresh4=cv2.threshold(GrayImage,127,255,cv2.THRESH_TOZERO)
ret,thresh5=cv2.threshold(GrayImage,127,255,cv2.THRESH_TOZERO_INV)

#显示结果
titles = ['Gray Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [GrayImage, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
   plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
   plt.title(titles[i])
   plt.xticks([]),plt.yticks([])
plt.show()

 

运行结果如下所示:(注意一个窗口多张图像的用法


 

参考资料

[1] https://blog.csdn.net/Eastmount/article/details/83548652

[2] Python+OpenCV图像处理

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zaishuiyifangxym/article/details/89556318

智能推荐

使用nginx解决浏览器跨域问题_nginx不停的xhr-程序员宅基地

文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr

在 Oracle 中配置 extproc 以访问 ST_Geometry-程序员宅基地

文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc

Linux C++ gbk转为utf-8_linux c++ gbk->utf8-程序员宅基地

文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8

IMP-00009: 导出文件异常结束-程序员宅基地

文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束

python程序员需要深入掌握的技能_Python用数据说明程序员需要掌握的技能-程序员宅基地

文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求

Spring @Service生成bean名称的规则(当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致)_@service beanname-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname

随便推点

二叉树的各种创建方法_二叉树的建立-程序员宅基地

文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include&lt;stdio.h&gt;#include&lt;string.h&gt;#include&lt;stdlib.h&gt;#include&lt;malloc.h&gt;#include&lt;iostream&gt;#include&lt;stack&gt;#include&lt;queue&gt;using namespace std;typed_二叉树的建立

解决asp.net导出excel时中文文件名乱码_asp.net utf8 导出中文字符乱码-程序员宅基地

文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码

笔记-编译原理-实验一-词法分析器设计_对pl/0作以下修改扩充。增加单词-程序员宅基地

文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词

android adb shell 权限,android adb shell权限被拒绝-程序员宅基地

文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限

投影仪-相机标定_相机-投影仪标定-程序员宅基地

文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定

Wayland架构、渲染、硬件支持-程序员宅基地

文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland

推荐文章

热门文章

相关标签