OpenCV学习之路(十三) 图像阈值化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dashujua/article/details/82344914

官方文档

阈值可以被视为最简单的图像分割方法。比如从一幅图像中分割出我们所需要的物体部分(可以是一部分或整体)。该方法基于图像中物体与背景之间的灰度值差异,且此分割属于像素级的分割,用图像中的每一个像素点的灰度值和我们给定的阈值进行比较,并给出相应的判断(指定分割出物体的灰度值,如黑色或白色)。阈值的选取决于具体的问题。

OpenCV 2.X 中,使用 Threshold() 函数和 adaptiveThreshold() 函数来进行图像的阈值化处理。

1. Threshold() 函数。固定阈值操作。函数原型如下:

double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type);

(1)第一个参数,InputArray 类型的 src,源图像。单通道,8 或 32位浮点数类型的深度。

(2)第二个参数,OutputArray 类型的 dst,输出图像。

(3)第三个参数,double 类型的 thresh,选取的阈值。

(4)第四个参数,double 类型的 maxval。

(5)第五个参数,int 类型的 type。阈值类型。如下所示:

 

2. adaptiveThreshold() 函数。自适应阈值操作。函数原型如下:

void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C);

(1)第一个参数,InputArray 类型的 src,源图像。8 为单通道图像。

(2)第二个参数,OutputArray 类型的 dst,输出图像。

(3)第三个参数,double 类型的 maxValue,给像素赋的满足条件的非零值。

(4)第四个参数,int 类型的 adaptiveMethod,用于指定要使用的自适应阈值计算法,可取值为 ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C。

(5)第五个参数,int 类型的 thresholdType,阈值类型。取值必须为 THRESH_BINARY、THRESH_BINARY_INV 之一。

(6)第六个参数,int 类型的 blockSize,用于计算阈值大小的一个像素的邻域尺寸,取值为3、5、7等。

(7)第七个参数,double 类型的 C,减去平均或加权平均值后的常数值。通常为正数。

adaptiveThreshold() 函数中阈值的计算,是通过对 blockSize * blockSize 邻域内的像素进行平均或加权平均后减去 C 。

简单示例代码如下:

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

void on_Threshold(int, void*);
void on_adaptiveThreshold(int, void*);

int g_threshValue = 90;
int g_threshType = 0;
int g_maxThreshValue = 255;
int g_maxThreshType = 4;
int g_maxBinaryValue = 255;

int g_adapMethod = 0;
int g_maxAdapMethod = 1;
int g_adapType = 0;
int g_maxAdapType = 1;
int g_blockSize = 3;
int g_maxBlockSize = 11;
int g_adapC = 3;
int g_maxAdadC = 11;

const char* threshName = "固定阈值化效果图";
const char* threshType = "阈值类型";
const char* threshValue = "阈值大小";
const char* adaptiveName = "自适应阈值化效果图";
const char* adaptiveType = "阈值类型";
const char* adaptiveMethod = "自适应方法";
const char* blockSize = "邻域大小";
const char* adaptiveC = "C值大小";

Mat srcThreshImage, dstThreshImage, srcAdapImage, dstAdapImage;

int main()
{
	srcThreshImage = imread("cat.jpg");
	cvtColor(srcThreshImage, srcThreshImage, COLOR_RGB2GRAY);
	if (srcThreshImage.empty())
	{
		cout << "固定阈值化源图像读取错误" << endl;
	}
	srcAdapImage = imread("cat.jpg");
	imshow("原图", srcThreshImage);
	cvtColor(srcAdapImage, srcAdapImage, COLOR_RGB2GRAY);
	if (srcAdapImage.empty())
	{
		cout << "自适应阈值化源图像读取错误" << endl;
	}

	namedWindow(threshName,WINDOW_AUTOSIZE);
	namedWindow(adaptiveName, WINDOW_AUTOSIZE);


	createTrackbar(threshValue, threshName, &g_threshValue, g_maxThreshValue, on_Threshold);
	createTrackbar(threshType, threshName, &g_threshType, g_maxThreshType, on_Threshold);

	createTrackbar(adaptiveMethod, adaptiveName, &g_adapMethod, g_maxAdapMethod, on_adaptiveThreshold);
	createTrackbar(adaptiveType, adaptiveName, &g_adapType, g_maxAdapType, on_adaptiveThreshold);
	createTrackbar(blockSize, adaptiveName, &g_blockSize, g_maxBlockSize, on_adaptiveThreshold);
	createTrackbar(adaptiveC, adaptiveName, &g_adapC, g_maxAdadC, on_adaptiveThreshold);

	on_Threshold(0, 0);
	on_adaptiveThreshold(0, 0);

	waitKey(0);
	return 0;

}

void on_Threshold(int, void*)
{
	/*
		阈值类型
		0:THRESH_BINARY
		1:THRESH_BINARY_INV
		2:THRESH_TRUNC
		3:THRESH_TOZERO
		4:THRESH_TOZERO_INV
	*/

	threshold(srcThreshImage, dstThreshImage, g_threshValue, g_maxBinaryValue, g_threshType);

	imshow(threshName, dstThreshImage);
}

void on_adaptiveThreshold(int, void*)
{
	/*
		阈值类型
		0:THRESH_BINARY
		1:THRESH_BINARY_INV
	*/

	/*
		自适应方法:
		0:平均(ADAPTIVE_MEAN)
		1:加权平均(ADAPTIVE_GAUSSIAN_C)
	*/
	adaptiveThreshold(srcAdapImage, dstAdapImage, g_maxBinaryValue, g_adapMethod, g_adapType, g_blockSize, g_adapC);

	imshow(adaptiveName, dstAdapImage);
}

代码运行效果图:

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/dashujua/article/details/82344914