图像处理时,常常需要将图片二值化。以某个点为区分点,大于它的为一个值,小于它的赋另一个值。 opencv提供了cv.threshold(),处理阈值,并生成阈值处理后的结果。
cv2.threshold()可以产生二值化的结果,也可以产生其它结果。
retval, dst = cv2.threshold(src, thresh, maxval, type)
retval: 代表返回的阈值,也就是此次阈值处理所用的阈值。
dst: 代表阈值分割结果图,与原始图src有相同的大小和类型。
src:代表要进行阈值分割的图片。可以是多通道的,8位或者32位浮点类型。
thresh: 代表要设置的阈值。
maxval: 只有type为:cv2.THRESH_BINARY和cv2.THRESH_BINARY_INV时需要,作为最大值用。(也就是只有二值化时,maxval作为最大值,0作为最小值)
type:代表阈值分割的类型。
使用图示:
详解如下:
1. 二值化阈值处理:cv2.THRESH_BINARY:
会将原始图像处理为仅有两个值的二值图像。
#threshold img_bgr = cv2.imread("images/people.webp", cv2.IMREAD_COLOR) t, rst = cv2.threshold(img_bgr, 127, 255, cv2.THRESH_BINARY) cv2.imshow("ORZ", img_bgr) cv2.imshow("BINARY", rst) cv2.waitKey() cv2.destroyAllWindows()
2. 反二值化阈值处理:cv2.THRESH_BINARY_INV:
反二值化阈值处理与相反,高于阈值的部分设置为0,低于阈值的部分设置为maxval.
img_bgr = cv2.imread("images/people.webp", cv2.IMREAD_COLOR) t, rst = cv2.threshold(img_bgr, 127, 255, cv2.THRESH_BINARY_INV) cv2.imshow("ORZ", img_bgr) cv2.imshow("BINARY", rst) cv2.waitKey() cv2.destroyAllWindows()
3. 截断阈值化处理 cv2.THRESH_TRUNC:
大于阈值的像素点设置为阈值,小于阈值的像素点不变。
img_bgr = cv2.imread("images/people.webp", cv2.IMREAD_COLOR) t, rst = cv2.threshold(img_bgr, 127, 255, cv2.THRESH_TRUNC) cv2.imshow("ORZ", img_bgr) cv2.imshow("BINARY", rst) cv2.waitKey() cv2.destroyAllWindows()
4. 超阈值零处理 cv2.THRESH_TOZERO_INV
5. 低阈值零处理 cv2.THRESH_TOZERO:
6. Otsu处理:
前面所有阈值处理类型,都需要自己设置一个阈值,以此作为图像阈值处理的依据。但在某些情况下,阈值并不好测算。
例如:有些图像的灰度级分布非常不均衡,比如绝大部分在60-70之间,若把阈值设置为127,则明显不符合预期。 需要找到更好的阈值。但阈值的并不是一下就能看出的。若需要手动查找,工作量太大。而Otsu处理则可以自动找出最佳的分割阈值。只需要在type中加入cv2.THRESH_OTSU
A. type中增加cv2.THRESH_OTSU.
B. 设定的阈值为0.
C 返回值t是Otsu方法计算出的最佳阈值。
#threshold img_bgr = cv2.imread("images/people.webp", cv2.IMREAD_GRAYSCALE) t, rst = cv2.threshold(img_bgr, 0, 255, cv2.THRESH_TRUNC+cv2.THRESH_OTSU) print("OTSU :", t) cv2.imshow("ORZ", img_bgr) cv2.imshow("BINARY", rst) cv2.waitKey() cv2.destroyAllWindows()
7. 自适应阈值处理:
不管是指定阈值,还是Otsu找到合适的阈值。都建立在目标图片色彩均衡,用一个阈值就可以很好的处理。 但有些图片色彩不均匀。某个阈值在图片的一部分表现良好,在另一部分则效果不佳。
所以就有了自适阈值处理,它经过计算每一个点周围邻近区域的加权平均作为阈值,并对当前像素点进行处理。
cv2.adaptiveThreshold()