简单点说,阈值是把图像分割的标尺,为了从一副图像中提取出我们需要的部分,应该用图像中的每一个像素点的灰度值与选取的阈值进行比较,并作出相应的判断。阈值的选取依赖于具体的问题,例如,物体在不同的图像中有可能会有不同的灰度值。
当找到了需要分割的物体的像素点,我们可以对这些像素点设定一些特定的值来表示。例如:可以将该物体的像素点的灰度值设定为:‘0’(黑色),其他的像素点的灰度值为:‘255’(白色);两种颜色对比度较强,方便观察结果。这样的图像分割方法是基于图像中物体与背景之间的灰度差异,而且此分割属于像素级的分割。
=========================================================================
THRESH_BINARY=0,该阈值化类型为:
应用此阈值类型时,首先选择特定的阈值量,例如125。 这样,新的阈值生成规则可以解释为,将大于125的像素点的灰度值设为最大值,例如,将8位的灰度值设为最大255,将灰度值小于125的像素点的灰度值设为0。
---------------------------------------------------------------------------------------------------------------------------------
THRESH_BINARY_INV=1 ,该阈值化类型为:
使用该阈值化类型,必须首先选择阈值。该阈值化与二进制阈值化相似,首先选择特定灰度值作为阈值,但是最后的设定值相反。 (在8位灰度中,大于阈值的设置为0,而小于阈值的设置为255。
---------------------------------------------------------------------------------------------------------------------------------
THRESH_TRUNC=2,该阈值化类型为:
使用该阈值化类型,必须首先选择阈值。 图像中大于该阈值的像素点被设置为该阈值,小于该阈值的像素点保持不变。 例如,如果将阈值设置为125,则小于125的像素点的阈值不会更改,而大于125的像素点的阈值将设置为该阈值125。
---------------------------------------------------------------------------------------------------------------------------------
THRESH_TOZERO=3,该阈值化类型为:
使用该阈值化类型,必须首先选择阈值。对图像进行以下处理。 如果1个像素点的灰度值大于该阈值,则不进行任何改变; 如果两个像素的点的灰度值小于该阈值,则该灰度值都为0。
---------------------------------------------------------------------------------------------------------------------------------
阈值类型一阈值反取零 (threshold to zero inverted)
THRESH_TOZERO_INV=4,该阈值化类型为:
使用该阈值化类型,必须首先选择阈值。原理类似于0的阈值,但处理图像时相反。 也就是说,如果像素点的灰度值小于该阈值,则不进行任何变更,大于阈值的部分灰度值都为0。
=========================================================================
全局阈值处理:
#阈值处理API:
cv2.threshold(src, thresh, maxval, type, dst=None)
参数说明:
src: 原图像,就是要进行阈值处理的原图对象。
thresh: 阈值,就是进行分类的阈值。
maxval: 当type指定为THRESH_BINARY或THRESH_BINARY_INV时,才需要设置该值。指的是高于(低于)阈值时赋予的新值。
type: 指定阈值处理的方法,常用的有:
cv2.THRESH_BINARY (黑白二值)
cv2.THRESH_BINARY_INV (黑白二值反转)
cv2.THRESH_TRUNC (截断阈值化处理)
cv2.THRESH_TOZERO (阈值取零)
cv2.THRESH_TOZERO_INV (阈值反取零)
dst: 目标图像
该函数有两个返回值,第一个retVal(得到的阈值值,因为有时要自动找阈值),第二个就是阈值化后的图像。
---------------------------------------------------------------------------------------------------------------------------------
在前面部分使用的都是全局阈值,整幅图采用同一个数值当做阈值。但这种方法并不适用于所有情况,尤其是当同一副图像上的不同部分的具有不同的亮度时。这种情况采用自适应阈值。具体针对光影变化过大的图片,或者范围内颜色差异不太明显的图片。自适应是指保证计算机能够通过判断和计算取得该图像区域的平均阈值进行迭代。此时的阈值是根据图像上的每一个小区域计算与其对应的阈值。因此在同一副图像上的不同的区域采用不同的阈值,从而我们能在亮度不同时得到更好的结果。
#自适应阈值处理API:
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)
参数说明:
src: 要进行处理的原始图像
maxValue: 当参数thresholdType为cv2.THRESH_BINARY或者cv2.THRESH_BINARY_INV时,该参数表示高于(低于)阈值时赋予的新值。
adaptiveMethod: 计算自适应阈值的方法。这里有2种方法,也就是这个参数有2个可选值。
第一种方法是:adaptiveMethod=cv2.ADAPTIVE_THRESH_MEAN_C, 这种方法是将邻域所有像素点的权重值都取一样。
第二种方法是:adaptiveMethod=cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 这种方法是通过高斯公式获得邻域所有像素点的权重值。这种权重值的选取就跟各邻域像素点到目标像素点的距离有关,距离越近权重越高,距离越远权重越低。
thresholdType: 表示阈值处理方式,这个参数是和maxValue一起搭配使用的。这个参数只能选择cv2.THRESH_BINARY或者cv2.THRESH_BINARY_INV中的一个。
blockSize: 表示邻域尺寸的大小,一般取3,5,7等。
C: 是常量,阈值等于平均值或者加权平均值减去这个常数。
=========================================================================
代码实现:
#include"stdafx.h"
#include
#include
#include
using namespace std;
using namespace cv;
void Threshold_Demo(int, void*);//函数声明
int threshold_value_min = 100;
const int threshold_value_max = 255;
int threshold_value = 127;
const int MAX_THRESHOLD = 255;
int threshold_type = 2;
const int MAX_THRESHOLD_TYPE = 4;
Mat src, srcGray, dst;
Mat image2, image3;
Mat dst1, dst2, dst3;
int main()
{
Mat image1 = imread("F:/photo/qx.jpg");
namedWindow("input_picture1");
imshow("input_picture1", image1);//输入原图
cvtColor(image1, image2, COLOR_RGB2GRAY);
namedWindow("gray_picture");
imshow("gray_picture", image2);//输出灰度图
//threshold(image2, image3, 65, 255, THRESH_BINARY);
//namedWindow("input_picture3");
//imshow("input_picture3", image3);
namedWindow("image_threshold", WINDOW_AUTOSIZE);
createTrackbar("threshold: ", "image_threshold", &threshold_value_min, MAX_THRESHOLD, Threshold_Demo);
createTrackbar("type: ", "image_threshold", &threshold_type, MAX_THRESHOLD_TYPE, Threshold_Demo);
Threshold_Demo(0,0);
waitKey(0);
return 0;
}
void Threshold_Demo(int,void*) {
//cvtColor(image2, srcGray, COLOR_BGR2GRAY); //转换为灰度图
// printf("%d", THRESH_BINARY); // 0
// printf("%d", THRESH_BINARY_INV); // 1
// printf("%d", THRESH_TRUNC); // 2
// printf("%d", THRESH_TOZERO); // 3
// printf("%d", THRESH_TOZERO_INV); // 4
threshold(image2, dst, threshold_value_min, MAX_THRESHOLD, threshold_type);
// threshold(srcGray, dst, 0, 255, THRESH_OTSU | threshold_type); // 自动计算阈值
// threshold(srcGray, dst, 0, 255, THRESH_TRIANGLE | threshold_type); // 自动计算阈值
imshow("Threshold", dst);
}
---------------------------------------------------------------------------------------------------------------------------------
原图与灰度图
threshold 逐渐变大,type=3 时的图像变化
threshold =0,type =1 时的图像为纯白色
threshold =0,type =2,4时的图像为黑色
threshold 数值逐渐变大,type =1 时图像的变化
threshold 数值逐渐变大,type =0 时图像的变化