第六节:阈值分割

一: 全阈值分割

实例代码:

image = cv2.imread('img.jpg', cv2.IMREAD_GRAYSCALE)

the = 100 # 设置阈值为100

maxval = 255

dst, img = cv2.threshold(image, the, maxval, cv2.THRESH_BINARY)

cv2.imshow('hand_thresh', img)

cv2.waitKey(0)

cv2.destroyAllWindows()

给出你的阈值 ,然后告诉你的最大阈值是多少 。。。也就是你二值图中一个阈值为0,另外一个阈值可以指定为多少。。这里指定为255

看一下输出结果。。

二:局部阈值分割

局部阈值分割的核心是计算阈值矩阵。。比较常用的是后面提到的自适应阈值算法。。我们等会后面讲实现。。

三:直方图技术法

代码实现:

import numpy as np

import cv2

def calcGrayHist(image):

'''

统计像素值

:param image:

:return:

'''

# 灰度图像的高,宽

rows, cols = image.shape

# 存储灰度直方图

grayHist = np.zeros([256], np.uint64)

for r in range(rows):

for c in range(cols):

grayHist[image[r][c]] += 1

return grayHist

def threshTwoPeaks(image):

# 计算灰度直方图

histogram = calcGrayHist(image)

# 找到灰度直方图的最大峰值对应的灰度值

maxLoc = np.where(histogram == np.max(histogram))

firstPeak = maxLoc[0][0]

# 寻找灰度直方图的第二个峰值对应的灰度值

measureDists = np.zeros([256], np.float32)

for k in range(256):

measureDists[k] = pow(k - firstPeak, 2)*histogram[k]

maxLoc2 = np.where(measureDists == np.max(measureDists))

secondPeak = maxLoc2[0][0]

# 找两个峰值之间的最小值对应的灰度值,作为阈值

thresh = 0

if firstPeak > secondPeak:

temp = histogram[int(secondPeak): int(firstPeak)]

minLoc = np.where(temp == np.min(temp))

thresh = secondPeak + minLoc[0][0] + 1

else:

temp = histogram[int(firstPeak): int(secondPeak)]

minLoc = np.where(temp == np.min(temp))

thresh = firstPeak + minLoc[0][0] + 1

# 找到阈值,我们进行处理

img = image.copy()

img[img > thresh] = 255

img[img <= thresh] = 0

cv2.imshow('deal_image', img)

cv2.waitKey(0)

cv2.destroyAllWindows()

if __name__ == '__main__':

image = cv2.imread('img.jpg', cv2.IMREAD_GRAYSCALE)

threshTwoPeaks(image)

输出结果:

四:熵算法

代码实现:

import numpy as np

import cv2

import math

def calcGrayHist(image):

'''

统计像素值

:param image:

:return:

'''

# 灰度图像的高,宽

rows, cols = image.shape

# 存储灰度直方图

grayHist = np.zeros([256], np.uint64)

for r in range(rows):

for c in range(cols):

grayHist[image[r][c]] += 1

return grayHist

def threshEntroy(image):

rows, cols = image.shape

# 求灰度直方图

grayHist = calcGrayHist(image)

# 归一化灰度直方图,即概率直方图

normGrayHist = grayHist / float(rows*cols)

# 第一步:计算累加直方图,也称零阶累积矩

zeroCumuMoment = np.zeros([256], np.float32)

for k in range(256):

if k == 0:

zeroCumuMoment[k] = normGrayHist[k]

else:

zeroCumuMoment[k] = zeroCumuMoment[k-1] + normGrayHist[k]

# 第二步:计算各个灰度级的熵

entropy = np.zeros([256], np.float32)

for k in range(256):

if k == 0:

if normGrayHist[k] == 0:

entropy[k] = 0

else:

entropy[k] = -normGrayHist[k]*math.log10(normGrayHist[k])

else:

if normGrayHist[k] == 0:

entropy[k] = entropy[k-1]

else:

entropy[k] = entropy[k-1] - normGrayHist[k]*math.log10(normGrayHist[k])

# 第三步:找阈值

fT = np.zeros([256], np.float32)

ft1, ft2 = 0.0, 0.0

totalEntropy = entropy[255]

for k in range(255):

# 找最大值

maxFront = np.max(normGrayHist[0: k+1])

maxBack = np.max(normGrayHist[k+1: 256])

if (maxFront == 0 or zeroCumuMoment[k] == 0

or maxFront == 1 or zeroCumuMoment[k] == 1 or totalEntropy == 0):

ft1 = 0

else:

ft1 = entropy[k] / totalEntropy*(math.log10(zeroCumuMoment[k])/math.log10(maxFront))

if (maxBack == 0 or 1-zeroCumuMoment[k] == 0

or maxBack == 1 or 1-zeroCumuMoment[k] == 1):

ft2 = 0

else:

if totalEntropy == 0:

ft2 = (math.log10(1-zeroCumuMoment[k]) / math.log10(maxBack))

else:

ft2 = (1-entropy[k]/totalEntropy)*(math.log10(1-zeroCumuMoment[k])/math.log10(maxBack))

fT[k] = ft1 + ft2

# 找最大值的索引,作为得到的阈值

threshLoc = np.where(fT == np.max(fT))

thresh = threshLoc[0][0]

# 阈值处理

threshold = np.copy(image)

threshold[threshold > thresh] = 255

threshold[threshold <= thresh] = 0

return threshold

if __name__ == '__main__':

image = cv2.imread('img5.jpg', cv2.IMREAD_GRAYSCALE)

img = threshEntroy(image)

cv2.imshow('origin', image)

cv2.imshow('deal_image', img)

cv2.waitKey(0)

cv2.destroyAllWindows()

输出结果:

五:Otsu算法

这里就不具体实现了。。我们调用opencv给的API

image = cv2.imread('img.jpg', cv2.IMREAD_GRAYSCALE)

maxval = 255

otsuThe = 0

otsuThe, dst_Otsu = cv2.threshold(image, otsuThe, maxval, cv2.THRESH_OTSU)

cv2.imshow('Otsu', dst_Otsu)

cv2.waitKey(0)

cv2.destroyAllWindows()

输出结果:

六:自适应阈值算法

代码实现:

import cv2

import numpy as np

def adaptiveThresh(I, winSize, ratio=0.15):

# 第一步:对图像矩阵进行均值平滑

I_mean = cv2.boxFilter(I, cv2.CV_32FC1, winSize)

# 第二步:原图像矩阵与平滑结果做差

out = I - (1.0 - ratio) * I_mean

# 第三步:当差值大于或等于0时,输出值为255;反之,输出值为0

out[out >= 0] = 255

out[out < 0] = 0

out = out.astype(np.uint8)

return out

if __name__ == '__main__':

image = cv2.imread('img7.jpg', cv2.IMREAD_GRAYSCALE)

img = adaptiveThresh(image, (5, 5))

cv2.imshow('origin', image)

cv2.imshow('deal_image', img)

cv2.waitKey(0)

cv2.destroyAllWindows()

结果展示:

未完待续。。。。。。

下节你将能够学到一些形态学处理(腐蚀,膨胀等等)

最大熵阈值python_【6】python-opencv3教程:阈值分割(全阈值分割,局部阈值分割,直方图技术法,熵算法,自适应算法,Otsu算法)...相关推荐

  1. OpenCV —— 阈值分割(直方图技术法,熵算法,Otsu,自适应阈值算法)

    阈值分割 1. 全局阈值分割 直方图技术法 熵算法 Otsu算法 2. 局部阈值分割 自适应阈值 阈值的分割的核心就是如何选取阈值,选取正确的阈值时分割成功的关键.可以使用手动设置阈值,也可以采用直方 ...

  2. 面向小白的最全 Python 可视化教程,超全的!

    作者 | 俊欣 来源丨关于数据分析与可视化 今天小编总结归纳了若干个常用的可视化图表,并且通过调用plotly.matplotlib.altair.bokeh和seaborn等模块来分别绘制这些常用的 ...

  3. 【Python】面向小白的Python可视化教程,超全的!

    今天小编总结归纳了若干个常用的可视化图表,并且通过调用plotly.matplotlib.altair.bokeh和seaborn等模块来分别绘制这些常用的可视化图表,最后无论是绘制可视化的代码,还是 ...

  4. C#,图像二值化(24)——局部阈值算法的NiBlack算法及源程序

    1.局部阈值算法的NiBlack算法 摘要-医学图像的处理最为复杂人和计算机.磁性捐赠的脑组织共振成像(MRI)在许多领域是非常重要的问题例如手术和治疗.最常见的分割图像的最简单方法是使用阈值.在这项 ...

  5. 二维otsu算法python_【OpenCV+Python】图像阈值与OTSU算法

    图像阈值 自本教程开始,我们已经进入了图像处理的一些基本操作的学习,所谓的图像阈值,就是图像二值化.什么是二值化?就是只有0和1,没有其他的.在OpenCV的图像里面,二值化表示图像的像素为0和255 ...

  6. 白月黑羽教python_白月黑羽Python在线教程

    推荐白月黑羽Python在线教程 白月黑羽 站在初学者的角度为大家安排了Python学习教程,帮助大家迅速掌握程序开发技能. http://www.python3.vip/doc/tutorial/p ...

  7. open cv python_open cv——图像阈值处理(python文档)

    目标 学习简单阈值处理(cv2.threshold)和自适应阈值处理(cv2.adaptiveThreshold),大津二值化处理(otus's thresholding) 简单阈值处理(cv2.th ...

  8. 有一定基础学python_有一定编程基础,有什么好的自学python的教程吗?

    有一定编程基础,有什么好的自学 Python 的教程吗? 如果已经有一定的编程基础,那么在学一门新的语言时就不需要花太多时间在编程语言的基础上了.基本上是一天左右就可以了,甚至是可以以"分钟 ...

  9. 白月黑羽python_白月黑羽Python在线教程

    推荐白月黑羽Python在线教程 白月黑羽 站在初学者的角度为大家安排了Python学习教程,帮助大家迅速掌握程序开发技能. http://www.python3.vip/doc/tutorial/p ...

最新文章

  1. 线性布局上的一个小错误
  2. 秒杀系统架构分析与实战,一文带你搞懂秒杀架构!
  3. 【博客话题】技术人生之三界修炼
  4. jax-rs jax-ws_Google App Engine JAX-RS REST服务
  5. Linux 命令之 pwconv -- 开启用户的投影密码
  6. maven的profile详解
  7. 特征工程之数据预处理(下)
  8. vuedraggable示例_vuedraggable快速入门
  9. 《大数据》2020年第3期目次摘要
  10. Python中的顺序表介绍
  11. Linux lvs 的固定访问
  12. 可作为GC Roots的对象
  13. HCIP-RS-MPLS-LSP建立-静态LSP
  14. android layout_width 代码,关于LinearLayout设置权重后width或height不设置0dp的影响说明...
  15. 计算机打字速录,速录员打字口诀有哪些
  16. python图标变成了白色_怎么解决图标变成白色图标的问题
  17. 华为路由器6to4隧道原理及配置
  18. CSS高级篇——属性选择器 (attribute selectors)
  19. 微信多媒体文件speex格式转为mp3文件格式
  20. Hbase的二级索引和RowKey的设计

热门文章

  1. java pkcs12_如何阅读pkcs12文件内容?
  2. BP神经网络-(参考游戏编程中的人工智能技术)
  3. C语言string库strcpy、strcmp、strcat函数详解
  4. 关于大学生道德现状的思考
  5. asp oracle源码下载,大型电子病历系统(oracle版)源码
  6. 白板体现计算机什么方面应用,白板汉字论文,关于电子白板在小学低年级识字写字教学中的运用相关参考文献资料-免费论文范文...
  7. 百度Paddle视频分类论文3D Resnet论文复现
  8. Ocelot(二)- 请求聚合
  9. C++之父B. Stroustrup近期言论
  10. 微信开发者工具更换默认用户存储目录方法