美文网首页
OpenCV-Python学习(四):阈值操作

OpenCV-Python学习(四):阈值操作

作者: 星光下的胖子 | 来源:发表于2020-06-23 20:18 被阅读0次

目录:

  • 1.图像二值化
  • 2.阈值操作
    • 简单阈值(全局阈值)
    • 自适应阈值(局部阈值)
  • 3.简单阈值 vs 自适应阈值

一、图像二值化

图像二值化:将图像上像素点的灰度值设置为0或255,呈现明显的黑白效果。
图像二值化是图像预处理中必不可少的操作。

OTSU算法(大津法):是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出。从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景图像的类间方差最大。

OTSU二值化:

import cv2

# OTSU二值化
img = cv2.imread("image/1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)  # OTSU算法求阈值

cv2.imshow("image", img)
cv2.imshow("gray", gray)
cv2.imshow("binary", binary)
cv2.waitKey(0)
cv2.destroyAllWindows()

二、阈值操作

1.简单阈值

函数:

1)简单阈值操作: threshold()
        ret, mask = threshold(src, thresh, maxval, type, dst=None)

        ret: thresh阈值
        mask: 二值化后的图像

        src:图片源
        thresh:阈值,取值范围0~255。
        maxval:填充色(最大值),取值范围0~255,一般取255。
            注意:maxval只对THRESH_BINARY和THRESH_BINARY_INV两种阈值类型有效。
        type:阈值类型。常用的几种阈值类型如下:
            1)THRESH_BINARY = 0
                阈值二值化(threshold binary)
                小于等于阈值的像素点置0,大于阈值的像素点置255.
            2)THRESH_BINARY_INV = 1
                阈值反二值化(threshold binary Inverted)
                小于等于阈值的像素点置255,大于阈值的像素点置0.
            3)THRESH_TRUNC = 2
                截断(truncate)
                小于等于阈值的像素点保持原色,大于阈值的像素点置灰(与阈值threshold一致).
            4)THRESH_TOZERO = 3
                阈值取零(threshold to zero)
                小于等于阈值的像素点置0,大于阈值的像素点保持原色。
            5)THRESH_TOZERO_INV = 4
                阈值反取零(threshold to zero inverted)
                小于等于阈值的像素点保持原色,大于阈值的像素点置0。

示例:

import cv2
import matplotlib.pyplot as plt

# 将彩色图转化为灰度图
img = cv2.imread("image/1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 将灰度图转化为二值化图
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
ret, binary_inv = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
ret, truncate = cv2.threshold(gray, 0, 255, cv2.THRESH_TRUNC | cv2.THRESH_OTSU)
ret, tozero = cv2.threshold(gray, 0, 255, cv2.THRESH_TOZERO | cv2.THRESH_OTSU)
ret, tozero_inv = cv2.threshold(gray, 0, 255, cv2.THRESH_TOZERO_INV | cv2.THRESH_OTSU)

# 结合matplotlib,展示多张二值化图
titles = ['Gray Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [gray, binary, binary_inv, truncate, tozero, tozero_inv]
for i in range(6):
    # 划分2行*3列的区域,在第(i+1)个区域上画图
    plt.subplot(2, 3, i+1)

    # 将图片显示在画板上
    # cmap颜色映射: 当img形状是三维矩阵(M,N,3)或(M,N,4)时,值被解释为RGB或RGBA,此时cmap将被忽略。
    # 当img形状是二维矩阵(M,N)时,此时cmap用于值到颜色的一个映射。
    plt.imshow(images[i], cmap="gray")

    # 添加标题
    plt.title(titles[i])

    # 清空x轴、y轴刻度
    plt.xticks([])
    plt.yticks([])
plt.show()  # 显示画板
简单阈值.png
2.自适应阈值

函数:

2)自适应阈值操作: adaptiveThreshold()
        adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)

        src:源图片(8位单通道)。
        maxval:背景填充色(赋给满足条件的像素的非零值)。
            注意:maxval只对THRESH_BINARY和THRESH_BINARY_INV两种阈值类型有效。
        adaptiveMethod:自适应阈值的计算方法。两种自适应阈值的计算方法:
            1)ADAPTIVE_THRESH_MEAN_C:阈值取自相邻区域的平均值。(平均数-常数)
            2)ADAPTIVE_THRESH_GAUSSIAN_C:阈值取自相邻区域的高斯分布加权和。(加权平均数-常数)
        thresholdType:阈值类型,只能是THRESH_BINARY或THRESH_BINARY_INV。
        blockSize:相相邻区域块大小(用于计算像素点的阈值),且为大于1的奇数(一般取3~11),如: 3,5,7等。
            blockSize=11 表示[11 x 11]的一个正方形像素区域块。
        C:Constant常数,计算阈值时用平均数或加权平均数减去该常数。一般为正数,也可以是0或负数。

示例:

import cv2
import matplotlib.pyplot as plt

# 读取彩色图片并转化为灰度图
gray = cv2.imread("image/2.jpg", cv2.IMREAD_GRAYSCALE)

# 1.简单阈值(全局阈值)
ret, global_binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

# 2.自适应阈值(局部阈值)
adaptive_mean_binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11 ,2)
adaptive_gaussian_binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11 ,2)

titles = ['Gray Image', "Global Thresholding", 'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [gray, global_binary, adaptive_mean_binary, adaptive_gaussian_binary]
for i in range(4):
    # 划分[2行*2列]的区域,在第(i+1)个区域上画图
    plt.subplot(2, 2, i+1)
    # 将图片显示到画板上
    plt.imshow(images[i], cmap="gray")
    # 添加标题
    plt.title(titles[i])
    # 清空x轴、y轴坐标刻度
    plt.xticks([])
    plt.yticks([])
plt.show()  # 显示画板
自适应阈值.png

三、简单阈值 vs 自适应阈值

简单阈值:即全局固定阈值,整个图像采用同一个阈值。
自适应阈值:即局部阈值,为每个像素点单独计算一个阈值。

一张图片的不同区域具有不同的亮度时,全局阈值往往不能得到想要的效果,这时我们采用自适应阈值。自适应阈值在图像的不同区域采用不同的阈值,从而使我们在图像亮度不同的情况下得到更好的效果。

相关文章

网友评论

      本文标题:OpenCV-Python学习(四):阈值操作

      本文链接:https://www.haomeiwen.com/subject/vqqkfktx.html