本文详细介绍基于opencv的图像二值化,图像二值化即是设置一个阈值T,如果图像像素点的灰度值小于T此点值设为0(黑),反之设为255(白),最后图像只有黑和白两种颜色。
opencv中的二值化函数有两种,阈值化的图像二值化,自适应阈值化的二值化,我们接下来先介绍两种二值化函数:
1、阈值化函数:
cvThreshold (constCvArr* src, CvArr* dst, double threshold, double max_value,int threshold_type)
src –原始数组 (单通道 , 8-bit of 32-bit 浮点数)。
dst –输出数组,必须与 src 的类型一致,或者为 8-bit。
thresh –阈值。
max_value –使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值。
threshold_type –对图像取阈值的方法。
如果threshold_type=CV_THRESH_BINARY:
if src(x,y)>threshold dst(x,y) = max_value, else dst(x,y) =0.
如果threshold_type=CV_THRESH_BINARY_INV:
if src(x,y)>threshold dst(x,y) = 0, else dst(x,y) =max_value.
如果threshold_type=CV_THRESH_TRUNC:
if src(x,y)>threshold dst(x,y) = threshold , else dst(x,y) =src(x,y).
如果threshold_type=CV_THRESH_TOZERO:
if src(x,y)>threshold dst(x,y) = src(x,y), else dst(x,y) =0.
如果threshold_type=CV_THRESH_TOZERO_INV:
if src(x,y)>threshold dst(x,y) = 0, else dst(x,y) =src(x,y).
2、自适应阈值化函数
cvAdaptiveThreshold ( const CvArr* src, CvArr* dst, double max_value, int adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C,
int thresthold_type= CV_THRESH_BINARY,
int block_size=3, double param1=5)
src :输入图像.
dst :输出图像.
max_value :使用 CV_THRESH_BINARY 和CV_THRESH_BINARY_INV 的最大值.
adaptive_method:自适应阈值算法使用:CV_ADAPTIVE_THRESH_MEAN_C 或 CV_ADAPTIVE_THRESH_GAUSSIAN_C .
函数 cvAdaptiveThreshold 将灰度图像变换到二值图像,采用下面公式:
如果threshold_type=CV_THRESH_BINARY:
if src(x,y)>threshold dst(x,y) = max_value, else dst(x,y) =0.
如果threshold_type=CV_THRESH_BINARY_INV:
if src(x,y)>threshold dst(x,y) = 0, else dst(x,y) =max_value.
threshold_type:取阈值类型:必须是下者之一
(1)CV_THRESH_BINARY,
(2)CV_THRESH_BINARY_INV
block_size :用来计算阈值的象素邻域大小: 3, 5, 7, ...
param1:与方法有关的参数。对方CV_ADAPTIVE_THRESH_MEAN_C 和 CV_ADAPTIVE_THRESH_GAUSSIAN_C, 它是一个从均值或加权均值提取的常数, 尽管它可以是负数。
阈值化二值化实现代码:
#include
#include
using namespace cv;
using namespace std;
void main()
{
Mat src, imgGray;
Mat dst1,dst2,dst3,dst4,dst5;
src = imread("lena.jpg");
namedWindow("src", WINDOW_NORMAL);
imshow("src", src);
if(src.channels()>1)
cvtColor(src, imgGray, CV_BGR2GRAY);//二值化前先进行灰度转换
else imgGray = src;
//threshold_type=CV_THRESH_BINARY:
threshold(imgGray,dst1,120,255, CV_THRESH_BINARY);
namedWindow("CV_THRESH_BINARY", WINDOW_NORMAL);
imshow("CV_THRESH_BINARY", dst1);
//threshold_type=CV_THRESH_BINARY_INV:
threshold(imgGray, dst2, 120, 255, CV_THRESH_BINARY_INV);
namedWindow("CV_THRESH_BINARY_INV", WINDOW_NORMAL);
imshow("CV_THRESH_BINARY_INV", dst2);
//threshold_type=CV_THRESH_TRUNC:
threshold(imgGray, dst3, 120, 255, CV_THRESH_BINARY_INV);
namedWindow("CV_THRESH_TRUNC", WINDOW_NORMAL);
imshow("CV_THRESH_TRUNC", dst3);
//threshold_type=CV_THRESH_TOZERO:
threshold(imgGray, dst4, 120, 255, CV_THRESH_TOZERO);
namedWindow("CV_THRESH_TOZERO", WINDOW_NORMAL);
imshow("CV_THRESH_TOZERO", dst4);
//threshold_type=CV_THRESH_TOZERO_INV:
threshold(imgGray, dst5, 120, 255, CV_THRESH_TOZERO_INV);
namedWindow("CV_THRESH_TOZERO_INV", WINDOW_NORMAL);
imshow("CV_THRESH_TOZERO_INV", dst5);
waitKey();
}
结果:
src CV_THRESH_BINARY CV_THRESH_BINARY_INV
CV_THRESH_TRUNC CV_THRESH_TOZERO CV_THRESH_TOZERO_INV
自适应阈值化实现代码:
#include
#include
using namespace cv;
using namespace std;
void main()
{
Mat src, imgGray;
Mat dst1,dst2;
src = imread("lena.jpg");
namedWindow("src", WINDOW_NORMAL);
imshow("src", src);
if(src.channels()>1)
cvtColor(src, imgGray, CV_BGR2GRAY);//二值化前先进行灰度转换
else imgGray = src;
//threshold_type=CV_THRESH_BINARY:
adaptiveThreshold(imgGray,dst1,255,ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY,25,5);
namedWindow("CV_THRESH_BINARY", WINDOW_NORMAL);
imshow("CV_THRESH_BINARY", dst1);
//threshold_type=CV_THRESH_BINARY_INV:
adaptiveThreshold(imgGray, dst2, 255, ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 25, 5);
namedWindow("CV_THRESH_BINARY_INV", WINDOW_NORMAL);
imshow("CV_THRESH_BINARY_INV", dst2);
waitKey();
}
结果:
src CV_THRESH_BINARY CV_THRESH_BINARY_INV
上述结果是当adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C的;
当adaptive_method=CV_ADAPTIVE_THRESH_GAUSSIAN_C时,结果为:
src CV_THRESH_BINARY CV_THRESH_BINARY_INV
到此图像二值化介绍告一段落,迎大家留言讨论,如有兴趣一起学习图像处理、计算机视觉、深度学习相关领域欢迎关注号,一起学习进步,
可以微信搜索“图像处理CV讲武堂”关注,也可如下二维扫码关注。