最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

雾看OpenCV(5)——图像阈值

互联网 admin 1浏览 0评论

雾看OpenCV(5)——图像阈值

目录

  • 前言
  • 正文
    • 简单阈值
      • cv2.threshhold()
    • 自适应阈值
      • cv2.adaptiveThreshold
    • Otsu二值化
  • 参考

前言

本节你将学到简单阈值,自适应阈值,Otsu’s 二值化等 • 将要学习的函数有 cv2.threshold,cv2.adaptiveThreshold 等。

正文

简单阈值

与名字一样,这种方法非常简单。但像素值高于阈值时,我们给这个像素 赋予一个新值(可能是白色),否则我们给它赋予另外一种颜色(也许是黑色)。 这个函数就是 cv2.threshhold()。
效果图

code

import cv2
import numpy as np
from matplotlib import pyplot as plt
img=cv2.imread('../images/lena.jpg',0)
ret,thresh1=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
ret,thresh2=cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
ret,thresh3=cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
ret,thresh4=cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
ret,thresh5=cv2.threshold(img,127,255,cv2.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()

cv2.threshhold()

这个函数的第一个参数就是原图像,原图 像应该是灰度图。
第二个参数就是用来对像素值进行分类的阈值。
第三个参数 就是当像素值高于(有时是小于)阈值时应该被赋予的新的像素值。
OpenCV 提供了多种不同的阈值方法,这是有第四个参数来决定的。

这第四个参数的方法我这里列举一些:

cv2.THRESH_BINARY
cv2.THRESH_BINARY_INV
cv2.THRESH_TRUNC
cv2.THRESH_TOZERO
cv2.THRESH_TOZERO_INV

自适应阈值

当同一幅图像上的不同部分的具有不 同亮度时,我们需要采用自适应阈值。此时的阈值是根据图像上的 每一个小区域计算与其对应的阈值。因此在同一幅图像上的不同区域采用的是 不同的阈值,从而使我们能在亮度不同的情况下得到更好的结果。
效果图

code

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt# img = cv2.imread('dave.jpg', 0)
src = cv.imread('../../images/lena.jpg', 0)
# 中值滤波
img = cv.medianBlur(src, 5)
ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)# 11 为 Block size 邻域大小 用来计算阈值的区域大小 ,
# 2 为 C值,常数, 阈值就等于的平均值或者加权平均值减去这个常数。
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 = ['Origin Image','Global threshold','Adaptive Gaussian','Adaptive Mean']
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()# cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
# cv.imshow('input image', src)
cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口cv.destroyAllWindows()

cv2.adaptiveThreshold

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

1.src:原图像
2. maxValue:满足条件的像素点需要设置的灰度值。(将要设置的灰度值)
3. adaptiveMethod:自适应阈值算法。可选ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C

4. blockSize:要分成的区域大小,上面的N值,一般取奇数
5. C:常数,每个区域计算出的阈值的基础上在减去这个常数作为这个区域的最终阈值,可以为负数
6. dst=None:输出图像,可以忽略

Otsu二值化

如果是一副双峰图像(简 单来说双峰图像是指图像直方图中存在两个峰)呢?我们岂不是应该在两个峰 之间的峰谷选一个值作为阈值?这就是 Otsu 二值化要做的。简单来说就是对 一副双峰图像自动根据其直方图计算出一个阈值。
效果图

code

import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltsrc = cv.imread("../../images/noisy2.png")
img = cv.cvtColor(src,cv.COLOR_BGR2GRAY)
## 全局阈值
ret1,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
## OTSU阈值
ret,th2 = cv.threshold(img,0,255,cv.THRESH_BINARY + cv.THRESH_OTSU)
blur = cv.GaussianBlur(img,(5,5),0)#阈值一定要设为0
ret3,th3 = cv.threshold(blur,0,255,cv.THRESH_BINARY + cv.THRESH_OTSU)images = [src, 0, th1,src, 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.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([])print(i)
plt.show()# cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
# cv.imshow('input image', src)
# cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
#
# cv.destroyAllWindows()

参考

雾看OpenCV(5)——图像阈值

目录

  • 前言
  • 正文
    • 简单阈值
      • cv2.threshhold()
    • 自适应阈值
      • cv2.adaptiveThreshold
    • Otsu二值化
  • 参考

前言

本节你将学到简单阈值,自适应阈值,Otsu’s 二值化等 • 将要学习的函数有 cv2.threshold,cv2.adaptiveThreshold 等。

正文

简单阈值

与名字一样,这种方法非常简单。但像素值高于阈值时,我们给这个像素 赋予一个新值(可能是白色),否则我们给它赋予另外一种颜色(也许是黑色)。 这个函数就是 cv2.threshhold()。
效果图

code

import cv2
import numpy as np
from matplotlib import pyplot as plt
img=cv2.imread('../images/lena.jpg',0)
ret,thresh1=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
ret,thresh2=cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
ret,thresh3=cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
ret,thresh4=cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
ret,thresh5=cv2.threshold(img,127,255,cv2.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()

cv2.threshhold()

这个函数的第一个参数就是原图像,原图 像应该是灰度图。
第二个参数就是用来对像素值进行分类的阈值。
第三个参数 就是当像素值高于(有时是小于)阈值时应该被赋予的新的像素值。
OpenCV 提供了多种不同的阈值方法,这是有第四个参数来决定的。

这第四个参数的方法我这里列举一些:

cv2.THRESH_BINARY
cv2.THRESH_BINARY_INV
cv2.THRESH_TRUNC
cv2.THRESH_TOZERO
cv2.THRESH_TOZERO_INV

自适应阈值

当同一幅图像上的不同部分的具有不 同亮度时,我们需要采用自适应阈值。此时的阈值是根据图像上的 每一个小区域计算与其对应的阈值。因此在同一幅图像上的不同区域采用的是 不同的阈值,从而使我们能在亮度不同的情况下得到更好的结果。
效果图

code

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt# img = cv2.imread('dave.jpg', 0)
src = cv.imread('../../images/lena.jpg', 0)
# 中值滤波
img = cv.medianBlur(src, 5)
ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)# 11 为 Block size 邻域大小 用来计算阈值的区域大小 ,
# 2 为 C值,常数, 阈值就等于的平均值或者加权平均值减去这个常数。
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 = ['Origin Image','Global threshold','Adaptive Gaussian','Adaptive Mean']
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()# cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
# cv.imshow('input image', src)
cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口cv.destroyAllWindows()

cv2.adaptiveThreshold

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

1.src:原图像
2. maxValue:满足条件的像素点需要设置的灰度值。(将要设置的灰度值)
3. adaptiveMethod:自适应阈值算法。可选ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C

4. blockSize:要分成的区域大小,上面的N值,一般取奇数
5. C:常数,每个区域计算出的阈值的基础上在减去这个常数作为这个区域的最终阈值,可以为负数
6. dst=None:输出图像,可以忽略

Otsu二值化

如果是一副双峰图像(简 单来说双峰图像是指图像直方图中存在两个峰)呢?我们岂不是应该在两个峰 之间的峰谷选一个值作为阈值?这就是 Otsu 二值化要做的。简单来说就是对 一副双峰图像自动根据其直方图计算出一个阈值。
效果图

code

import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltsrc = cv.imread("../../images/noisy2.png")
img = cv.cvtColor(src,cv.COLOR_BGR2GRAY)
## 全局阈值
ret1,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
## OTSU阈值
ret,th2 = cv.threshold(img,0,255,cv.THRESH_BINARY + cv.THRESH_OTSU)
blur = cv.GaussianBlur(img,(5,5),0)#阈值一定要设为0
ret3,th3 = cv.threshold(blur,0,255,cv.THRESH_BINARY + cv.THRESH_OTSU)images = [src, 0, th1,src, 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.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([])print(i)
plt.show()# cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)
# cv.imshow('input image', src)
# cv.waitKey(0)  # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
#
# cv.destroyAllWindows()

参考

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论