Opencv-Python | 图像阈值处理及代码实现

目录

1、简单阈值处理

(1)函数介绍

(2)代码实现

2、 自适应阈值

(1)函数介绍

(2)代码实现

3、Outs二值化处理

(1)基础介绍

(2)代码实现

        图像的二值化或阈值化 (Binarization) 旨在提取图像中的目标物体,将背景以及噪声区分开来。通常会设定一个阈值T,通过阈值将图像的像素划分为两类:大于阈值的像素群和小于阈值的像素群。 灰度转换处理后的图像中,每个像素都只有一个灰度值,其大小表示明暗程度。二值化处理可以将图像中的像素划分为两类颜色

1、简单阈值处理

(1)函数介绍

ret, dst = cv2.threshold(src, thresh, maxval, type)
        src: 输入图,只能输入单通道图像,通常来说为灰度图
        dst: 输出图
        thresh: 阈值
        maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
        type:二值化操作的类型,包含以下5种类型: cv2.THRESH_BINARY;         cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC;         cv2.THRESH_TOZERO; cv2.THRESH_TOZERO_INV
        cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0
        cv2.THRESH_BINARY_INV THRESH_BINARY的反转
        cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变
        cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0
        cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转

(2)代码实现

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
def img_show(name, img): # 展示图像函数
    cv2.imshow(name, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
x = np.zeros([255,255])
for i in np.arange(0,255):
     x[:,i] = i
img_x = np.array(x,dtype='uint8')
img_show('img_x',img_x)

ret, thresh1 = cv2.threshold(img_x, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_x, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img_x, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img_x, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img_x, 127, 255, cv2.THRESH_TOZERO_INV)

titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img_x, thresh1, thresh2, thresh3, thresh4, thresh5]

for i in range(6):
    plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

 下面我们用彩色RGB图像进行演示:
  其中原始RGB三通道图如下图所示:

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
def img_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
img=cv2.imread('chess.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img_gray
img_show('chess',img_gray)
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)

titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img_gray, thresh1, thresh2, thresh3, thresh4, thresh5]

for i in range(6):
    plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

2、 自适应阈值

(1)函数介绍

th2 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY,11,2)

  • 第一个参数(img):源图像
  • th2:输出图像,与源图像大小一致
  • 第三个参数(255):超过阈值的部分取值是多少(对于cv.THRESH_BINARY而言)
  • 第四个参数(cv.ADAPTIVE_THRESH_MEAN_C):
  • (1)在一个邻域内计算阈值所采用的算法,有两个取值,分别为 ADAPTIVE_THRESH_MEAN_C 和 ADAPTIVE_THRESH_GAUSSIAN_C
  • (2)ADAPTIVE_THRESH_MEAN_C的计算方法是计算出领域的平均值再减去第七个参数2的值。
  • (3)ADAPTIVE_THRESH_GAUSSIAN_C的计算方法是计算出领域的高斯均值再减去第七个参数2的值
  • 第五个参数(cv.THRESH_BINARY):这是阈值类型,只有两个取值,分别为 THRESH_BINARY 和THRESH_BINARY_INV
  • 第六个参数(11):adaptiveThreshold的计算单位是像素的邻域块大小选择,这是局部邻域大小,3、5、7等
  • 第七个参数(2):这个参数实际上是一个偏移值调整量,用均值和高斯计算阈值后,再减或加这个值就是最终阈值。

(2)代码实现

img = cv2.imread('chess.jpg',0)
img = cv2.medianBlur(img,5) # 中值滤波
img_show('1',img)
ret,th1 = cv2.threshold(img,127,255,cv.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_MEAN_C,\
            cv2.THRESH_BINARY,11,2)
th3 = cv2.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,\
            cv2.THRESH_BINARY,11,2)

titles = ['Original Image', 'Global Thresholding (v = 127)',
 'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]

for i in np.arange(4):
    plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])
plt.show()

3、Outs二值化处理

(1)基础介绍

在第一部分中,第二个参数retVal(ret)。当我们进行Otsu的二值化时,就会用到它。那是什么?

在全局阈值处理中,我们使用任意值作为阈值,那么,我们如何知道我们选择的值是好还是坏?答案是,试错法。但是考虑一个双峰图像(简单来说,双峰图像是直方图有两个峰值的图像)。对于该图像,我们可以近似地将这些峰值中间的一个值作为阈值,这就是Otus二值化所做的。所以简单来说,它会自动从图像直方图中计算出双峰图像的阈值。(对于非双峰图像,二值化将不准确)

为此,使用了我们的 cv2.threshold() 函数,但传递了一个额外的标志cv2.THRESH_ OTSU。对于阈值,只需传递 zero。然后算法找到最佳阈值并将您作为第二个输出retVal返回。如果不使用Otsu阈值,则 retVal 与您使用的阈值相同。

看看下面的例子。输入图像是噪声图像。在第一种情况下,我为 127 应用了全局阈值。在第二种情况下,我直接应用了Otsu的阈值。在第三种情况下,我使用 5×5 高斯核过滤图像以去除噪声,然后应用 Otsu 阈值。了解噪声过滤如何改善结果。

(2)代码实现

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('noisy.jpg',0)

# global thresholding
ret1,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)

# Otsu's thresholding
ret2,th2 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# Otsu's thresholding after Gaussian filtering
blur = cv2.GaussianBlur(img,(5,5),0)
ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# plot all the images and their histograms
images = [img, 0, th1,
          img, 0, th2,
          blur, 0, th3]
titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)',
          'Original Noisy Image','Histogram',"Otsu's Thresholding",
          'Gaussian filtered Image','Histogram',"Otsu's Thresholding"]

for i in np.arange(3):
    plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')
    plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])
    plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)
    plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([])
    plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')
    plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])
plt.show()

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2022年5月13日
下一篇 2022年5月13日

相关推荐