文章目录

  • 1.图像二值化
  • 2.阈值
  • 2.1.阈值的定义
  • 2.2.阈值类型
  • 2.2.1.二进制阈值化(cv2.THRESH_BINARY)
  • 2.2.2.反二进制阈值化(cv2.THRESH_BINARY_INV)
  • 2.2.3.截断阈值化(cv2.THRESH_TRUNC)
  • 2.2.4.阈值化为0(cv2.THRESH_TOZERO)
  • 2.2.5.反阈值化为0(cv2.THRESH_TOZERO_INV)
  • 3.图像二值化方法
  • 3.1.全局二值化
  • 3.2.局部二值化
  • 3.3.自己计算阈值
  • 完整代码


1.图像二值化

图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出黑白效果的过程。
图像的二值化,在图像处理中是十分重要的一个步骤。是几乎所有后续的图像处理的基础和前提。只有根据不同场景选择不同的二值化处理,才能对一幅图片较好的初始化。(包括灰度值处理,二值化处理,根据噪声类型降噪等)。
一幅图像包括目标物体、背景还有噪声,要想从多值二值化的数字图像中直接提取出目标物体,最常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(BINARIZATION)。

2.阈值

2.1.阈值的定义

说到图像二值化,就不得不提到阈值,阈的意思是界限,故阈值又叫临界值,是指一个效应能够产生的最低值或最高值。

2.2.阈值类型

图像二值化的阈值有五种类型。为了解释阈值分割的过程,我们可以看一个简单有关像素灰度的图片,该图如下,该图中的蓝色水平线代表着具体的一个阈值。

Python cv 二值化后的质心 python图像二值化_Python cv 二值化后的质心

2.2.1.二进制阈值化(cv2.THRESH_BINARY)

该类型如下式所示:

Python cv 二值化后的质心 python图像二值化_二值化_02


在运用该阈值类型的时候,先要选定一个特定的阈值量,比如:125,这样,大于125的像素点的灰度值设定为最大值(如8位灰度值最大为255),灰度值小于125的像素点的灰度值设定为0,其图解为:

Python cv 二值化后的质心 python图像二值化_计算机视觉_03

2.2.2.反二进制阈值化(cv2.THRESH_BINARY_INV)

该类型的公式为:

Python cv 二值化后的质心 python图像二值化_python_04


该阈值化与二进制阈值化相似,先选定一个特定的灰度值作为阈值,不过最后的设定值相反。在8位灰度图中,例如大于阈值的设定为0,而小于该阈值的设定为255,其图解为:

Python cv 二值化后的质心 python图像二值化_计算机视觉_05

2.2.3.截断阈值化(cv2.THRESH_TRUNC)

该类型的公式为:

Python cv 二值化后的质心 python图像二值化_Python cv 二值化后的质心_06


首先需要选定一个阈值,图像中大于该阈值的像素点被设定为该阈值,小于该阈值的保持不变。例如:阈值选取为125,那小于125的阈值不改变,大于125的灰度值(230)的像素点就设定为该阈值。其图解为:

Python cv 二值化后的质心 python图像二值化_二值化_07

2.2.4.阈值化为0(cv2.THRESH_TOZERO)

该阈值类型为:

Python cv 二值化后的质心 python图像二值化_二值化_08


先选定一个阈值,然后对图像做如下处理:若像素点的灰度值大于该阈值的不进行任何改变;若像素点的灰度值小于该阈值的,其灰度值全部变为0。

其图解为:

Python cv 二值化后的质心 python图像二值化_opencv_09

2.2.5.反阈值化为0(cv2.THRESH_TOZERO_INV)

该类型的公式为:

Python cv 二值化后的质心 python图像二值化_计算机视觉_10


原理类似于0阈值,但是在对图像做处理的时候相反,若像素点的灰度值小于该阈值的不进行任何改变,而大于该阈值的部分,其灰度值全部变为0。

其图解为:

Python cv 二值化后的质心 python图像二值化_python_11

3.图像二值化方法

图像二值化方法有全局二值化,局部二值化,自定义二值化。
在进行图像二值化之前,我们都要先将图像转化为灰度图像,然后在进行相关的操作。

3.1.全局二值化

在全局二值化中,我们会用到threshold这个API,
threshold( src_gray, dst, threshold_value, max_BINARY_value, threshold_type );
其代码为:

def threshold_demo(image):              # 全局二值化
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    print("threshold value: %s" % ret)
    cv.imshow("binary image", binary)

原图为:

Python cv 二值化后的质心 python图像二值化_Python cv 二值化后的质心_12


经过二值化后的图像为:

Python cv 二值化后的质心 python图像二值化_opencv_13

3.2.局部二值化

在局部二值化中,我们会使用到adaptiveThreshold这个API,
adaptiveThreshold( src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)
src:源图像,maxValue:像素值上限,adaptiveMethod:自适应方法,
— cv2.ADAPTIVE_THRESH_MEAN_C :领域内均值
—cv2.ADAPTIVE_THRESH_GAUSSIAN_C :领域内像素点加权和,权重为一个高斯窗口
thresholdType:阈值类型,blockSize:规定领域大小(一个正方形的领域),它必须为奇数,
C:阈值等于均值或者加权值减去这个常数(为0相当于阈值 就是求得领域内均值或者加权值)
代码如下:

def local_threshold(image):             # 局部二值化
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    dst = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
    cv.imshow("binary image", dst)

得到的效果为:

Python cv 二值化后的质心 python图像二值化_python_14

3.3.自己计算阈值

将图像转换为灰度图像后求出其宽和高,接着将灰度图像转变成1行,w*h列的图像,然后求出平均值,最后我们再通过全局二值化来得到二值化图像。
其代码为:

def custom_threshold(image):            # 自己计算阈值
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    h, w = gray.shape[:2]
    m = np.reshape(gray, [1, w * h])    # 图像变成一行
    mean = m.sum() / (w * h)
    print("mean: ", mean)
    ret, dst = cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
    cv.imshow("binary image", dst)

得到的效果为:

Python cv 二值化后的质心 python图像二值化_计算机视觉_15

完整代码

import cv2 as cv  # 导入opencv模块
import numpy as np  # 导入数学函数库


def threshold_demo(image):              # 全局二值化
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    """
    #大律法,全局自适应阈值 参数0可改为任意数字但不起作用   
    cv.THRESH_BINARY | cv.THRESH_OTSU 

    #TRIANGLE法,,全局自适应阈值, 参数0可改为任意数字但不起作用,适用于单个波峰
    cv.THRESH_BINARY | cv.THRESH_TRIANGLE

    # 自定义阈值为150,大于150的是白色 小于的是黑色
     cv.THRESH_BINARY

    # 自定义阈值为150,大于150的是黑色 小于的是白色
    cv.THRESH_BINARY_INV 

    # 截断 大于150的是改为150  小于150的保留
    cv.THRESH_TRUNC 

    # 截断 小于150的是改为150  大于150的保留
    cv.THRESH_TOZERO 
    """
    # ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_TRUNC)
    print("threshold value: %s" % ret)
    cv.imshow("binary image", binary)


def local_threshold(image):             # 局部二值化
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    dst = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
    cv.imshow("binary image", dst)


def custom_threshold(image):            # 自己计算阈值
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    h, w = gray.shape[:2]
    m = np.reshape(gray, [1, w * h])    # 图像变成一行
    mean = m.sum() / (w * h)
    print("mean: ", mean)
    ret, dst = cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
    cv.imshow("binary image", dst)


print("------------hello python!------------")

src = cv.imread("D:/opencv3/image/house.jpg")
cv.namedWindow("input_image", cv.WINDOW_AUTOSIZE)
cv.imshow("input_image", src)
# threshold_demo(src)
# local_threshold(src)
custom_threshold(src)

cv.waitKey(0)
cv.destroyAllWindows()  # 释放所有窗口