opencv阈值操作threshold以及图像二值化

什么是阈值

  • 最简单的分割方法
  • 应用示例:分离对应于我们想要分析的对象的图像的区域。该分离基于对象像素和背景像素之间的强度变化。
  • 为了区分我们感兴趣的像素(其最终将被拒绝),我们对每个像素强度值相对于阈值进行比较(根据要解决的问题确定)。
  • 一旦我们正确分离了重要的像素,我们可以用一个确定的值来设置它们来识别它们(即我们可以为它们分配值(黑色),(白色)或适合您需要的任何值)。0~255。

 阈值化的类型

  • OpenCV中提供了阈值(threshold)函数: threshold 。

  • 这个函数有8种阈值化类型

  1. CV_THRESH_BINARY =0, /**< value = value > threshold ? max_value : 0 */
  2. CV_THRESH_BINARY_INV =1, /**< value = value > threshold ? 0 : max_value */
  3. CV_THRESH_TRUNC =2, /**< value = value > threshold ? threshold : value */
  4. CV_THRESH_TOZERO =3, /**< value = value > threshold ? value : 0 */
  5. CV_THRESH_TOZERO_INV =4, /**< value = value > threshold ? 0 : value */
  6. CV_THRESH_MASK =7,
  7. CV_THRESH_OTSU =8,  使用Otsu算法选择最优阈值; 将标志与以上CV_THRESH_ *值之一组合
  8. CV_THRESH_TRIANGLE =16  使用Triangle算法选择最佳阈值
  • 为了解释阈值分割的过程,我们来看一个简单有关像素灰度的图片,该图如下。该图中的蓝色水平线代表着具体的一个阈值。

二进制阈值化:THRESH_BINARY =0

该阈值化类型如下式所示:

 解释:在运用该阈值类型的时候,先要选定一个特定的阈值量,比如:125,这样,新的阈值产生规则可以解释为大于125的像素点的灰度值设定为最大值(如8位灰度值最大为255),灰度值小于125的像素点的灰度值设定为0。

反二进制阈值化:THRESH_BINARY_INV =1

该阈值类型如下式所示:

解释:该阈值化与二进制阈值化相似,先选定一个特定的灰度值作为阈值,不过最后的设定值相反。(在8位灰度图中,例如大于阈值的设定为0,而小于该阈值的设定为255)。

截断阈值化:THRESH_TRUNC =2

 解释:同样首先需要选定一个阈值,图像中大于该阈值的像素点被设定为该阈值,小于该阈值的保持不变。(例如:阈值选取为125,那小于125的阈值不改变,大于125的灰度值(230)的像素点就设定为该阈值)。

阈值化为0:THRESH_TOZERO =3

 解释:先选定一个阈值,然后对图像做如下处理:1 像素点的灰度值大于该阈值的不进行任何改变;2 像素点的灰度值小于该阈值的,其灰度值全部变为0。

反阈值化为0:THRESH_TOZERO_INV =4

 解释:原理类似于0阈值,但是在对图像做处理的时候相反,即:像素点的灰度值小于该阈值的不进行任何改变,而大于该阈值的部分,其灰度值全部变为0。

 THRESH_OTSU类型

threshold(srcImg,0,255,THRESH_BINARY | THRESH_OTSU)

我们自己不一定能够找到一个最好的阈值,去二分化图像,所以我们需要算法自己去寻找一个阈值,而THRESH_OTSU就可以满足这个需求,去找到一个最好的阈值。 注意:它非常适用于图像灰度直方图具有双峰的情况,他会在双峰之间找到一个值作为阈值,对于非双峰图像,可能并不是很好用。 因为THRESH_OTSU方法会产生一个阈值,那么函数threshold的的第二个参数(设置阈值)就是0(None)了,并且在threshold的方法参数中还得加上语句THRESH_OTSU。

THRESH_TRIANGLE类型(有丢失)适用于单个波峰

threshold(gray,0,255,THRESH_BINARY | THRESH_TRIANGLE)

 THRESH_OTSU和THRESH_TRIANGLE和前面的说到的二值化方法组合使用,好处是不用自己指定thresh值,系统会进行计算并且作为返回值返回。

区别是: THRESH_OTSU最适用于双波峰 THRESH_TRIANGLE最适用于单个波峰,最开始用于医学分割细胞等。

 函数

函数原型:

CV_EXPORTS_W double threshold( InputArray src, OutputArray dst,

                               double thresh, double maxval, int type );

/** @brief Applies a fixed-level threshold to each array element.对每个数组元素应用一个固定级别的阈值。

The function applies fixed-level thresholding to a multiple-channel array. The function is typically

used to get a bi-level (binary) image out of a grayscale image ( #compare could be also used for

this purpose) or for removing a noise, that is, filtering out pixels with too small or too large

values. There are several types of thresholding supported by the function. They are determined by

type parameter.

该函数对多通道矩阵应用固定级别阈值。该函数通常用于从灰度图像中获得一个二值图像(#compare也可用于此目的)或去除噪声,即过滤出值过小或过大的像素。该函数支持几种类型的阈值设置。它们由类型参数决定。

Also, the special values #THRESH_OTSU or #THRESH_TRIANGLE may be combined with one of the

above values. In these cases, the function determines the optimal threshold value using the Otsu's

or Triangle algorithm and uses it instead of the specified thresh.

另外,特殊值#THRESH OTSU或#THRESH TRIANGLE也可以与上述值中的一个结合使用。在这些情况下,函数使用Otsu的或Triangle算法确定最佳阈值,并使用它而不是指定的阈值。

@note Currently, the Otsu's and Triangle methods are implemented only for 8-bit single-channel images.当前,仅对8位单通道图像实施Otsu和Triangle方法。

@param src input array (multiple-channel, 8-bit or 32-bit floating point).输入数组(多通道,8位或32位浮点)。

@param dst output array of the same size  and type and the same number of channels as src.输出数组的大小和类型与src具有相同的通道数。

@param thresh threshold value.阈值。

@param maxval maximum value to use with the #THRESH_BINARY and #THRESH_BINARY_INV thresholding types.   #THRESH_BINARY和#THRESH_BINARY_INV阈值使用的最大值类型。

@param type thresholding type (see #ThresholdTypes).阈值类型(请参阅#ThresholdTypes)。

@return the computed threshold value if Otsu's or Triangle methods used .如果使用Otsu或Triangle方法,则返回计算出的阈值

#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
int threshold_value = 0;
int threshold_type = 3;
int const max_value = 255;
int const max_type = 4;
int const max_BINARY_value = 255;
Mat src, src_gray, dst;
const char* window_name = "Threshold Demo";
const char* trackbar_type = "Type: \n 0: Binary \n 1: Binary Inverted \n 2: Truncate \n 3: To Zero \n 4: To Zero Inverted";
const char* trackbar_value = "Value";
void Threshold_Demo(int, void*);
int main(int argc, char** argv)
{
	String imageName("2.jpg"); // by default
	if (argc > 1)
	{
		imageName = argv[1];
	}
	src = imread(imageName, IMREAD_COLOR); // Load an image
	if (src.empty())
	{
		return -1;
	}
	cvtColor(src, src_gray, COLOR_BGR2GRAY); // Convert the image to Gray
	namedWindow(window_name, WINDOW_AUTOSIZE); // Create a window to display results
	createTrackbar(trackbar_type,
		window_name, &threshold_type,
		max_type, Threshold_Demo); // Create Trackbar to choose type of Threshold
	createTrackbar(trackbar_value,
		window_name, &threshold_value,
		max_value, Threshold_Demo); // Create Trackbar to choose Threshold value
	Threshold_Demo(0, 0); // Call the function to initialize
	for (;;)
	{
		char c = (char)waitKey(20);
		if (c == 27)
		{
			break;
		}
	}
}
void Threshold_Demo(int, void*)
{
	/* 0: Binary 二进制阈值
	   1: Binary Inverted  反二进制阈值
	   2: Threshold Truncated 截断阈值
	   3: Threshold to Zero 0阈值
	   4: Threshold to Zero Inverted 反0阈值
	 */
	threshold(src_gray, dst, threshold_value, max_BINARY_value, threshold_type);
	imshow(window_name, dst);
}

 二值化操作

#include "opencv2/imgproc/imgproc.hpp"  

#include "opencv2/highgui/highgui.hpp"  

#include <iostream>

using namespace cv;

using namespace std;

void main()

{

	//定义变量
	Mat img,result1,result2;
	//设定阈值
	int threshval = 170;

	//载入图片  

	img = imread("4.jpg", 0);

	// 方法一,使用阈值操作转为二值图  
	//使用二进制阈值化THRESH_BINARY,像素值大于阈值threshval的变为255,小于threshval的变为0
	threshold(img, result1, 0, 255, THRESH_OTSU);

	//方法二,如果阈值小于100,那么中间为真,即像素值小于160的为1,大于160的为0;如果阈值大于100,那么右边为真,即像素值大于160的为1,小于160的为0.
	result2 = threshval < 100 ? (img < 160) : (img > 160);//二值化
	//显示原图  
	namedWindow("Image");
	imshow("Image", img);
	// 显示二值图 

	namedWindow("使用阈值操作二值化后的图像");

	imshow("使用阈值操作二值化后的图像", result1);

	namedWindow("二值化后的图像");
	imshow("二值化后的图像", result2);

	waitKey(0);

}

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SOC罗三炮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值