灰度图像的自动阈值分割

这篇具有很好参考价值的文章主要介绍了灰度图像的自动阈值分割。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第一种:Otsu (大津法)

一、基于cv2的API调用

1、代码实现

直接给出相关代码:

import cv2
import matplotlib.pylab as plt

path = r"D:\Desktop\00aa\1.png"
img = cv2.imread(path, 0)

def main2():
    ret, thresh1 = cv2.threshold(img, 0, 1, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    print(ret)  # 输出阈值。thresh1是阈值图像

    titles = ['Original Image', 'After Binarization']
    images = [img, thresh1]

    for i in range(2):
        plt.subplot(1, 2, i + 1)
        plt.imshow(images[i], 'gray')
        plt.title(titles[i])
        plt.xticks([])
        plt.yticks([])

    plt.show()

main2()

灰度图像的自动阈值分割,笔记,opencv,人工智能,计算机视觉

2、参数详解

ret, binary_image = cv2.threshold(image, threshold_value, max_value, type)

cv2.threshold()的参数如下:

  • image:要处理的输入图像,可以是灰度图像或彩色图像,类型为uint8或者uint16,否则会报错
  • threshold_value:设定的阈值,如果像素值大于该阈值,则将其设为max_value,否则将其设为0。即:用于分割像素的阈值。
  • max_value:高于阈值的像素所设置的值,默认为255。即:高于threshold_value的设置为该值,也就是最后二值图像中的最大值。
  • type:阈值化的类型,有以下几种可选:
    • cv2.THRESH_BINARY:二值化阈值化,大于阈值的像素值设为max_value,小于等于阈值的像素值设为0。
    • cv2.THRESH_BINARY_INV:反二值化阈值化,大于阈值的像素值设为0,小于等于阈值的像素值设为max_value。
    • cv2.THRESH_TRUNC:截断阈值化,大于阈值的像素值设为阈值,小于等于阈值的像素值不变。
    • cv2.THRESH_TOZERO:阈值化为0,大于阈值的像素值不变,小于等于阈值的像素值设为0。
    • cv2.THRESH_TOZERO_INV:反阈值化为0,大于阈值的像素值设为0,小于等于阈值的像素值不变。

3、为什么用的是cv2.THRESH_BINARY+cv2.THRESH_OTSU

将 cv2.THRESH_BINARY 和 cv2.THRESH_OTSU 结合使用可以发挥它们的优势,尤其适用于那些具有不同对比度区域的图像。这种组合利用大津算法自动选择最佳阈值,然后将图像进行二值化。

但是经过测试,没有THRESH_BINARY的结果也是一样的,所以需不需要根据自己需求。

1)了解 cv2.THRESH_BINARY

一种基本的二值化方法,它使用一个用户指定的固定阈值将图像中的像素分为两类:高于阈值和低于阈值。简而言之,像素值大于阈值的被设为一个值(通常是255),而像素值小于阈值的被设为另一个值(通常是0)。

ret, binary_image = cv2.threshold(image, threshold_value, max_value, cv2.THRESH_BINARY)
  • image: 输入的灰度图像。
  • threshold_value: 用于分割像素的阈值。
  • max_value: 高于阈值的像素所设置的值。
  • cv2.THRESH_BINARY: 指定使用二进制阈值化。
2)了解 cv2.THRESH_OTSU

大津算法,它是一种自动确定阈值的方法。该算法会分析图像的直方图,找到能够最佳区分前景和背景的阈值。这使得它特别适用于前景和背景对比度差异较大的图像。

ret, binary_image = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
  • image: 输入的灰度图像。
  • 0: 这里将阈值设置为0,但实际上会被 cv2.THRESH_OTSU 自动确定。
  • 255: 高于阈值的像素所设置的值。
  • cv2.THRESH_BINARY+cv2.THRESH_OTSU: 结合了二进制阈值和大津法。

4、注意

输入的灰度图像必须是uint8或者uint16类型,如果不是需要进行转换。

img = img.astype(np.uint16)

此外,数据中如果有负值,那么计算返回的阈值会一直显示为最大值,此时需要将负值去除或重置为正数,也可以利用最大最小归一化技术在乘以255。

import numpy as np

path = r"D:\Desktop\00aa\1.png"
img = cv2.imread(path, 0)

def normalize(arr):
    min_val = np.min(arr)
    max_val = np.max(arr)
    normalized_arr = (arr - min_val) / (max_val - min_val)
    return normalized_arr

img = normalize(img)*255
img = img.astype(np.uint16)

在cv2.threshold函数中,我们设置的两个数值,第一个就是阈值(OTSU会自动学习,设置多少无所谓),根据该阈值进行分割;第二个是将二值图像中的最大值设置为多少,即设置5,那么的到的二值图像就是0和5。

二、使用numpy实现

import cv2
import matplotlib.pylab as plt
import numpy as np

path = r"D:\Desktop\00aa\1.png"
img = cv2.imread(path, 0)

def OTSU(img_gray, GrayScale): # GrayScale:灰度图中灰度值的最大值,这里需要在将此值加1。即:灰度图最大值+1
    assert img_gray.ndim == 2, "must input a gary_img"  # shape有几个数字, ndim就是多少
    img_gray = np.array(img_gray).ravel().astype(np.uint8)
    u1 = 0.0  # 背景像素的平均灰度值
    u2 = 0.0  # 前景像素的平均灰度值
    th = 0.0

    # 总的像素数目
    PixSum = img_gray.size
    # 各个灰度值的像素数目
    PixCount = np.zeros(GrayScale)
    # 各灰度值所占总像素数的比例
    PixRate = np.zeros(GrayScale)
    # 统计各个灰度值的像素个数
    for i in range(PixSum):
        # 默认灰度图像的像素值范围为GrayScale
        Pixvalue = img_gray[i]
        PixCount[Pixvalue] = PixCount[Pixvalue] + 1

    # 确定各个灰度值对应的像素点的个数在所有的像素点中的比例。
    for j in range(GrayScale):
        PixRate[j] = PixCount[j] * 1.0 / PixSum
    Max_var = 0
    # 确定最大类间方差对应的阈值
    for i in range(1, GrayScale):  # 从1开始是为了避免w1为0.
        u1_tem = 0.0
        u2_tem = 0.0
        # 背景像素的比列
        w1 = np.sum(PixRate[:i])
        # 前景像素的比例
        w2 = 1.0 - w1
        if w1 == 0 or w2 == 0:
            pass
        else:  # 背景像素的平均灰度值
            for m in range(i):
                u1_tem = u1_tem + PixRate[m] * m
            u1 = u1_tem * 1.0 / w1
            # 前景像素的平均灰度值
            for n in range(i, GrayScale):
                u2_tem = u2_tem + PixRate[n] * n
            u2 = u2_tem / w2
            # print(u1)
            # 类间方差公式:G=w1*w2*(u1-u2)**2
            tem_var = w1 * w2 * np.power((u1 - u2), 2)
            # print(tem_var)
            # 判断当前类间方差是否为最大值。
            if Max_var < tem_var:
                Max_var = tem_var  # 深拷贝,Max_var与tem_var占用不同的内存空间。
                th = i
    return th

def main():
    # 将图片转为灰度图
    th = OTSU(img, 256)
    print("使用numpy的方法:" + str(th))

    ret, thresh1 = cv2.threshold(img, th, 1, cv2.THRESH_BINARY)

    titles = ['Original Image', 'After Binarization']
    images = [img, thresh1]

    for i in range(2):
        plt.subplot(1, 2, i + 1)
        plt.imshow(images[i], 'gray')
        plt.title(titles[i])
        plt.xticks([])
        plt.yticks([])

    plt.show()

main()

灰度图像的自动阈值分割,笔记,opencv,人工智能,计算机视觉

两种实现结果基本一致

灰度图像的自动阈值分割,笔记,opencv,人工智能,计算机视觉

第二种:自适应阈值分割(局部阈值化)

自适应阈值分割,也称为局部阈值化,是根据像素的邻域块的像素值分布来确定该像素位置上的阈值。这种方法的好处是每个像素位置的阈值是根据其周围邻域像素的分布来确定的,因此不是固定不变的。不同亮度、对比度和纹理的局部图像区域将拥有不同的局部阈值。

常用的局部自适应阈值有:1)局部邻域块的均值;2)局部邻域块的高斯加权和。
 

在OPenCV中实现自适应阈值分割的API是:

dst = cv.adaptiveThreshold(src, maxval, thresh_type, type, Block Size, C)

参数:

  • src: 输入图像,一般是灰度图
  • Maxval:灰度中的最大值,一般为255,用来指明像素超过或小于阈值(与type类型有关),赋予的最大值
  • thresh_type : 阈值的计算方法,主要有以下两种:
  • type: 阈值方式,与threshold中的type意义相同
  • block_size: 计算局部阈值时取邻域的大小,如果设为11,就取11*11的邻域范围,一般为奇数。
  • C: 阈值计算方法中的常数项,即最终的阈值是邻域内计算出的阈值与该常数项的差值

返回:

  • dst:自适应阈值分割的结果

即type类型:

灰度图像的自动阈值分割,笔记,opencv,人工智能,计算机视觉

代码演示:

import cv2 as cv
import matplotlib.pyplot as plt

# 1. 图像读取
img = cv.imread(r"D:\Desktop\00aa\1.png", 0) # 转为灰度图

# 2.固定阈值/阈值分割 threshold(要处理的图像,一般是灰度图, 设定的阈值, 灰度中的最大值, 阈值分割的方式)
ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)

# 3.自适应阈值
# 3.1 邻域内求均值 cv.adaptiveThreshold(输入图像, 灰度中的最大值, 阈值的计算方法, 阈值方式,计算局部阈值时取邻域的大小,阈值计算方法中的常数项)
th2 = cv.adaptiveThreshold(
    img, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 11, 4)
# 3.2 邻域内高斯加权
th3 = cv.adaptiveThreshold(
    img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 17, 6)

# 4 结果绘制
titles = ['Original drawing', 'Global threshold (v = 127)', 'Adaptive threshold (averaging)',
          'Adaptive threshold (Gaussian weighted)']
images = [img, th1, th2, th3]
plt.figure(figsize=(10, 6))
for i in range(4):
    plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i], fontsize=8)
    plt.xticks([]), plt.yticks([])
plt.show()

灰度图像的自动阈值分割,笔记,opencv,人工智能,计算机视觉

参考:图像二值化阈值调整、OpenCV 中的二值化文章来源地址https://www.toymoban.com/news/detail-817659.html

到了这里,关于灰度图像的自动阈值分割的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [OpenCV学习笔记]Qt+OpenCV实现图像灰度反转、对数变换和伽马变换

    灰度反转是一种线性变换,是将某个范围的灰度值映射到另一个范围内,一般是通过灰度的对调,突出想要查看的灰度区间。 S = L − 1 − r ( r ⊂ [ 0 , L − 1 ] ) S = L -1-r (r subset [0,L-1]) S = L − 1 − r ( r ⊂ [ 0 , L − 1 ]) 比如在以下胸片图像中提取白色絮状形状,在黑色背景下看

    2024年04月13日
    浏览(26)
  • MATLAB图像分割之阈值分割

            可以通过图像全局的信息,例如整个图像的灰度直方图。如果在整个图像中只使用一个阈值,则这种方法叫做全局阈值法,整个图象分成两个区域,即目标对象(黑色)和背景对象(白色)。全局阈值将整个图像的灰度阈值设置为常数。 I=imread(\\\'veg.png\\\'); figure,imshow(I); I2=r

    2024年02月07日
    浏览(35)
  • Matlab|图像处理04|图像分割-阈值分割方法

    一、人工阈值分割方法threshold_test1.m 1、分析修改阈值对分割结果的影响 分析:取直方图中第一个谷底的灰度值作为阈值,图像分割效果较好。当阈值改变时,分割后的图像有部分信息丢失,本图中当阈值减小时分割后的图像黑色部分较多,当阈值增大时分割后的图像白色部

    2024年02月11日
    浏览(31)
  • 图像处理与计算机视觉--第五章-图像分割-自适应阈值分割

      在图片处理过程中,针对铺前进行二值化等操作的时候,我们希望能够将图片相应区域内所有的信息提供保留。实验室环境下,相应的素材是模板化的,但是将实验室方法应用于现实环境中时,我们会发现光影环境对于效果的影响其实是很大的。在这种情况下进行处理,

    2024年02月07日
    浏览(35)
  • (数字图像处理MATLAB+Python)第十章图像分割-第一、二节:阈值分割和边界分割

    图像分割 :在对图像的研究和应用中,人们往往仅对图像中的某些目标感兴趣,这些目标通常对应图像中具有特定性质的区域。图像分割是指把一幅图像分成不同的具有特定性质区域的图像处理技术,将这些区域分离提取出来,以便进一步提取特征和理解 图像分割方法多种

    2024年02月16日
    浏览(39)
  • Matlab图像处理-多阈值分割

    多阈值分割 在某些时候图像使用单独的阈值不能够对其实现有效地分割,例如在灰度直方图中有明显的三个峰时候,我们需要提取中间峰,这时我们使用双阈值分割会得到较好的分割效果。如下例子中生成灰度直方图中有两个峰,选择合适的两个阈值进行多阈值分割后可生成

    2024年02月09日
    浏览(37)
  • 图像分割---基于阈值处理的基本方法

    本文主要介绍图像分割基于阈值处理的一些基本方法。 该方法基于图像直方图上出现的双峰现象。当一个图像有双峰现象时,其直方图会出现两个峰,分别对应图像中两种不同的颜色或亮度区域。这时我们可以使用直方图双峰法来自动确定合适的阈值。其基本思路如下: 计

    2024年02月05日
    浏览(31)
  • Matlab遗传算法道路图像阈值分割(附上完整源码)

    图像阈值分割是图像处理中常用的一种方法,用于将图像分割为不同的区域。本文介绍了遗传算法在道路图像阈值分割中的应用。首先,对图像进行预处理,包括图像的灰度化和噪声去除。然后,通过遗传算法优化阈值的选择,以得到最佳的分割结果。实验结果表明,遗传算

    2024年02月12日
    浏览(26)
  • 三维重建 阈值分割 3D可视化 医学图像分割 CT图像分割及重建系统 可视化编程技术及应用

    此系统实现了常见的VTK四视图,实现了很好的CT图像分割,可以用于骨骼,头部,肺部,脂肪等分割,,并且通过三维重建实现可视化。使用了第三方库 VTK,ITK 实现分割和生不重建。 窗口分为 (横断面)、冠状面、矢状面,和3D窗口;包含了体绘制和面绘制; 效果: CT分割

    2024年02月08日
    浏览(43)
  • 【图像分割】基于浣熊优化算法COA的Otsu(大津法)多阈值电表数字图像分割 电表数字识别【Matlab代码#52】

    长鼻浣熊优化算法(Cоati Optimization Algorithm,COA)是一种启发式优化算法,灵感来源于长鼻浣熊(Coati)的行为策略。长鼻浣熊优化算法基于长鼻浣熊在觅食过程中的特性和行为模式。长鼻浣熊是一种树栖动物,具有长而灵活的鼻子,用于觅食和捕食。它们通过嗅觉感知周围环

    2024年02月16日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包