阈值在计算机视觉中有许多应用,并且通常在许多处理管道的初始阶段执行。有几种类型的阈值算法。让我们关注“全局”阈值。
文章包括以下几个部分:
- 1.全局阈值法
- 2.二值化
- 3.反二值化
- 4.截断阈值
- 5.零阈值
- 6.反零阈值
1.全局阈值法
那么,什么是“全局”阈值?当阈值规则均等地应用于图像中的每个像素,且阈值固定时,称为全局操作。
全局阈值算法以源图像(src)和阈值(thresh)为输入,通过比较源像素位置(x,y)的像素强度与阈值产生输出图像(dst)。如果src(x,y) > thresh,则dst(x,y)被赋值。否则,dst(x,y)被赋给其他值。
全局阈值的最简单形式称为二值化。
- 除了源图像(src)和阈值(thresh)之外,它还接受另一个称为最大值(maxValue)的输入参数。
- 在每个像素位置(x,y),该位置的像素强度与一个阈值(thresh)进行比较。如果src(x,y)大于thresh,则阈值操作将目标图像像素dst(x,y)的值设置为maxValue。否则,它将它设为0。
对src(x,y)应用不同的阈值规则得到dst(x,y)。在这里,我们将检查OpenCV中可用的五种不同的阈值类型。
(1)Python
import cv2import copy# 读取图片src = cv2.imread("input_image.jpg", cv2.IMREAD_GRAYSCALE);src_copy = copy.deepcopy(src)cv2.putText(src_copy, "input_image.jpg", (20, 20), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.5, color=(250, 225, 100))cv2.imwrite("opencv_input_image.jpg", src_copy);# 基本阈值例子src_copy = copy.deepcopy(src)th, dst = cv2.threshold(src_copy, 0, 255, cv2.THRESH_BINARY);cv2.putText(dst, "opencv-threshold-example.jpg", (20, 20), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.5, color=(250, 225, 100))cv2.imwrite("opencv-threshold-example.jpg", dst);# maxValue设置为128的阈值src_copy = copy.deepcopy(src)th, dst = cv2.threshold(src_copy, 0, 128, cv2.THRESH_BINARY);cv2.putText(dst, "opencv-thresh-binary-maxval.jpg", (20, 20), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.5, color=(250, 225, 100))cv2.imwrite("opencv-thresh-binary-maxval.jpg", dst);# 阈值设置为127src_copy = copy.deepcopy(src)th, dst = cv2.threshold(src_copy, 127, 255, cv2.THRESH_BINARY);cv2.putText(dst, "opencv-thresh-binary.jpg", (20, 20), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.5, color=(250, 225, 100))cv2.imwrite("opencv-thresh-binary.jpg", dst);# 阈值使用THRESH_BINARY_INVsrc_copy = copy.deepcopy(src)th, dst = cv2.threshold(src_copy, 127, 255, cv2.THRESH_BINARY_INV);cv2.putText(dst, "opencv-thresh-binary-inv.jpg", (20, 20), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.5, color=(10, 5, 10))cv2.imwrite("opencv-thresh-binary-inv.jpg", dst);# 阈值使用THRESH_TRUNCsrc_copy = copy.deepcopy(src)th, dst = cv2.threshold(src_copy, 127, 255, cv2.THRESH_TRUNC);cv2.putText(dst, "opencv-thresh-trunc.jpg", (20, 20), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.5, color=(250, 225, 100))cv2.imwrite("opencv-thresh-trunc.jpg", dst);# 阈值使用THRESH_TOZEROsrc_copy = copy.deepcopy(src)th, dst = cv2.threshold(src_copy, 127, 255, cv2.THRESH_TOZERO);cv2.putText(dst, "opencv-thresh-tozero.jpg", (20, 20), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.5, color=(250, 225, 100))cv2.imwrite("opencv-thresh-tozero.jpg", dst);# 阈值使用THRESH_TOZERO_INVsrc_copy = copy.deepcopy(src)th, dst = cv2.threshold(src_copy, 127, 255, cv2.THRESH_TOZERO_INV);cv2.putText(dst, "opencv-thresh-to-zero-inv.jpg", (20, 20), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.5, color=(250, 225, 100))cv2.imwrite("opencv-thresh-to-zero-inv.jpg", dst); (2)C++
#include "opencv2/opencv.hpp"using namespace cv;using namespace std;int main( int argc, char** argv ){ // 读取 Mat src = imread("threshold.png", IMREAD_GRAYSCALE); Mat dst; // 基本的阈值样例 threshold(src,dst,0, 255, THRESH_BINARY); imwrite("opencv-threshold-example.jpg", dst); // maxValue设置为128的阈值 threshold(src, dst, 0, 128, THRESH_BINARY); imwrite("opencv-thresh-binary-maxval.jpg", dst); // 阈值设置为127 threshold(src,dst,127,255, THRESH_BINARY); imwrite("opencv-thresh-binary.jpg", dst); // 阈值使用THRESH_BINARY_INV threshold(src,dst,127,255, THRESH_BINARY_INV); imwrite("opencv-thresh-binary-inv.jpg", dst); // 阈值使用THRESH_TRUNC threshold(src,dst,127,255, THRESH_TRUNC); imwrite("opencv-thresh-trunc.jpg", dst); // 阈值使用THRESH_TOZERO threshold(src,dst,127,255, THRESH_TOZERO); imwrite("opencv-thresh-tozero.jpg", dst); // 阈值使用THRESH_TOZERO_INV threshold(src,dst,127,255, THRESH_TOZERO_INV); imwrite("opencv-thresh-to-zero-inv.jpg", dst); }
在下面的每个示例中,我们将通过伪代码解释阈值规则,然后为示例提供实际的Python和c++代码以及阈值输出图像。
2.代码解析
- 1.二值化(THRESH_BINARY)
# 二值化伪代码if src(x,y) > thresh dst(x,y) = maxValueelse dst(x,y) = 0
- 2.反二值化(THRESH_BINARY_INV)
# 反二值化伪代码if src(x,y) > thresh dst(x,y) = 0else dst(x,y) = maxValue
- 3.截断阈值(THRESH_TRUNC)
如果源像素值大于阈值,则将目标像素设置为阈值(thresh)。否则,将其设置为源像素值。maxValue被忽略。
# 截断阈值if src(x,y) > thresh dst(x,y) = threshelse dst(x,y) = src(x,y)
- 4.零阈值(THRESH_TOZERO)
如果源像素值大于阈值,则将目标像素值设置为对应源的像素值。否则,将其设置为0。maxValue被忽略。
# 零阈值if src(x,y) > thresh dst(x,y) = src(x,y)else dst(x,y) = 0
- 5.反零阈值(THRESH_TOZERO_INV)
如果源像素值大于阈值,则目标像素值设为零。否则,将其设置为源像素值。maxValue被忽略。
# 反零阈值if src(x,y) > thresh dst(x,y) = 0else dst(x,y) = src(x,y)
总结
我们讨论了如何使用阈值来提取图像中的特定对象。演示了几种全局阈值算法,并为每种算法提供了代码示例。您了解了OpenCV中的单个函数如何通过传递适当的阈值标志来执行不同类型的阈值。



