昊虹AI笔记网

 找回密码
 立即注册
搜索
查看: 1573|回复: 0
收起左侧

使用OpenCV的函数threshold()对图像进行二值化或阈值化处理

[复制链接]

239

主题

241

帖子

928

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
928
昊虹君 发表于 2022-12-8 12:00 | 显示全部楼层 |阅读模式
使用OpenCV的函数threshold()对图像进行二值化或阈值化处理

如果一幅图像,其像素的灰度值只有两个取值,那么这样的图像我们就称作二值图像。
把图像转化为二值图像的过程称为图像的二值化处理。

如果对图像的灰度值按与某个值的大小关系进行新值的设置,称为叫图像的阈值化处理。

在OpenCV中,可以使用函数threshold()对图像作二值化或阈值化处理。

其原型如下:
C++原型如下:
  1. double cv::threshold(InputArray src,
  2.                      OutputArray dst,
  3.                      double thresh,
  4.                      double maxval,
  5.                      int type)
复制代码

Python原型如下:
  1. double cv::threshold(InputArray src,
  2.                      OutputArray dst,
  3.                      double thresh,
  4.                      double maxval,
  5.                      int type)
复制代码

参数意义如下:
src—输入图像,即待二值化的图像,可以是多通道,8位或32位符点型数据类型的图像,但是当参数type选择THRESH_OTSU或THRESH_TRIANGLE时,图像只能为8位的单通道图像。

dst—经过二值化处理的输出图像。

thresh—进行二值化处理的阈值。当type选择THRESH_OTSU或THRESH_TRIANGLE时,这个值被忽略,此时函数用通过OTSU法或TRIANGLE法计算出的阈值进行二值化操作。

maxval—二值化处理后的maxval值,详情见对参数type的介绍。当type选择THRESH_BINARY、THRESH_BINARY_INV、THRESH_OTSU、THRESH_TRIANGLE时会用到它,在type选择其它类型时,虽然它没有用,但也要填上它。

type—这个参数的可选枚举值及意义如下:

要特别注意的是,在Python环境中,函数threshold()的返回值有两个,分别为retval和dst。
第一个retval代表函数threshold()在进行二值化处理时使用的阈值,这一点挺好,特别是对于type选择THRESH_OTSU或THRESH_TRIANGLE时,我们可以知道进行二值处理时用的阈值究竟是多少。
如果不想使用retval这个返回值,可以像下面这样调用:
  1. _, dst = cv.threshold(src, thresh, maxval, type[, dst])
复制代码

即用下划线命名返回值retval。

明白了以上各参数的意义和可取值后,就基本了解了函数threshold()的使用,接下来再看看示例代码就能完全掌握了。

首先是当type取值为THRESH_BINARY 、THRESH_BINARY_INV 、THRESH_TRUNC、THRESH_TOZERO 、THRESH_TOZERO_INV 时的示例代码。

当type取值为THRESH_BINARY 、THRESH_BINARY_INV 、THRESH_TRUNC、THRESH_TOZERO 、THRESH_TOZERO_INV 时的Python代码如下:
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
# 出处:昊虹AI笔记网(hhai.cc)
# 用心记录计算机视觉和AI技术

# 博主微信/QQ 2487872782
# QQ群 271891601
# 欢迎技术交流与咨询

# OpenCV的版本为4.4.0

import numpy as np
import cv2 as cv

if __name__ == '__main__':
    A1 = np.array([[0, 10, 50],
                   [80, 150, 255]], dtype='uint8')

    thresh1 = 80
    maxval1 = 200
    retval1, B1 = cv.threshold(A1, thresh1, maxval1, cv.THRESH_BINARY)
    retval2, B2 = cv.threshold(A1, thresh1, maxval1, cv.THRESH_BINARY_INV)
    retval3, B3 = cv.threshold(A1, thresh1, maxval1, cv.THRESH_TRUNC)
    retval4, B4 = cv.threshold(A1, thresh1, maxval1, cv.THRESH_TOZERO)
    retval5, B5 = cv.threshold(A1, thresh1, maxval1, cv.THRESH_TOZERO_INV)

运行结果如下:




当type取值为THRESH_BINARY 、THRESH_BINARY_INV 、THRESH_TRUNC、THRESH_TOZERO 、THRESH_TOZERO_INV 时的C++代码如下:
[C++] 纯文本查看 复制代码
//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术

//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询

//OpenCV版本 OpenCV3.0

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

using namespace std;
using namespace cv;


int main()
{

	cv::Mat A1 = (cv::Mat_<uchar>(2, 3) << 0, 10, 50,
		                                   80, 150, 255);
	cout << "A1中的数据为:\n" << A1 << endl << endl;

	
	double thresh1 = 80;
	double maxval1 = 200;

	Mat B1, B2, B3, B4, B5;

	threshold(A1, B1, thresh1, maxval1, THRESH_BINARY);
	cout << "B1中的数据为:\n" << B1 << endl << endl;

	threshold(A1, B2, thresh1, maxval1, THRESH_BINARY_INV);
	cout << "B2中的数据为:\n" << B2 << endl << endl;

	threshold(A1, B3, thresh1, maxval1, THRESH_TRUNC);
	cout << "B3中的数据为:\n" << B3 << endl << endl;

	threshold(A1, B4, thresh1, maxval1, THRESH_TOZERO);
	cout << "B4中的数据为:\n" << B4 << endl << endl;

	threshold(A1, B5, thresh1, maxval1, THRESH_TOZERO_INV);
	cout << "B5中的数据为:\n" << B5 << endl << endl;

	return(0);
}

运行结果如下:

然后是当type取值为THRESH_OTSU 、THRESH_TRIANGLE时的示例代码。

下面的示例代码中用到的图像下载链接如下:
https://pan.baidu.com/s/1PqeJG6EbONmYg03jYQb2MQ?pwd=xu7b

当type取值为THRESH_OTSU 、THRESH_TRIANGLE时的Python示例代码如下:
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
# 出处:昊虹AI笔记网(hhai.cc)
# 用心记录计算机视觉和AI技术

# 博主微信/QQ 2487872782
# QQ群 271891601
# 欢迎技术交流与咨询

# OpenCV的版本为4.4.0

import cv2 as cv
import sys

image = cv.imread('F:/material/images/2022/2022-06/img_300_320.jpg')
if image is None:
    print('Error: Could not load image')
    sys.exit()

# cv.imshow('Source Image', image)

img_gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow('img_gray', img_gray)

thresh1 = 0
maxval1 = 250

OTSU_threshold, img_B1 = cv.threshold(img_gray, thresh1, maxval1, cv.THRESH_OTSU)
TRIANGLE_threshold, img_B2 = cv.threshold(img_gray, thresh1, maxval1, cv.THRESH_TRIANGLE)

cv.imshow('img_OTSU', img_B1)
cv.imshow('img_TRIANGLE', img_B2)

cv.waitKey(0)
cv.destroyAllWindows()

运行结果如下:



                                          

                                          

从上面的运行结果可以看出,
利用OTSU算法找到的阈值为135;
利用Triangle算法找到的阈值为203。
并且,函数threshold()当type选择为THRESH_OTSU和THRESH_TRIANGLE时,将低于阈值的值置为0,将高于阈值的值置为我们设定的maxval1 = 250。

当type取值为THRESH_OTSU 、THRESH_TRIANGLE时的C++示例代码如下:
[C++] 纯文本查看 复制代码
//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术

//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询

//OpenCV版本 OpenCV3.0

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

using namespace std;
using namespace cv;

int main()
{
	// 读取源图像
	cv::Mat image = cv::imread("F:/material/images/2022/2022-06/img_300_320.jpg", 1);
	if (image.empty())
		return -1;

	//imshow("image", image);

	Mat img_gray;

	cvtColor(image, img_gray, COLOR_BGR2GRAY);
	imshow("img_gray", img_gray);

	Mat img_B1, img_B2;
	double thresh1 = 0;
	double maxval1 = 250;

	threshold(img_gray, img_B1, thresh1, maxval1, THRESH_OTSU);
	threshold(img_gray, img_B2, thresh1, maxval1, THRESH_TRIANGLE);

	imshow("img_B1", img_B1);
	imshow("img_B2", img_B2);


	cv::waitKey(0);
	return 0;
}

运行结果如下:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|昊虹AI笔记网 ( 蜀ICP备2022024117号-1 )

GMT+8, 2024-5-2 22:56 , Processed in 0.027191 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表