python3 opencv 图像二值化笔记(cv2.threshold)

刚接触opencv,需要用到图像二值化,发现opencv提供的二值化算法有很多,网上借鉴了很多大神的帖子,自己做了一些总结归纳,作为笔记先记录一下。

opencv二值化相关函数有两个,先记录一下threshold的使用,另一个为adaptiveThreshold,会在下个帖子做记录

cv2.threshold(src, thresh, maxval, type, dst=None)

研究了一下参数,

src:需要进行二值化的一张灰度图像

thresh:手动指定的灰度值(0~255)(用来比较的阈值)

maxval:另一个需要手动指定的灰度值(0~255)(将要设置的灰度值)

type:opencv提供的二值化方法

dst:输出图像,可以忽略

返回值有两个,第一个是opencv实际在做二值化处理时的用的灰度值,第二个是二值化后的图像

在使用这个函数的时候,

第一个参数src

需要一张灰度图,这个很简单,直接下面这段代码就能得到灰度图

image_path = './img/1.jpg'
img = cv2.imread(image_path)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

第二个参数thresh

指定一个阈值,将灰度图的像素点分成两类,灰度大于阈值的像素点集合和小于阈值的像素点集合

一般简单粗暴直接传个中间值127进去,但毕竟是写死的数值,通用性较差,因此也可以使用图像的平均灰度值,好处是能根据不同图像动态变换。具体图像的平均灰度值计算方法如下

import numpy as np

h, w = gray.shape[:2] # gray 为灰度图
m = np.reshape(gray, [1, w*h])
mean = m.sum()/(w*h) # 图像平均灰度值

thresh = mean

第三个参数maxval

一般情况下可以认为把大于阈值的像素点的灰度值设置成maxval,一般用255,即大于阈值的像素点值一律变成255(白色)

第四个参数type

opencv提供以下参数

THRESH_BINARY     = 0, 
THRESH_BINARY_INV = 1,
THRESH_TRUNC      = 2,
THRESH_TOZERO     = 3, 
THRESH_TOZERO_INV = 4, 
THRESH_MASK       = 7,
THRESH_OTSU       = 8,
THRESH_TRIANGLE   = 16

看了其他帖子的介绍,THRESH_MASK好像不支持使用,因此可以忽略。剩下的参数可以分为两类

THRESH_BINARY     = 0, 
THRESH_BINARY_INV = 1,
THRESH_TRUNC      = 2,
THRESH_TOZERO     = 3, 
THRESH_TOZERO_INV = 4, 
THRESH_OTSU       = 8,
THRESH_TRIANGLE   = 16

前五个为一类参数,用来指定二值化的方式,总结出来如下

THRESH_BINARY:大于阈值thresh的像素点灰度值设为maxval, 小于阈值的像素点灰度值设为0
THRESH_BINARY_INV:THRESH_BINARY的反转,即大于阈值的像素点灰度值设为0, 小于阈值的像素点灰度值设为maxval
THRESH_TRUNC   大于阈值的像素点灰度值设为阈值thresh,其他像素点不变, maxval参数不生效
THRESH_TOZERO   大于阈值的像素点不变,小于阈值的像素点灰度值设为0, maxval参数不生效
THRESH_TOZERO_INV  大于阈值的像素点灰度值设为0,其他像素点不变, maxval参数不生效

大部分场合,会用到前面两种类型,而后三种类型函数的第三个参数maxval将不会生效。

看一下效果,作为演示,阈值都指定为127

thresh, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_XXXX)
cv2.imshow(f'thresh={int(thresh)}, type=THRESH_XXXX', binary)

再来说最后两个参数THRESH_OTSU和THRESH_TRIANGLE ,前面的代码的阈值,不管是127还是动态计算平均灰度值,都需要人为指定,而使用THRESH_OTSU或THRESH_TRIANGLE后,就不需要人为指定阈值了。

THRESH_OTSU或THRESH_TRIANGLE不是二值化方式,更像是计算图像阈值的算法,因此需要结合前五个参数一起使用,具体使用方式比如 type= cv2.THRESH_BINARY | cv2.THRESH_OTSU

#第二个参数不生效,因此传个0
thresh, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) 
cv2.imshow(f'thresh={int(thresh)}, type=THRESH_BINARY | cv2.THRESH_OTSU', binary)

thresh, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_TRIANGLE)
cv2.imshow(f'thresh={int(thresh)}, type=THRESH_BINARY | cv2.THRESH_TRIANGLE', binary)

可以看到,即便阈值设置为0,两个算法分别算出了用于计算的阈值,分别是153和250

以上为cv2.threshold使用时的个人总结,之后继续分享另一种二值化方式cv2.adaptiveThreshold

import cv2
import numpy as np

def cal_average_gray_value(gray):
    h, w = gray.shape[:2]
    m = np.reshape(gray, [1, w*h])
    mean = m.sum()/(w*h)
    return mean

if __name__ == "__main__":
    image_path = './img/1.jpg'
    img = cv2.imread(image_path)

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    thresholdTypes = [cv2.THRESH_BINARY, cv2.THRESH_BINARY_INV, cv2.THRESH_TRUNC,
                      cv2.THRESH_TOZERO, cv2.THRESH_TOZERO_INV, cv2.THRESH_OTSU, cv2.THRESH_TRIANGLE]

    for thresholdType in thresholdTypes:
        thresh, binary = cv2.threshold(gray, 127, 255, thresholdType)
        cv2.imshow(
            f'thresh={int(thresh)}, thresholdType={thresholdType}', binary)
    
    cv2.waitKey(0)

Python中使用OpenCV库进行图像二值化时,可以调用`cv2.threshold`函数来实现。该函数可以根据不同的阈值处理方式将图像转换为二值图像。`cv2.threshold`函数有五种不同的类型,分别对应不同的二值化策略: 1. `cv2.THRESH_BINARY`:标准二值化。如果像素值大于阈值(`thresh`),则被设置为`maxval`;否则,被设置为0(黑色)。 2. `cv2.THRESH_BINARY_INV`:反转的二值化。如果像素值小于阈值(`thresh`),则被设置为`maxval`;否则,被设置为0。 3. `cv2.THRESH_TRUNC`:截断二值化。如果像素值大于阈值(`thresh`),像素值被设置为阈值;否则,保持原值。 4. `cv2.THRESH_TOZERO`:向零二值化。如果像素值大于阈值(`thresh`),像素值保持不变;否则,被设置为0。 5. `cv2.THRESH_TOZERO_INV`:反转的向零二值化。如果像素值小于阈值(`thresh`),像素值保持不变;否则,被设置为0。 下面是一个简单的代码示例,展示如何使用`cv2.threshold`函数进行五种不同的二值化处理: ```python import cv2 import numpy as np # 读取图像 image = cv2.imread('path_to_image.jpg', 0) # 确保使用灰度模式读取图像 # 设置阈值和最大值 thresh = 127 maxval = 255 # 应用五种不同的二值化方式 ret, binary = cv2.threshold(image, thresh, maxval, cv2.THRESH_BINARY) ret, binary_inv = cv2.threshold(image, thresh, maxval, cv2.THRESH_BINARY_INV) ret, trunc = cv2.threshold(image, thresh, maxval, cv2.THRESH_TRUNC) ret, tozero = cv2.threshold(image, thresh, maxval, cv2.THRESH_TOZERO) ret, tozero_inv = cv2.threshold(image, thresh, maxval, cv2.THRESH_TOZERO_INV) # 显示结果 cv2.imshow('Binary', binary) cv2.imshow('Binary Inverted', binary_inv) cv2.imshow('Truncated', trunc) cv2.imshow('To Zero', tozero) cv2.imshow('To Zero Inverted', tozero_inv) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上述代码中,`path_to_image.jpg`应替换为你想要进行二值化处理的图像路径。通过读取的图像和定义的阈值以及最大值,使用`cv2.threshold`函数对图像进行五种不同的二值化处理,并使用`cv2.imshow`函数显示结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值