OpenCV计算机视觉 —— 图像的阈值处理与自适应阈值Otsu

Posted 一只会飞的猪️

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV计算机视觉 —— 图像的阈值处理与自适应阈值Otsu相关的知识,希望对你有一定的参考价值。

阈值处理是指剔除图像内像素高于阈值或者低于阈值的像素点图像的阈值处理主要是设置一个阈值:大于这个数赋予一个值,小于一个数赋予另一个值,将图片的像素值变成两个灰度值数中间的一个,实现图像的分割。图像阈值化分割是一种传统的最常用的图像分割方法,因其实现简单、计算量小、性能较稳定而成为图像分割中最基本和应用最广泛的分割技术。

目录

1、图像阈值处理函数threshold()介绍

 2、常见的5大阈值处理方法

3、自适应阈值与Otsu处理

自适应阈值处理

Otsu处理


1、图像阈值处理函数threshold()介绍

进行阈值处理主要使用OpenCV库中的cv.threshold()函数

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

src:输入的图片

thresh:阈值

maxval:最大阈值,只对THRESH_BINARY和THRESH_BINARY_INV有用

type:主要有以下几种类型:

 对应的类型解释如下:(图片来自OpenCV threshold函数详解_Leenux0810的博客-CSDN博客_opencv threshold

 2、常见的5大阈值处理方法

五大阈值处理方法主要是二值化阈值处理(cv.THRESH_BINARY)、反二值化处理(cv.THRESH_BINARY_INV)、截断阈值化处理(cv.THRESH_TRUNC)、超阈值化零处理(cv.THRESH_TOZERO_INV)、低阈值零处理(cv.THRESH_TOZERO)。五大阈值处理方法,都是通过每个点的像素值与阈值进行比较,然后赋予一个固定的像素值,实现图像的分割,具体意义见上表。废话不多说,先看代码:

import cv2 as cv

# 读取图片
img = cv.imread('zzf10.jpg')
img = cv.resize(img, None, fx=0.4, fy=0.4)
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.imshow('img', img)


# 图像的二值化阈值处理
t, img1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
cv.imshow('THRESH_BINARY', img1)

# 图像的反二值化阈值处理
t, img2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)
cv.imshow('THRESH_BINARY_INV', img2)

#  图像的截断阈值化处理
t, img3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC)
cv.imshow('THRESH_TRUNC', img3)

# 图像的低阈值化零处理
t, img4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO)
cv.imshow('THRESH_TOZERO', img4)

# 图像的超阈值化零处理
t, img5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV)
cv.imshow('THRESH_TOZERO_INV', img5)

cv.waitKey(0)
cv.destroyAllWindows()

运行结果如下:

二值化阈值处理是比较每个点的阈值,大于thresh的赋予maxval,小于thresh的赋予0;反二值化阈值处理,大于thresh的赋予0,小于thresh的赋予thresh;截断阈值化处理,大于thresh的赋予阈值,小于thresh的保持原像素值;超阈值化零处理,大于thresh的赋予0,小于thresh的保持原像素值;低阈值化零处理,大于thresh的保持原像素值,小于thresh的赋予0。图像效果比较明显,各个操作的具体作用大家可以自己去了解一下。

那么问题来了,我们的阈值处理处理的是灰度图,那么能处理彩色图吗?处理的效果是什么呢?只需要将上面的图片灰度化注释掉即可,运行结果如下:

大家可以看出来,这好像和阈值处理的目的和特点不相符合。我查找了一些资料也不太明白为什么是这样。但是我有一些自己的想法,我认为,图片的阈值化处理,是和单个数据比较大小,那么就应该在一维的单通道图片进行比较;而彩色图是三通道,可能是在某一个通道处理,或者是多个通道处理。具体的阈值比较方法不清楚,所以和阈值处理所介绍的效果和目的大相径庭 。大家有什么想法可以在评论区进行讨论哦!

3、自适应阈值与Otsu处理

自适应阈值处理

自适应阈值分割也叫做局部阈值化它是根据像素的邻域块的像素值分布来确定该像素位置上的阈值。 这样做的好处在于每个像素位置处的阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。 亮度较高的图像区域的阈值通常会较高,而亮度较低的图像区域的阈值则会相适应地变小。当图像的色彩不均衡时,只用一个阈值不能有效清晰的分割图像,所以需要自适应阈值处理。

具体的操作需要使用cv.adaptiveThreshold()函数进行自适应阈值处理,具体参数介绍如下:

cv.adaptiveThreshold(src,maxValue,adaptiveMethod,thresholdType,blockSize,C,dst=None)

src:输入的图像

maxValue:最大值

adaptiveMethod:自适应的方法有两种,一种是cv.ADAPTIVE_THRESH_MEAN_C,领域内的像素值的权值一样;另一种是cv.ADAPTIVE_THRESH_GAUSSIAN_C,领域内的像素值的权值不同,与到中心的距离有关系,呈现高斯分布,通过高斯方程得到各个点的权重。

thresholdType:代表阈值处理的方法,该值必须是cv.THRESH_BINARY或者cv.THRESH_BINARY_INV中的一个

blockSize:块的大小,计算阈值使用的尺寸,3,5,7等

C:常量对每个blockSize所指定的领域的加权平均值减去常量C

具体代码如下:

import cv2 as cv

img = cv.imread('zzf10.jpg')
img = cv.resize(img, None, fx=0.3, fy=0.3)
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.imshow('img_', img)

# 图像二值化阈值处理
t, img1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)

# 采用领域像素点权重一致的方法自适应阈值
img2 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 5, 3)

# 采用领域像素点权重通过高斯方程计算权值的方法自适应阈值
img3 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 5, 3)

cv.imshow('THRESH_BINARY', img1)
cv.imshow('ADAPTIVE_THRESH_MEAN_C', img2)
cv.imshow('ADAPTIVE_THRESH_GAUSSIAN_C', img3)

cv.waitKey(0)
cv.destroyAllWindows()

运行结果如下图:

可以看的出来自适应阈值分割相对于二值化阈值分割来说,能分割出更多的细节和特征 。在图像中设置多个阈值,能更好的对图像的各个区域的像素值进行处理,分割效果更好。

Otsu处理

当我们在对图像进行cv.threshold()阈值处理时,这个阈值往往是自己随机设置的,并不能很好的对图像进行分割。阈值的选取在阈值处理、图像分割中至关重要。Otsu处理可以再遍历所有的像素值找到最好的类间分割阈值,然后进行cv.threshold操作。具体代码如下:

import cv2 as cv

img = cv.imread('zzf10.jpg')
img = cv.resize(img, None, fx=0.3, fy=0.3)
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.imshow('img', img)

# 图像二值化阈值处理
t, img1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)

# 采用Otsu处理的二值化阈值处理
t2, img2 = cv.threshold(img, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU)

cv.imshow('THRESH_BINARY', img1)
cv.imshow('OTSU', img2)
cv.waitKey(0)
cv.destroyAllWindows()

运行结果如下:

 

可以看得到Otsu处理得到的阈值是145,且分割效果要比普通的二值化处理要好,图片更加清晰,特征更加分明。

总结:本文讲述了图像阈值处理的五种基本方法,同时介绍了自适应阈值方法,针对基本图像阈值处理采用Otsu获取迭代出最佳类间分割阈值,得到最好的阈值处理效果,使得图像分割出的特征更加明显有效。

以上是关于OpenCV计算机视觉 —— 图像的阈值处理与自适应阈值Otsu的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV-Python实战——OpenCV用于图像分割的阈值技术(含大量示例,建议收藏)

scikit-image 中用于图像分割的阈值算法

何为计算机视觉?计算机视觉与数字图像处理的区别Opencv的起源。

何为计算机视觉?计算机视觉与数字图像处理的区别Opencv的起源。

计算机视觉OpenCV 4高级编程与项目实战(Python版):图像处理基础

计算机视觉OpenCV 4高级编程与项目实战(Python版):图像处理基础