35_OpenCv中的阈值化操作

导读:本篇文章讲解 35_OpenCv中的阈值化操作,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

阈值化操作原理是给定一个数组和阈值,对于数组中每个值,根据其高于或低于这个阈值做出响应的处理。也可以把阈值化理解成一个用axa的核进行卷积,对每个像素进行一次非线性操作。

1. 二值化阈值 cv::threshold()

函数原型:

double cv::threshold(
	cv::InputArray src,  // input image
	cv::OutputArray dst,  // result image
	double thresh,  // threshold value
	double maxValue, // max value for upward operations
	int thresholdType  // threshold type to use
);

每种阈值化操作类型对应于第i个源像素和阈值threshold之间的比较运算方式。根据源像素和阈值之间的关系,目标像素dst可以被赋值为0、src_i或给定的最大值maxValue。返回值阈值

参数thresholdType的可选项:

阈值类型 操作 说明
cv::THRESH_BINARY DST[i] = (SRC[i] > thresh) ? MAXVALUE : 0 二值化
cv::THRESH_BINARY_INV DST[i] = (SRC[i] > thresh) ? 0 : MAXVALUE 反二值化
cv::THRESH_TRUNC DST[i] = (SRC[i] > thresh) ? THRESH : SRC[i]  截断,不超过阈值
cv::THRESH_TOZERO DST[i] = (SRC[i] > thresh) ? SRC[i] : 0 置0阈操作
cv::THRESH_TOZERO_INV DST[i] = (SRC[i] > thresh) ? 0 : SRC[i] 反置0阈操作

2. 获取最优阈值的算法—Otsu算法

cv::threshold()函数也可以自动决定最优的阈值,需要设置参数type=cv::THRESH_OTSU。

当设置cv::THRESH_OTSU时,阈值设置为0时,函数会返回计算得到的最佳阈值。

Otsu算法是遍历所有可能的阈值,然后对每个阈值结果的两类像素计算方差σ²(即低于阈值核高于阈值的两类像素)。Otsu算法计算方差使下列表达式最小:

35_OpenCv中的阈值化操作

 35_OpenCv中的阈值化操作 ​​​​​​和35_OpenCv中的阈值化操作 是根据两类像素的数量计算得到的权值,35_OpenCv中的阈值化操作35_OpenCv中的阈值化操作表示两类像素的方差。

Otsu算法需要遍历所有可能的阈值,相对来说效率不是很高。

 3. 自适应阈值  cv::adaptiveThreshold()

自适应阈值在整个过程中自动产生变化。在OpenCv中,函数cv::adaptiveThreshold()实现这种方法。函数原型声明:

void cv::adaptiveThreshold(
	cv::InputArray src,  // input image
	cv::OutputArray dst,  // result image
	double maxValue,  // max value for upward operations
	int adaptiveMethod,  // mean or Gaussian
	int thresholdType,  // threshold type to use
	int blockSize,  // block size
	double C  // constant
);

 cv::adaptiveShold()函数根据adaptiveMethos参数的设置,允许两种不同的自适应阈值方法。这两个方法都是逐个像素地去计算自适应阈值T(x,y),方法是通过计算每个像素位置周围的bxb区域的加权平均值然后减去常数C,其中b由blockSize给定(blockSize一般为奇数),不同的是,

  • 如果选择的均值方法是cv::ADAPTIVE_THRESH_MEAN_C,那么均值时取得权值是相等的;
  • 如果选择的均值方法是cv::ADAPTIVE_THRESH_GAUSSIAN_C,(x,y)周围的像素的权值则根据其到中心点的距离通过高斯方程得到。

参数thresholdType只支持cv::THRESH_BINARY和cv::THRESH_BINARY_INV。

当图像中出现较大的明暗差异时,自适应阈值非常有效。cv::adaptiveThreshold()函数仅处理单通道8位或浮点图像,并且要求源图像和目标图像不同

使用示例:

	if (argc != 7){
		std::cout << "Usage: " << argv[0] << " fixed_threshold invert(0=off|1=on)"
			"adaptive_type(0=mean|1=gaussian) block_size offset image\n"
			"Example: " << " 100 1 0 15 10 fruits.jpg\n";
		return;
	}

	// command line

	double fixed_threshold = (double)atof(argv[1]);
	int threshold_type = atoi(argv[2]) ? cv::THRESH_BINARY : cv::THRESH_BINARY_INV;
	int adaptive_method = atoi(argv[3]) ? cv::ADAPTIVE_THRESH_MEAN_C : cv::ADAPTIVE_THRESH_GAUSSIAN_C;

	int block_size = atoi(argv[4]);
	double offset = (double)atof(argv[5]);
	cv::Mat Igray = cv::imread(argv[6], CV_LOAD_IMAGE_GRAYSCALE);
	if (Igray.empty()){
		std::cout << "can not load" << argv[6] << std::endl;
		return;
	}

	cv::Mat It, Iat;
	double fThresh = cv::threshold(Igray, It, fixed_threshold, 255, threshold_type);  // 输入图片 输出二值化图片  阈值  最大值 阈值类型
	cv::adaptiveThreshold(
		Igray,   // 输入图片
		Iat,    // 输出图片
		255,   // 最大值
		adaptive_method,     //自适应阈值算法(均值或高斯均值 cv::ADAPTIVE_THRESH_MEAN_C  或cv::ADAPTIVE_THRESH_GAUSSIAN_C
		threshold_type,   // 阈值类型只支持二值化或反二值化
		block_size,   // 核 blockSize x blockSize区域计算
		offset);  // 减去常量 offset

	cv::imshow("raw", Igray);
	cv::imshow("threshold", It);
	cv::imshow("adaptive_threshold", Iat);
	cv::waitKey(0);

 使用的参数为  15 1 1 71 15 E:\\right14.jpg  表示cv::thresh()函数使用的阈值为15,使用的阈值化类型为二值化,使用的自适应阈值类型是cv::ADAPTIVE_THRESH_MEAN_C,自适应阈值时计算的核是71 x 71,减去的常量值是15。显示结果为:

原图                                    二值化                              自适应阈值

35_OpenCv中的阈值化操作35_OpenCv中的阈值化操作35_OpenCv中的阈值化操作

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/46153.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!