opencv#16 图像二值化

一、图像阈值二值化

比如有个原始信号,图片中的横线表示阈值,当信号大于阈值,定义为最大输出,当信号小于阈值,定义为最小输出。

 阈值化可以简单地将其理解为一个信号的滤波。

固定阈值二值化

threshold()

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

·src:待二值化地图像,图像只能是CV_8U和CV_32F两种数据类型。对于图像通道数目的要求和选择地二值化方法相关。

·dst:二值化后的图像,与输入图像具有相同的尺寸,数据类型和通道数。

·thresh:二值化的阈值。

·maxval:二值化过程中的最大值。

·type:选择图像二值化方法的标志

前面的几种二值化方法都是需要人为的给出一个比较阈值,若对图像充分了解,那么给出的阈值是比较合理的,可以将两者充分的分离开,如果对图像不是很了解,会造成给出的阈值,是偏离期望的阈值,就会造成二值化的时候得到非预期的结果,为了避免这种情况,在opencv中,集成了另外两种可以自动给出整幅图像阈值的两种算法,分别是OTSU大津算法和TRIANGLED三角形算法,我们调用的时候是与前面的几种算法相对应的,我们只需要在前面同一加上THRESH_...上面两种函数是自动给出阈值,也就是在阈值比较的时候,第三个参数是无用的,可以自由的给出。

示例

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

using namespace cv; //opencv的命名空间
using namespace std;

int main()
{
	Mat img = imread("E:/opencv/opencv-4.6.0-vc14_vc15/opencv/lenac.png");
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	Mat gray;
	cvtColor(img, gray, COLOR_BGR2GRAY);
	Mat img_B, img_B_V, gray_B, gray_B_V, gray_T, gray_T_V, gray_TRUNC;

	//彩色图像二值化
	threshold(img, img_B, 125, 255, THRESH_BINARY);
	threshold(img, img_B_V, 125, 255, THRESH_BINARY_INV);
	imshow("img_B", img_B);
	imshow("img_B_V", img_B_V);

	//灰度图像BINARY二值化
	threshold(gray,gray_B, 125, 255, THRESH_BINARY);
	threshold(gray,gray_B_V, 125, 255, THRESH_BINARY_INV);
	imshow("gray_B", gray_B);
	imshow("gray_B_V", gray_B_V);

	//灰度图像TOZERO变换
	threshold(gray, gray_T, 125, 255, THRESH_TOZERO);
	threshold(gray, gray_T_V, 125, 255, THRESH_TOZERO_INV);
	imshow("gray_T", gray_T);
	imshow("gray_T_V", gray_T_V);

	//灰度图像TRUNC变换
	threshold(gray, gray_TRUNC, 125, 255, THRESH_TRUNC);
	imshow("gray_TRUNC", gray_TRUNC);

	//灰度图像大津法和三角形法二值化
	Mat img_Thr = imread("E:/opencv/opencv-4.6.0-vc14_vc15/opencv/threshold.jpeg", IMREAD_GRAYSCALE);
	Mat img_Thr_0, img_Thr_T;
	threshold(img_Thr, img_Thr_0, 100, 255, THRESH_BINARY | THRESH_OTSU);
	threshold(img_Thr, img_Thr_T, 125, 255, THRESH_BINARY | THRESH_TRIANGLE);
	imshow("img_Thr", img_Thr);
	imshow("img_Thr_0", img_Thr_0);
	imshow("img_Thr_T", img_Thr_T);

	waitKey(0);


	



	return 0;

}

结果 

这种彩色图像是将每个通道单独的进行阈值化后将其进行组合,相当于是将亮色图像变白,暗色图像保留,因为这种方式是对每个通道进行处理的,所以不会出现图像中只有黑白的情况,最多会出现2^3种形式,因为第一个通道是0-255,第二个通道0-255,第三个通道也是0-255,进行这些形式组合,最后得到这样的结构。

灰度图像二值化的结果:下面是一种相对应的方式,分别将高于阈值或者将低于阈值置0,是互补形式。 

下图相当于是将小于某个阈值的形式都保留了,图片中整个区域更亮的形式,但是对低于阈值的纹理也进行了保留。 

下图两者也是互补形式,当两者叠加在一起时,就可以恢复原先的图像。 

下面是对图片进行了自动选取阈值的方式。整个图像选取的最佳阈值 之后,均方差最大,这种方式对于全局梯度是有阴影变化的形式的时候,是没办法选出来一个很好的阈值,能够实现像人眼一样自动区分的功能。如果我们将原始图像分解为多个区域,之后再进行大津法或者三角形法,是否会得到更好的效果?当然。

为了解决上述情况,我们想要在一个比较小的区域内选取合适的阈值,在另外一个小区域内,再选取一个合适阈值,将这张图像分为多个较小的区域,之后进行二值化。opencv也提供了对应的函数。

自适应阈值的图像二值化 

adaptive Threshold()

void cv::adaptive Threshold(InputArray   src,
                            OutputArray  dst,
                            double       maxValue,
                            int          adaptiveMethod,
                            int          thresholdType,
                            int          blockSize,
                            double       C
                            )

 ·src:待二值化的图像,图像只能是CV_8UC1(0~255,灰度图(单通道))数据类型。

·dst:二值化后的图像,与输入图像具有相同的尺寸,数据类型。

·maxValue:二值化的最大值。

·adaptiveMethod:自制应确定阈值的方法,分为均值发ADAPTIVE_THRESH_MEAN_C和高斯法ADAPTIVE_THRESH_GAUSSIAN_C这两种。

·thresholdType:选择图像二值化方法的标志,只能是THRESH_BINARY和THRESH_BINARY_INV。

·blockSize:自适应确定阈值的像素邻域大小,一般为3,5,7的奇数。

·C:从平均值或者加权平均值中减去的常数,可以为正,也可以为负。

示例2:加入了自适应阈值二值化

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

using namespace cv; //opencv的命名空间
using namespace std;

int main()
{
	Mat img = imread("E:/opencv/opencv-4.6.0-vc14_vc15/opencv/lenac.png");
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	Mat gray;
	cvtColor(img, gray, COLOR_BGR2GRAY);
	Mat img_B, img_B_V, gray_B, gray_B_V, gray_T, gray_T_V, gray_TRUNC;

	//彩色图像二值化
	threshold(img, img_B, 125, 255, THRESH_BINARY);
	threshold(img, img_B_V, 125, 255, THRESH_BINARY_INV);
	imshow("img_B", img_B);
	imshow("img_B_V", img_B_V);

	//灰度图像BINARY二值化
	threshold(gray,gray_B, 125, 255, THRESH_BINARY);
	threshold(gray,gray_B_V, 125, 255, THRESH_BINARY_INV);
	imshow("gray_B", gray_B);
	imshow("gray_B_V", gray_B_V);

	//灰度图像TOZERO变换
	threshold(gray, gray_T, 125, 255, THRESH_TOZERO);
	threshold(gray, gray_T_V, 125, 255, THRESH_TOZERO_INV);
	imshow("gray_T", gray_T);
	imshow("gray_T_V", gray_T_V);

	//灰度图像TRUNC变换
	threshold(gray, gray_TRUNC, 125, 255, THRESH_TRUNC);
	imshow("gray_TRUNC", gray_TRUNC);

	//灰度图像大津法和三角形法二值化
	Mat img_Thr = imread("E:/opencv/opencv-4.6.0-vc14_vc15/opencv/threshold.jpeg", IMREAD_GRAYSCALE);
	Mat img_Thr_0, img_Thr_T;
	threshold(img_Thr, img_Thr_0, 100, 255, THRESH_BINARY | THRESH_OTSU);
	threshold(img_Thr, img_Thr_T, 125, 255, THRESH_BINARY | THRESH_TRIANGLE);
	imshow("img_Thr", img_Thr);
	imshow("img_Thr_0", img_Thr_0);
	imshow("img_Thr_T", img_Thr_T);

	//自适应阈值二值化
	Mat adaptive_mean, adaptive_gauss;

	adaptiveThreshold(img_Thr, adaptive_mean, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 55, 0);
	adaptiveThreshold(img_Thr, adaptive_gauss, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 55, 0);

	imshow("adaptive_mean", adaptive_mean);
	imshow("adaptive_gauss", adaptive_gauss);



	waitKey(0);
	return 0;

}

结果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值