opencv 阈值处理

 

在使用opencv进行滤波时会考虑到中值滤波,全局虑波,局部滤波,ostu滤波等。

一 全局阈值


函数:threshold(src, thresh, maxval, type, dst=None),返回两个值retVal(阈值) 和 threshImg(处理后的图像)

函数中四个参数分别是原图像、阈值、最大值、阈值类型 

阈值类型一般分为五种: 

cv2.THRESH_BINARY:大于阈值的部分像素值变为maxval,其他变为0 
cv2.THRESH_BINARY_INV:大于阈值的部分变为0,其他部分变为最大值 
cv2.THRESH_TRUNC:大于阈值的部分变为阈值,其余部分不变 
cv2.THRESH_TOZERO:大于阈值的部分不变,其余部分变为0 
cv2.THRESH_TOZERO_INV:大于阈值的部分变为0,其余部分不变

二 局部阈值



在前面的部分我们使用是全局阈值,整幅图像采用同一个数作为阈值。当时这种方法并不适应与所有情况,尤其是当同一幅图像上的不同部分的具有不同亮度时。这种情况下我们需要采用自适应阈值。此时的阈值是根据图像上的每一个小区域计算与其对应的阈值。因此在同一幅图像上的不同区域采用的是不同的阈值,从而使我们能在亮度不同的情况下得到更好的结果。

adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)
这种方法需要我们指定六个参数,返回值只有一个。

• Adaptive Method- 指定计算阈值的方法。
– cv2.ADPTIVE_THRESH_MEAN_C:阈值取自相邻区域的平均值
 cv2.ADPTIVE_THRESH_GAUSSIAN_C:阈值取值相邻区域的加权和,权重为一个高斯窗口。
 Block Size - 邻域大小(用来计算阈值的区域大小)。
 C - 这就是是一个常数,阈值就等于的平均值或者加权平均值减去这个常数。

C的常用计算方法有两种:

1.平均值减去差值delta(使用盒过滤boxfilter,性能会非常不错)

2.高斯分布加权和减去差值delta (使用高斯滤波GaussionBlur)

python中源码



import cv2
import numpy as np


# 全局阈值
def threshold_demo(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # ret, binary = cv2.threshold(gray,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    # ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_TRIANGLE)
    # ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_TRUNC)
    ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    print("阈值:", ret)
    cv2.imshow("binary", binary)


# 局部阈值
def local_threshold(image):
    gray = cv2.cvtColor(image,cv2.COLOR_BGRA2GRAY)
    #binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,25,10)
    binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 25, 10)
    cv2.imshow("binary ", binary)


def custom_threshold(image):
    gray = cv2.cvtColor(image,cv2.COLOR_BGRA2GRAY)
    h, w = gray.shape[:2]
    m = np.reshape(gray, [1, w*h])
    mean = m.sum()/(w*h)
    # binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,25,10)
    ret, binary = cv2.threshold(gray, mean, 255, cv2.THRESH_BINARY)
    cv2.imshow("binary ", binary)


if __name__ == "__main__":
    img = cv2.imread("h.jpg")
    cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE)
    cv2.imshow("input image", img)
    local_threshold(img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
meancgauss7.png



总结 :在图像分割中,目标和背景对比度较强的时候,使用自适应阈值效果不错。

sitemap