opencv2-第五章-图像处理之阈值化
完成许多处理步骤之后,通常希望对图像中的像素做出最后的决策,或直接剔除一些低于或高于一定值的像素。在opencv中,函数cvThreshold()可以完成这些任务。其基本思想是,给定一个数组和一个阈值,然后根据数组中的每个元素是低于还是高于阈值而进行一些处理。
double cvThreshold(CvArr* src, CvArr* dst,
double threshold, double max_value, int threshold_type);
每个阈值类型对应于一个特定的比较操作,该比较操作在源图像第i个像素和阈值之间进行。根据源图像的像素和阈值之间的关系,目标图像的像素dst可能被设置为0,src或max_value。
cvThreshold中阈值类型选项和对应的操作
CV_THRESH_BINARY dst=(src>T)? M:0
CV_THRESH_BINARY_INV dst= (src>T ) ? 0:M
CV_THRESH_TRUNC dst = (src>T) ?M:src
CV_THRESH_TOZERO_INV dst = (src > T)? 0:src
CV_THRESH_TOZERO dst = (src >T) ?src:0
自适应阈值
这是一种改进了的阈值技术,其中阈值本身是一个变量。
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);
cvAdaptiveThreshold有两种不同的自适应阈值方法,可以用参数adaptive_method进行设置。在这两种情况下,自适应阈值T(x,y)在每个像素点都不同。通过计算像素点周围的bxb区域的加强平均,然后减去一个常数来得到自适应阈值,b由参数block_size指定,常数由param1指定。如果使用CV_ADAPTIVE_THRESH_MEAN_C方法,那么对区域的所有像素平均加权。如果使用了CV_ADAPTIVE_THRESH_GAUSSIAN_C方法,那么区域中的(x,y)周围的像素根据高斯函数按照它们离中心的距离进行加权计算。
最后参数threshold_type和前面的cvThreshold的参数一样。
针对有很强照明或反射梯度的图像,需要根据梯度进行阈值化时,自适应阈值技术非常有用。次函数只能处理单通道8位图像或浮点图像,它要求源图像和目标图像不能使用同一图像。
//-----------------------------------【宏定义部分】--------------------------------------------
// 描述:定义一些辅助宏
//------------------------------------------------------------------------------------------------
#define WINDOW_NAME "【程序窗口】" //为窗口标题定义的宏
//-----------------------------------【全局变量声明部分】--------------------------------------
// 描述:全局变量的声明
//-----------------------------------------------------------------------------------------------
int g_nThresholdValue = 100;
int g_nThresholdType = 3;
Mat g_srcImage, g_grayImage, g_dstImage;
//-----------------------------------【全局函数声明部分】--------------------------------------
// 描述:全局函数的声明
//-----------------------------------------------------------------------------------------------
static void ShowHelpText( );//输出帮助文字
void on_Threshold( int, void* );//回调函数
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( )
{
//【0】改变console字体颜色
system("color 1F");
//【0】显示欢迎和帮助文字
ShowHelpText( );
//【1】读入源图片
g_srcImage = imread("1.jpg");
if(!g_srcImage.data ) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
imshow("原始图",g_srcImage);
//【2】存留一份原图的灰度图
cvtColor( g_srcImage, g_grayImage, CV_RGB2GRAY );
//【3】创建窗口并显示原始图
namedWindow( WINDOW_NAME, CV_WINDOW_AUTOSIZE );
//【4】创建滑动条来控制阈值
createTrackbar( "模式",
WINDOW_NAME, &g_nThresholdType,
4, on_Threshold );
createTrackbar( "参数值",
WINDOW_NAME, &g_nThresholdValue,
255, on_Threshold );
//【5】初始化自定义的阈值回调函数
on_Threshold( 0, 0 );
// 【6】轮询等待用户按键,如果ESC键按下则退出程序
while(1)
{
int key;
key = waitKey( 20 );
if( (char)key == 27 ){ break; }
}
}
//-----------------------------------【on_Threshold( )函数】------------------------------------
// 描述:自定义的阈值回调函数
//-----------------------------------------------------------------------------------------------
void on_Threshold( int, void* )
{
//调用阈值函数
threshold(g_grayImage,g_dstImage,g_nThresholdValue,255,g_nThresholdType);
//更新效果图
imshow( WINDOW_NAME, g_dstImage );
}
//-----------------------------------【ShowHelpText( )函数】----------------------------------
// 描述:输出一些帮助信息
//----------------------------------------------------------------------------------------------
static void ShowHelpText()
{
//输出欢迎信息和OpenCV版本
printf("\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n");
printf("\n\n\t\t\t此为本书OpenCV2版的第55个配套示例程序\n");
printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION );
printf("\n\n ----------------------------------------------------------------------------\n");
//输出一些帮助信息
printf( "\n\t欢迎来到【基本阈值操作】示例程序~\n\n");
printf( "\n\t按键操作说明: \n\n"
"\t\t键盘按键【ESC】- 退出程序\n"
"\t\t滚动条模式0- 二进制阈值\n"
"\t\t滚动条模式1- 反二进制阈值\n"
"\t\t滚动条模式2- 截断阈值\n"
"\t\t滚动条模式3- 反阈值化为0\n"
"\t\t滚动条模式4- 阈值化为0\n" );
}
这里有两个滚动条,第一个滚动条设置了4中工作模式:
\t\t滚动条模式0- 二进制阈值
滚动条模式1- 反二进制阈值
滚动条模式2- 截断阈值
滚动条模式3- 反阈值化为0
滚动条模式4- 阈值化为0