zoukankan      html  css  js  c++  java
  • opencv 二值化图像详解 一文看懂各种二值化方法

    本文介绍使用不同的阈值方法“二值化”图像

    固定阈值分割

    图解

    使用固定阈值127分割图像

    代码

    import cv2 as cv
    
    # 读入灰度图像
    img = cv.imread('baby_g.jpg', 0)
    
    # 阈值127分割图像
    ret, th = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
    cv.imshow('thresh', th)
    cv.waitKey(0)
    cv.destroyAllWindows()
    

    函数讲解

    cv.threshold()用来实现阈值分割,ret是return value缩写,代表当前的阈值,暂时不用理会。函数有4个参数:
    参数1:要处理的原图,一般是灰度图
    参数2:设定的阈值
    参数3:最大阈值,一般为255
    参数4:阈值的方式,主要有5种。

    cv.threshold() 参数4阈值方式详解

    实验
    import cv2 as cv 
    import matplotlib.pyplot as plt
    
    img = cv.imread('gradient.jpg',0)
    
    # 应用5种不同的阈值方法
    ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
    ret, th2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)
    ret, th3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC)
    ret, th4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO)
    ret, th5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV)
    
    titles = ['Original', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
    images = [img, th1, th2, th3, th4, th5]
    
    # 使用Matplotlib显示
    for i in range(6):
        plt.subplot(2, 3, i + 1)
        plt.imshow(images[i], 'gray')
        plt.title(titles[i], fontsize=8)
        plt.xticks([]), plt.yticks([])  # 隐藏坐标轴
    
    plt.show()
    
    实验输出

    5种不同阈值方式的输出结果

    官网中的说明

    官网中对于阈值方式的说明

    一点说明

    很多人误以为阈值分割就是二值化。从上图中可以发现,两者并不等同,阈值分割结果是两类值,而不是两个值,所以教程开头我把二值化加了引号。

    自适应阈值

    简介及函数说明

    看得出来固定阈值是在整幅图片上应用一个阈值进行分割,它并不适用于明暗分布不均的图片。 cv.adaptiveThreshold()自适应阈值会每次取图片的一小部分计算阈值,这样图片不同区域的阈值就不尽相同。它有5个参数:
    参数1:要处理的原图
    参数2:最大阈值,一般为255
    参数3:小区域阈值的计算方式
    ADAPTIVE_THRESH_MEAN_C:小区域内取均值
    ADAPTIVE_THRESH_GAUSSIAN_C:小区域内加权求和,权重是个高斯核
    参数4:阈值方式(跟前面讲的那5种相同)
    参数5:小区域的面积,如11就是11*11的小块
    参数6:最终阈值等于小区域计算出的阈值再减去此值

    实验

    import cv2 as cv 
    import matplotlib.pyplot as plt
    
    img = cv.imread('paojie_g.jpg',0)
    
    # 固定阈值
    ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
    # 自适应阈值
    th2 = cv.adaptiveThreshold(
        img, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 15, 4)
    th3 = cv.adaptiveThreshold(
        img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 15, 8)
    
    titles = ['Original', 'Global(v = 127)', 'Adaptive Mean', 'Adaptive Gaussian']
    images = [img, th1, th2, th3]
    
    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()
    

    实验结果

    上述代码输出结果

    Otsu 阈值

    原理及python手动实现

    手动实现Otsu阈值法

    实验

    import cv2 as cv
    import numpy as np
    
    # Read image
    img = cv.imread("paojie_g.jpg",0)
    # Otsu's binarization of Opencv
    ret2,th2 = cv.threshold(img,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
    print("threshold >>", ret2)
    # Save result
    cv.imwrite("out.jpg", th2)
    cv.imshow("result", th2)
    cv.waitKey(0)
    cv.destroyAllWindows() 
    

    实验结果

    原图
    Otsu二值化阈值算法结果
    都看到这里了,点个赞再走呗。

  • 相关阅读:
    Android 屏幕实现水龙头事件
    高速排序算法
    hdu2993坡dp+二进制搜索
    如何设计接口?
    virtio-netdev 发送数据包
    android-sdk-windows下载版
    FusionCharts简明教程(一)---建立FusionCharts图形
    strcpy_s与strcpy对照
    安全博客
    图片相关
  • 原文地址:https://www.cnblogs.com/wojianxin/p/12589558.html
Copyright © 2011-2022 走看看