在一般的视觉视觉颜色是由RGB组成的,为了简化处理的视觉的复杂度,以及得到分割出指定物体的特征形状,通过二值化的方法更加的高效方便
二值化定义:图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果
二值化分割定义:一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(Binarization)。
1.简单的阈值-(全局阈值):cv2.threshold(src, thresh, maxval, type, dst=None)->retval,dst
参数:
src: 指原图像,原图像应该是灰度图
thresh:二值化的阈值
maxval:超过thresh的像素值设置的最大值
type:二值化的方法操作
1)二进制阈值化 THRESH_BINARY
3)截断阈值化 THRESH_TRUNC
阈值化为0 THRESH_TOZERO
反阈值化为0 THRESH_TOZERO_INV
6)大津阈值算法(OTSU):
简介:大津法(OTSU)可以根据图像特性,选择最佳的阈值,不需要人为提供阈值,故它也被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响。从大津法的原理上来讲,该方法又称作最大类间方差法,按照大津法求得的阈值进行图像二值化分割后,前景与背景图像的类间方差最大。适合处理所需提取的前景图像和背景图像差距较大的图像。其函数也十分简单,只需要把阈值thresh设置为0,然后设置type为cv2.THRESH_BINARY+cv2.THRESH_OTSU,会自动返回一个合适的阈值。
ret2,th2 =cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
dst - 输出数组/图像(与src相同大小和类型以及相同通道数的数组/图像)
返回值:
2.局部阈值法 : 当图像的色彩分布不均衡时,使用全局阈值处理的效果不是很好,这是使用局部阈值处理来进行分割,可以产生很好的效果。
局部阈值的处理原理是,针对每一个像素点专门配置一个阈值来进行处理,这些阈值就构成了和原图像维度相同的矩阵。
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)
参数:
灰度图像上每个像素的颜色值又称为灰度,指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0。所谓灰度值是指色彩的浓淡程度,灰度直方图是指一幅数字图像中,对应每一个灰度值统计出具有该灰度值的象素数。
图像灰度化处理有以下几种方式:
cvtColor(src, code, dst=None, dstCn=None)->gray_image
参数:
返回值:
源代码:
import cv2
import numpy as np
"""
二值化进行图像的背景分割:
1.全局阈值
2.局部阈值:表示自适应阈值算法,平均 (ADAPTIVE_THRESH_MEAN_C)或高斯(ADAPTIVE_THRESH_GAUSSIAN_C)
3.用户自己计算阈值:中值法计算阈值
4.HSV阈值的计算
"""
def nothing(*arg):
pass
# 全局阈值
def threshold_demo(image, threshold_value):
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # 把输入图像灰度化
# 直接阈值化(对输入的单通道矩阵逐像素进行阈值分割)表示的是二值化结合TRIANGLE法,全局自适应阈值,第二个参数值0可改为任意数字但不起作用,适用于单个波峰。
ret, binary = cv2.threshold(gray, threshold_value, 255, cv2.THRESH_BINARY)
print("threshold value %s" % ret)
cv2.namedWindow("binary0", cv2.WINDOW_NORMAL)
cv2.imshow("binary0", binary)
# 局部阈值:表示自适应阈值算法,平均 (ADAPTIVE_THRESH_MEAN_C)或高斯(ADAPTIVE_THRESH_GAUSSIAN_C)。
def local_threshold(image):
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # 把输入图像灰度化
# 自适应阈值化能够根据图像不同区域亮度分布,改变阈值
# 第三个参数必须为THRESH_BINARY或THRESH_BINARY_INV的阈值类型
# 第四个参数blockSize参数表示块大小(奇数且大于1,比如3,5,7........ )。
# 最后一个参数是常数,表示从平均值或加权平均值中减去的数
# 补充:在使用平均和高斯两种算法情况下,通过计算每个像素周围blockSize x blockSize大小像素块的加权均值并减去常量C即可得到自适应阈值。如果使用平均的方法,则所有像素周围的权值相同;如果使用高斯的方法,则每个像素周围像素的权值则根据其到中心点的距离通过高斯方程得到。
binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 25, 10)
cv2.namedWindow("binary1", cv2.WINDOW_NORMAL)
cv2.imshow("binary1", binary)
# 用户自己计算阈值:中值法计算阈值
def custom_threshold(image):
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # 把输入图像灰度化
h, w = gray.shape[:2]
m = np.reshape(gray, [1, w * h])
mean = m.sum() / (w * h)
print("mean:", mean)
ret, binary = cv2.threshold(gray, mean, 255, cv2.THRESH_BINARY)
cv2.namedWindow("binary2", cv2.WINDOW_NORMAL)
cv2.imshow("binary2", binary)
# HSV阈值的调整,这里也可以通过HSV来对图像阈值进行调整
def HSV():
cap = cv2.VideoCapture(0)
# set blue thresh 设置HSV中蓝色、天蓝色范围
lower_blue = np.array([78, 43, 46])
upper_blue = np.array([110, 255, 255])
while True:
# get a frame and show 获取视频帧并转成HSV格式, 利用cvtColor()将BGR格式转成HSV格式,参数为cv2.COLOR_BGR2HSV。
ret, frame = cap.read()
cv2.imshow('Capture', frame)
# change to hsv model
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# get mask 利用inRange()函数和HSV模型中蓝色范围的上下界获取mask,mask中原视频中的蓝色部分会被弄成白色,其他部分黑色。
mask = cv2.inRange(hsv, lower_blue, upper_blue)
cv2.imshow('Mask', mask)
# detect blue 将mask于原视频帧进行按位与操作,则会把mask中的白色用真实的图像替换:
res = cv2.bitwise_and(frame, frame, mask=mask)
cv2.imshow('Result', res)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
cv2.namedWindow('colorThreshold')
cv2.createTrackbar('threshold_value', 'colorThreshold', 0, 255, nothing)
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
threshold_value = cv2.getTrackbarPos('threshold_value', 'colorThreshold')
threshold_demo(frame, threshold_value)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()