【OpenCV学习笔记】之基本阈值操作(Threshold)
- 阈值化(Threshold)
阈值化,即图像的二值化处理就是讲图像上的点的灰度置为0或255,也就是讲整个图像呈现出明显的黑白效果。即将256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。在数字图像处理中,二值图像占有非常重要的地位,特别是在实用的图像处理中,以二值图像处理实现而构成的系统是很多的,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像,这样子有利于再对图像做进一步处理时,图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值,使处理变得简单,而且数据的处理和压缩量小。为了得到理想的二值图像,一般采用封闭、连通的边界定义不交叠的区域。所有灰度大于或等于阀值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。如果某特定物体在内部有均匀一致的灰度值,并且其处在一个具有其他等级灰度值的均匀背景下,使用阀值法就可以得到比较的分割效果。如果物体同背景的差别表现不在灰度值上(比如纹理不同),可以将这个差别特征转换为灰度的差别,然后利用阀值选取技术来分割该图像。动态调节阀值实现图像的二值化可动态观察其分割图像的具体结果。
其实在完成许多处理步骤后,通常希望对图像中的像素做出最后的决策,或直接剔除一些低于或高于一定值的像素。在opencv里面Threshold()可以完成这些任务。基本思想是,给定一个数组和一个阈值,然后根据数组中的每个元素的值是低于还是高于阈值而进行一些处理。
Opencv里面的API介绍:(全局阈值化)
C++ void threshold(Mat dst,Mat dst1,int threshold_value,int threshold_max,type);
//src:源图像,可以为8位的灰度图,也可以为32位的彩色图像。(两者有区别)dst:输出图像 thresh:阈值maxval:dst图像中最大值 type:阈值类型:1 THRESH_BINARY 2 THRESH_BINARY_INV 3 THRESH_TRUNC 4 THRESH_TOZERO 5 THRESH_TOZERO_INV
第五个参数Type:可以是下面五种格式,其中还有三种比较常用的像大津法(THRESH_OTSU),THRESH_MASK 和 THRESH_TRIANGLE
Opencv里面的API介绍:(局部阈值化)
局部自适应阈值则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。这样做的好处在于每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。亮度较高的图像区域的二值化阈值通常会较高,而亮度较低的图像区域的二值化阈值则会相适应地变小。不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。常用的局部自适应阈值有:1)局部邻域块的均值;2)局部邻域块的高斯加权和。
C++ void adaptiveThreshold(
InputArray src, 输入图像.
OutputArray dst, 输出图像.
double max_value,
int adaptive_method,
int threshold_type,
int block_size,
double param )
参数解释:
- 第一个参数,输入图像,需为8位单通道浮点图像;
- 第二个参数,输出图像,需和原图像尺寸类型一致;
- 第三个参数,double类型,给像素赋的满足条件的非零值;
- 第四个参数,用于指定自适应阈值的算法,CV_ADAPTIVE_THRESH_MEAN_C ,CV_ADAPTIVE_THRESH_GAUSSIAN_C
- 第五个参数,取阈值类型:必须是CV_THRESH_BINARY或者CV_THRESH_BINARY_INV
- 第六个参数,用来计算阈值的象素邻域大小: 3, 5, 7, ...
- 第七个参数,与方法有关的参数。对方法 CV_ADAPTIVE_THRESH_MEAN_C 和 CV_ADAPTIVE_THRESH_GAUSSIAN_C, 它是一个从均值或加权均值提取的常数, 有时也可以是小数或负数。
对方法 CV_ADAPTIVE_THRESH_MEAN_C,先求出块中的均值,再减掉param。
对方法 CV_ADAPTIVE_THRESH_GAUSSIAN_C ,那么区域中(x,y)周围的像素根据高斯函数按照他们离中心点的距离进行加权计算, 再减掉param。
示例程序:
//基本阈值操作
#include "stdafx.h"
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
Mat src, dst, dst1;
int threshold_value = 127;
int threshold_max = 255;
int type = 2;
int type_max = 4;
char result[] = "threshold image";//或者定义一个指针形式:const char* result="threshold image";
void threshold_Demo(int, void*);
int main(int argc, int argv)
{
src = imread("C:\\Users\\59235\\Desktop\\imag\\girl1.jpg");
if (!src.data)
{
printf("could not load image...\n");
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src);
namedWindow(result, CV_WINDOW_AUTOSIZE);
createTrackbar("threshold value", result, &threshold_value, threshold_max, threshold_Demo);
createTrackbar("threshold type", result, &type, type_max, threshold_Demo);
threshold_Demo(0, 0);
waitKey(0);
return 0;
}
//阈值化实现函数
void threshold_Demo(int, void*)
{
cvtColor(src, dst, CV_BGR2GRAY);
imshow("GRAY", dst);
//阈值化(自主定义阈值)
//threshold(dst,dst1,threshold_value,threshold_max,type);
//src:源图像,可以为8位的灰度图,也可以为32位的彩色图像。(两者由区别)dst:输出图像 thresh:阈值maxval:dst图像中最大值 type:阈值类型有8种(1 THRESH_BINARY 2 THRESH_BINARY_INV 3 THRESH_TRUNC 4 THRESH_TOZERO 5 THRESH_TOZERO_INV 6 THRESH_MASK 7 THRESH_OTSU 8 THRESH_TRIANGLE)
//阈值化(系统帮忙取,大津法OTSU:THRESH_OTSU;三角形阈值法:THRESH_TRIANGLE)
threshold(dst, dst1, 0, 255, THRESH_OTSU | type);
imshow(result, dst1);
}
效果图:
(THRESH_BINARY) (THRESH_BINARY_INV)
(THRESH_TRUNC) (THRESH_TOZERO )
(THRESH_TOZERO_INV)