1)Threshold:对数组元素进行固定阈值操作。通常希望对图像中的像素做出最后的决策,或直接剔除一些低于或高于一定值的像素。基本思想是:给定一个数组和一个阀值,然后根据数组中的每个元素的值是低于还是高于阀值而进行一些处理。
void cvThreshold( const CvArr* src, CvArr* dst, doublethreshold,
double max_value, int threshold_type );
src
原始数组 (单通道 , 8-bit of 32-bit 浮点数).
dst
输出数组,必须与 src 的类型一致,或者为 8-bit.
threshold
阈值
max_value
使用CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值.
threshold_type
阈值类型 有4种(见讨论)
函数 cvThreshold 对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像进行阈值操作得到二值图像。(cvCmpS 也可以达到此目的) 或者是去掉噪声,例如过滤很小或很大象素值的图像点。本函数支持的对图像取阈值的方法由 threshold_type 确定:
threshold_type=CV_THRESH_BINARY:dst(x,y) = max_value, if src(x,y)>threshold 0,otherwise
threshold_type=CV_THRESH_BINARY_INV:dst(x,y) = 0, if src(x,y)>threshold max_value, otherwise
threshold_type=CV_THRESH_TRUNC:dst(x,y) = threshold, if src(x,y)>threshold src(x,y), otherwise
threshold_type=CV_THRESH_TOZERO:dst(x,y) = src(x,y), if (x,y)>threshold 0,otherwise
threshold_type=CV_THRESH_TOZERO_INV:dst(x,y) = 0, if src(x,y)>threshold src(x,y), otherwise
2)cvAdaptiveThreshold:自适应阀值,改进了的阀值技术,其中阀值本身是一个变量。有两种自适应方法,通过参数adaptive_method设置。在这两种情况下,自适应阀值T(x,y)在每个像素点都不相同。通过计算像素点周围的bxb区域的加权平均,然后减去一个常数来得到自适应阀值,b由参数block_size指定,常数由param1指定。
void cvAdaptiveThreshold(
CvArr* src, //输入图像
CvArr* dst, //输出图像
double max_val, //最大值
int adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C, //自适应阈值方法
int threshold_type=CV_THRESH_BINARY, //阈值类型
int block_size=3, //邻域大小
double param1=5 //偏移量
);
自适应阈值方法adaptive_method:
CV_ADAPTIVE_THRESH_MEAN_C 加权平均,对区域的所有像素平均加权。
CV_ADAPTIVE_THRESH_GAUSSIAN_C 高斯加权平均,区域中的(x,y)周围的像素根据高斯函数按照它们离中心距离进行加权计算。
threshold_type阀值类型与前面cvThreshold函数一样。针对有很强照明或反射梯度的图像,需要根据梯度进行阀值化时,自适应阀值技术非常有用。此函数只能处理单通道8位图像或浮点图像,它要求源图像和目标图像不能使用同一图像。
代码:
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <opencv2/legacy/legacy.hpp>
//#pragma comment(lib, "opencv_legacy2411.lib")
using namespace cv;
using namespace std;
int main()
{
const char * soutceFile = "D:\\VC98\\C++项目\\opencv\\cvAdaptiveThreshold\\cvAdaptiveThreshold\\house2.png";
IplImage * image_Resource = cvLoadImage(soutceFile, CV_LOAD_IMAGE_UNCHANGED);
assert(image_Resource);
cvNamedWindow("原始图像", 0);
cvNamedWindow("题目_a_1", 0);
cvNamedWindow("题目_a_2", 0);
cvNamedWindow("题目_a_3", 0);
cvNamedWindow("题目_a_4", 0);
cvNamedWindow("题目_a_5", 0);
cvNamedWindow("题目_b_1", 0);
cvNamedWindow("题目_b_2", 0);
cvNamedWindow("题目_c_1", 0);
cvNamedWindow("题目_c_2", 0);
cvNamedWindow("题目_c_3", 0);
cvNamedWindow("题目_c_4", 0);
IplImage * image_Gray = cvCreateImage(cvSize(image_Resource->width, image_Resource->height), IPL_DEPTH_8U, 1);
//使用cvCvtColor和cvCopy这些函数前,都应该对参数进行验证再使用
if (image_Resource->nChannels != 3)
{
cout << "加载的图像必须为彩色图片" << endl;
return 0;
}
cvCvtColor(image_Resource, image_Gray, CV_RGB2GRAY);
cvShowImage("原始图像", image_Gray);
cvSaveImage("原始图像.jpg",image_Gray);
//---------------------------a:开始--------------------------------//
double max_value = 255;
double threshold = 128;
IplImage * image_Result_a_1 = cvCloneImage(image_Gray);
cvZero(image_Result_a_1);
cvThreshold(image_Gray, image_Result_a_1, threshold, max_value, CV_THRESH_BINARY);
cvShowImage("题目_a_1", image_Result_a_1);
cvSaveImage("a_1.jpg",image_Result_a_1);
IplImage * image_Result_a_2 = cvCloneImage(image_Gray);
cvZero(image_Result_a_2);
cvThreshold(image_Gray, image_Result_a_2, threshold, max_value, CV_THRESH_BINARY_INV);
cvShowImage("题目_a_2", image_Result_a_2);
cvSaveImage("a_2.jpg",image_Result_a_2);
IplImage * image_Result_a_3 = cvCloneImage(image_Gray);
cvZero(image_Result_a_3);
cvThreshold(image_Gray, image_Result_a_3, threshold, max_value, CV_THRESH_TRUNC);
cvShowImage("题目_a_3", image_Result_a_3);
cvSaveImage("a_3.jpg",image_Result_a_3);
IplImage * image_Result_a_4 = cvCloneImage(image_Gray);
cvZero(image_Result_a_4);
cvThreshold(image_Gray, image_Result_a_4, threshold, max_value, CV_THRESH_TOZERO_INV);
cvShowImage("题目_a_4", image_Result_a_4);
cvSaveImage("a_4.jpg",image_Result_a_4);
IplImage * image_Result_a_5 = cvCloneImage(image_Gray);
cvZero(image_Result_a_5);
cvThreshold(image_Gray, image_Result_a_5, threshold, max_value, CV_THRESH_TOZERO);
cvShowImage("题目_a_5", image_Result_a_5);
cvSaveImage("a_5.jpg",image_Result_a_5);
//---------------------------a:结束--------------------------------//
//---------------------------b:开始--------------------------------//
IplImage * image_Result_b_1 = cvCloneImage(image_Gray);
cvZero(image_Result_b_1);
cvAdaptiveThreshold(image_Gray, image_Result_b_1, max_value, CV_ADAPTIVE_THRESH_MEAN_C,CV_THRESH_BINARY, 3, 5);
cvShowImage("题目_b_1", image_Result_b_1);
cvSaveImage("b_1.jpg",image_Result_b_1);
IplImage * image_Result_b_2 = cvCloneImage(image_Gray);
cvZero(image_Result_b_2);
cvAdaptiveThreshold(image_Gray, image_Result_b_2, max_value, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV,3,5);
cvShowImage("题目_b_2", image_Result_b_2);
cvSaveImage("b_2.jpg",image_Result_b_2);
//---------------------------b:结束--------------------------------//
//---------------------------c:开始--------------------------------//
IplImage * image_Result_c_1 = cvCloneImage(image_Gray);
cvZero(image_Result_c_1);
cvAdaptiveThreshold(image_Gray, image_Result_c_1, max_value, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 3, 0);
cvShowImage("题目_c_1", image_Result_c_1);
cvSaveImage("c_1.jpg",image_Result_c_1);
IplImage * image_Result_c_2 = cvCloneImage(image_Gray);
cvZero(image_Result_c_2);
cvAdaptiveThreshold(image_Gray, image_Result_c_2, max_value, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 3, 0);
cvShowImage("题目_c_2", image_Result_c_2);
cvSaveImage("c_2.jpg",image_Result_c_2);
IplImage * image_Result_c_3 = cvCloneImage(image_Gray);
cvZero(image_Result_c_3);
cvAdaptiveThreshold(image_Gray, image_Result_c_3, max_value, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 3, -5);
cvShowImage("题目_c_3", image_Result_c_3);
cvSaveImage("c_3.jpg",image_Result_c_3);
IplImage * image_Result_c_4 = cvCloneImage(image_Gray);
cvZero(image_Result_c_4);
cvAdaptiveThreshold(image_Gray, image_Result_c_4, max_value, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 3, -5);
cvShowImage("题目_c_4", image_Result_c_4);
cvSaveImage("c_4.jpg",image_Result_c_4);
//---------------------------c:结束--------------------------------//
cvWaitKey(0);
cvReleaseImage(&image_Resource);
cvReleaseImage(&image_Result_a_1);
cvReleaseImage(&image_Result_a_2);
cvReleaseImage(&image_Result_a_3);
cvReleaseImage(&image_Result_a_4);
cvReleaseImage(&image_Result_a_5);
cvReleaseImage(&image_Result_b_1);
cvReleaseImage(&image_Result_b_2);
cvReleaseImage(&image_Result_c_1);
cvReleaseImage(&image_Result_c_2);
cvReleaseImage(&image_Result_c_3);
cvReleaseImage(&image_Result_c_4);
cvDestroyWindow("原始图像");
cvDestroyWindow("题目_a_1");
cvDestroyWindow("题目_a_2");
cvDestroyWindow("题目_a_3");
cvDestroyWindow("题目_a_4");
cvDestroyWindow("题目_a_5");
cvDestroyWindow("题目_b_1");
cvDestroyWindow("题目_b_2");
cvDestroyWindow("题目_c_1");
cvDestroyWindow("题目_c_2");
cvDestroyWindow("题目_c_3");
cvDestroyWindow("题目_c_4");
return 0;
}
效果:
原图:
灰度图:
二值化参数为:double max_value = 255;double threshold = 128;
CV_THRESH_BINARY:
CV_THRESH_BINARY_INV:
CV_THRESH_TRUNC:
CV_THRESH_TOZERO_INV:
CV_THRESH_TOZERO:
自适应cvAdaptiveThreshold
第一种:
cvAdaptiveThreshold(image_Gray, image_Result_c_1, max_value, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 3, 0);
第二种:
cvAdaptiveThreshold(image_Gray, image_Result_c_2, max_value, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 3, 0);
第三种:
cvAdaptiveThreshold(image_Gray, image_Result_c_3, max_value, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 3, -5);
第四种:
cvAdaptiveThreshold(image_Gray, image_Result_c_4, max_value, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 3, -5);
(完)