Py-OpenCV学习记录4-阈值过滤

前言

如前面所提及的,一张图像的信息都被记录在一个矩阵内,其通道数值便是不同点的信息,利用信息对图片进行处理,筛选出所需要的信息,简化图像信息加速后续处理的速度。
在OpenCV中的常见的阈值操作主要有三种,分别为:固定阈值自适应阈值Otsu阈值三种。

固定阈值过滤

使用 cv2.threshold() 函数。此方法为选定一个阈值,大于该阈值的和小于该阈值的分别被赋予不同的操作。

retval, dst=cv.threshold( src, thresh, maxval, type[,dst])
参数介绍
src操作的源图像
thresh阈值(分界线)
maxval和阈值方式配合使用(通常是将像素在大于或小于阈值是需要赋予的值)
type阈值方式
dst输出的图像会与选用的dst有相同的像素和通道数,默认值为src相同的参数

阈值方式type:

cv.THRESH BINARY
cv.THRESH BINARY INV
cv.THRESH TRUNC
cv.TOZERO
cv.TOZERO INV

有以上五种,处理的取值逻辑如下所示。
不同阈值方法计算逻辑

import numpy as np
import cv2

#生成一个渐变的灰度图像im1->灰度从0到250
im1 = np.ones((500,500), np.uint8)
for i in range(500):
    for j in range(250):
            im1[i][2*j] = im1[i][2*j-1] = j

#分别采用不同阈值处理方法,并显示
thresh, maxv = 100, 255
_, im2 = cv2.threshold(im1, thresh, maxv, cv2.THRESH_BINARY)
_, im3 = cv2.threshold(im1, thresh, maxv, cv2.THRESH_BINARY_INV)
_, im4 = cv2.threshold(im1, thresh, maxv, cv2.THRESH_TOZERO)
_, im5 = cv2.threshold(im1, thresh, maxv, cv2.THRESH_TOZERO_INV)
_, im6 = cv2.threshold(im1, thresh, maxv, cv2.THRESH_TRUNC)

img = [im1, im2, im3, im4, im5, im6]

for item in range(len(img)):
    cv2.imshow('im'+ str(int(item)+1), img[item])
k = cv2.waitKey(0)
if k == ord('s'):
    cv2.destroyAllWindows()

固定阈值处理结果

自适应阈值过滤

使用 cv2.adaptiveThreshold() 函数,自适应阈值区分与上一小节的全局阈值,自适应阈值的方法是在一个小范围内选取一个阈值进行筛选。

dst = cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst])
参数介绍
src8位单通道的源图像(灰度图像)
maxValue赋予满足条件的像素的灰度值
maxval赋予满足条件的像素的灰度值
adaptiveMehtod使用的自适应阈值方法,有两种 cv2.ADAPTIVE_THRESH_MEAN_Ccv2.ADAPTIVE_THRESH_GAUSSIAN_C
blockSize每次自适应计算的像素区域大小(只能是奇数,如3、5、11、17)
C这个参数与指定的方法有关

两种阈值方法略有区别,首先相同点在于计算的领域都是一个大小为 blockSize×blockSize 的矩形范围内,区别在于 MEANS 是取的周围所有的点的平均值与阈值作比较,而 GAUSSIAN 则是加权平均值,权值的大小和离中心像素点的距离有关。
blockSize 取值越大图像每次操作的区域越大,细节保留越少,同时边框感也越强。
C 的取值越小处理后的图像边框感越强,整体的轮廓很明显;反之取值越大,图像的许多细节会被过滤去。

import cv2
import numpy as np

#读取图片
im1 = cv2.imread('fruit_test.jpg',0)
#下条可根据需要选用,调整图片大小
im1 = cv2.resize(im1, None, fx=0.2, fy=0.2, interpolation=cv2.INTER_AREA)

#输出blockSize不同的MEAN阈值,命名为im_mean_x
for i in range(10):
    name = 'im_mean'+str(i)
    cv2.imshow(name,cv2.adaptiveThreshold(im1, 127, 
    cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, int(i)*2+3, 11))

#输出blockSize不同的GUASSIAN阈值,命名为im_guas_x
for i in range(10):
    name = 'im_guas'+str(i)
    cv2.imshow(name,cv2.adaptiveThreshold(im1, 127, 
    cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, int(i)*2+3, 11))
k = cv2.waitKey(0)
if k == ord('s'):

自适应阈值过滤结果

Otsu阈值过滤(大津法)

大津法(Otsu)是由日本学者大津展之( Nobuyuki Otsu )提出的一种自适应阈值处理方法,这是求解全局阈值的最佳方法,且计算简单,对于仅存在双峰的图像效果非常好。
其实大津法是在全局阈值上的一种改进,在固定的全局阈值中靠肉眼观测并不能直接找到最佳的阈值是在哪个位置,所以通常的方法都是不断地尝试,直到找到一个合适的阈值。大津法则是帮助我们直接找到一个合适的阈值,它会从图像的灰度直方图中计算出一个合适的阈值,对双峰图像处理效果最好,而非双峰图像所取的阈值可能不准确。
具体的操作方法如下说明与代码所示。

说明: 仍然使用的是 cv2.threshold() 函数,但是阈值选取的为0,并且在后续的阈值方法中添加 cv2.THRESH_OSTU 即可。

import cv2
import numpy as np

#读取图片
im1 = cv2.imread('t5.jpg',0)
#下条可根据需要选用,调整图片大小
im1 = cv2.resize(im1, None, fx=0.3, fy=0.3, interpolation=cv2.INTER_AREA)
#阈值为127的固定阈值法
ret1, th1 = cv2.threshold(im1, 127, 255, cv2.THRESH_BINARY)
#OTSU阈值法
ret2, th2 = cv2.threshold(im1, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
#显示
img = [im1, th1, th2]
for i in range(len(img)):
    cv2.imshow('im'+str(i+1), img[i])

k = cv2.waitKey(0)
if k == ord('s'):
    cv2.destroyAllWindows() 

大津法和固定阈值法的对比
请添加图片描述
附封面一张~

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小聪民

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值