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

Py-OpenCV学习记录4-阈值过滤,第1张

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

目录
  • 前言
  • 固定阈值过滤
  • 自适应阈值过滤
  • Otsu阈值过滤(大津法)

前言

如前面所提及的,一张图像的信息都被记录在一个矩阵内,其通道数值便是不同点的信息,利用信息对图片进行处理,筛选出所需要的信息,简化图像信息加速后续处理的速度。
在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_CblockSize每次自适应计算的像素区域大小(只能是奇数,如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() 



附封面一张~

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5657948.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存