坐看云起时|

一枚码农

园龄:7年6个月粉丝:5关注:1

opencv-python 4.3. 图像阈值

简单阈值处理

这种阈值处理的方法是简单易懂的。如果像素值大于阈值,则为其分配一个值(可以是白色),否则为其分配另一个值(可以是黑色)。使用的函数是cv.threshold。函数第一个参数是源图像,它应该是灰度图像。第二个参数是用于对像素值进行分类的阈值。第三个参数是maxVal,它表示如果像素值大于(有时小于)阈值则要给出的值。OpenCV提供不同类型的阈值,由函数的第四个参数决定。不同的类型有:

  • cv.THRESH_BINARY - 二进制阈值。把亮的处理成白色,暗的处理成黑色
  • cv.THRESH_BINARY_INV - 反二进制阈值。把亮的处理成黑色,暗的处理成白色
  • cv.THRESH_TRUNC - 截断阈值。亮的不能太亮,有上限,暗的不变
  • cv.THRESH_TOZERO threshold - 阈值化为0,比较亮的部分不变,比较暗的部分处理成黑色为0
  • cv.THRESH_TOZERO_INV threshold - 反阈值化为0,把比较亮的部分处理成0成黑色,小于等于阈值的像素点不变

函数将获得两个输出。第一个是retavl,它是用来进行Otsu's二值化,将在后面解释它的作用。第二个输出是我们的阈值图像。

import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\bg.jpg', 0)
rows, cols = img.shape

ret1, thresh1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
ret2, thresh2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)
ret3, thresh3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC)
ret4, thresh4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO)
ret5, thresh5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV)

titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, 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()

image

自适应阈值处理

在上面,我们使用全局值作为阈值,但在图像在不同区域具有不同照明条件的所有条件下可能并不好。在那种情况下,我们进行自适应阈值处理,算法计算图像的小区域的阈值,所以我们对同一幅图像的不同区域给出不同的阈值,这给我们在不同光照下的图像提供了更好的结果。
这种阈值处理方法有三个指定输入参数和一个输出参数。
Adaptive Method - 自适应方法,决定如何计算阈值。

  • cv.ADAPTIVE_THRESH_MEAN_C:阈值是邻域的平均值。
  • cv.ADAPTIVE_THRESH_GAUSSIAN_C:阈值是邻域值的加权和,其中权重是高斯窗口。

Block Size - 邻域大小,它决定了阈值区域的大小。
C - 它只是从计算的平均值或加权平均值中减去的常数。

import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\bg2.jpg', 0)

# 使用中值滤波模糊图像 中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的中值代替
img = cv.medianBlur(img, 5)

ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
th2 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 11, 2)
th3 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.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 range(4):
    plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])

plt.show()

image

Otsu's 二值化

在第一节中,我只告诉你另一个参数是retVal,但没告诉你它的作用。其实,它是用来进行Otsu's二值化。

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

为此,使用了我们的cv.threshold()函数,但是需要多传递一个参数cv.THRESH_OTSU。这时要吧阈值设为零。然后算法找到最佳阈值并返回第二个输出retVal。如果未使用Otsu二值化,则retVal与你设定的阈值相同。

请查看以下示例。输入图像是嘈杂的图像。在第一种情况下,我将全局阈值应用为值127。在第二种情况下,我直接应用了Otsu的二值化。在第三种情况下,我使用5x5高斯卷积核过滤图像以消除噪声,然后应用Otsu阈值处理。来看看噪声过滤如何改善结果。

import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread(r'C:\Users\yuyalong\Pictures\Saved Pictures\noise.jpg', 0)

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

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

# Otsu's thresholding after Gaussian filtering
blur = cv.GaussianBlur(img, (5, 5), 0)
ret3, th3 = cv.threshold(blur, 0, 255, cv.THRESH_BINARY + cv.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 range(3):
    plt.subplot(3, 3, i * 3 + 1), plt.imshow(images[i * 3], 'gray')
    plt.title(titles[i * 3]), plt.xticks([]), plt.yticks([])

    # plt.hist 将一个大区间划分为等间隔的小区间,并统计每个区间上样本出现的频数之和
    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()

image

本文作者:一枚码农

本文链接:https://www.cnblogs.com/yimeimanong/p/17265444.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   一枚码农  阅读(49)  评论(0编辑  收藏  举报
历史上的今天:
2022-03-28 django使用celery
2019-03-28 STM32单片机复位后GPIO电平状态
 
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 Sold Out Hawk
  2. 2 光辉岁月 Beyond
光辉岁月 - Beyond
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 黄家驹

作曲 : 黄家驹

编曲 : Beyond

制作人 : Beyond/Gordon O'Yang

Synth Programming : Gordon O'Yang / 叶世荣

Mixed by Philip Kwok

钟声响起归家的讯号

钟声响起归家的讯号

在他生命里

仿佛带点唏嘘

黑色肌肤给他的意义

是一生奉献 肤色斗争中

年月把拥有变做失去

疲倦的双眼带着期望

今天只有残留的躯壳

迎接光辉岁月

风雨中抱紧自由

一生经过彷徨的挣扎

自信可改变未来

问谁又能做到

可否不分肤色的界限

可否不分肤色的界限

愿这土地里

不分你我高低

缤纷色彩闪出的美丽

是因它没有

分开每种色彩

年月把拥有变做失去

疲倦的双眼带着期望

今天只有残留的躯壳

迎接光辉岁月

风雨中抱紧自由

一生经过彷徨的挣扎

自信可改变未来

问谁又能做到

今天只有残留的躯壳

今天只有残留的躯壳

迎接光辉岁月

风雨中抱紧自由

一生经过彷徨的挣扎

自信可改变未来

问谁又能做到

Woo

Ah

Ah

今天只有残留的躯壳

今天只有残留的躯壳

迎接光辉岁月

风雨中抱紧自由

一生经过彷徨的挣扎

自信可改变未来

问谁又能做到

Woo

Ah

Ah

今天只有残留的躯壳

今天只有残留的躯壳

迎接光辉岁月

风雨中抱紧自由

一生经过彷徨的挣扎

自信可改变未来