|
使用OpenCV的函数threshold()对图像进行二值化或阈值化处理
如果一幅图像,其像素的灰度值只有两个取值,那么这样的图像我们就称作二值图像。
把图像转化为二值图像的过程称为图像的二值化处理。
如果对图像的灰度值按与某个值的大小关系进行新值的设置,称为叫图像的阈值化处理。
在OpenCV中,可以使用函数threshold()对图像作二值化或阈值化处理。
其原型如下:
C++原型如下:
- double cv::threshold(InputArray src,
- OutputArray dst,
- double thresh,
- double maxval,
- int type)
复制代码
Python原型如下:
- double cv::threshold(InputArray src,
- OutputArray dst,
- double thresh,
- double maxval,
- 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—这个参数的可选枚举值及意义如下:
![](http://pic1.hhai.cc/pic1/2022/2022-12/001/01.png)
要特别注意的是,在Python环境中,函数threshold()的返回值有两个,分别为retval和dst。
第一个retval代表函数threshold()在进行二值化处理时使用的阈值,这一点挺好,特别是对于type选择THRESH_OTSU或THRESH_TRIANGLE时,我们可以知道进行二值处理时用的阈值究竟是多少。
如果不想使用retval这个返回值,可以像下面这样调用:
- _, 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)
运行结果如下:
![](http://pic1.hhai.cc/pic1/2022/2022-12/001/02.png)
![](http://pic1.hhai.cc/pic1/2022/2022-12/001/03.png)
当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);
}
运行结果如下:
![](http://pic1.hhai.cc/pic1/2022/2022-12/001/04.png)
然后是当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()
运行结果如下:
![](http://pic1.hhai.cc/pic1/2022/2022-12/001/05.png)
![](http://pic1.hhai.cc/pic1/2022/2022-12/001/06.png)
![](http://pic1.hhai.cc/pic1/2022/2022-12/001/07.png)
![](http://pic1.hhai.cc/pic1/2022/2022-12/001/08.png)
从上面的运行结果可以看出,
利用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;
}
运行结果如下:
![](http://pic1.hhai.cc/pic1/2022/2022-12/001/09.png) |
|