图像的二值化

图像二值化

简介

  • 图像二值化就是将图像像素的灰度值设置成只有最大值和最小值两种取值,使整个图像呈现出 “非黑即白” 的效果,是最简单的图像分割的方法

  • 应用举例:从一副图像中利用阈值分割出我们需要的物体部分(当然这里的物体可以是一部分或者整体)。这样的图像分割方法是基于图像中物体与背景之间的灰度差异,而且此分割属于像素级的分割

threshold()

简介

该函数是众多二值化方法的集成,所有的方法都实现了一个功能,就是给定一个阈值,计算所有像素灰度值与这个阈值的关系,得到最终的比较结果

double cv::threshold(src, dst, thresh, maxval, type)
  • src:输入图像,只能是CV_8U和CV_32F两种数据类型

  • dst:输出图像,与输入图像具有相同的尺寸、数据类型和通道数

  • thresh:二值化阈值

  • maxval:二值化过程中的最大值

  • type:选择图像二值化方法的标志,可选择的标志及含义如下

    标志参数 简记 作用
    THRESH_BINARY 0 灰度值大于阈值的为最大值,其他值为0
    THRESH_BINARY_INV 1 灰度值大于阈值的为0,其他值为最大值
    THRESH_TURNC 2 灰度值大于阈值的为阈值,其他值不变
    THRESH_TOZERO 3 灰度值大于阈值的不变,其他值为0
    THRESH_TOZERO_INV 4 灰度值大于阈值的为0,其他值不变
    THRESH_OTSU 8 大津法自动寻求全局阈值
    THRESH_TRIANGLE 16 三角形法自动寻求全局阈值

THRESH_OTSUTHRESH_TRIANGLE是获取阈值的方法,并不是阈值比较方法的标志,这两个标志可以与前面5种标志一起使用,例如 THRESH_BINARY | THRESH_OTSU。这两个标志分别利用大津法(OTUS)和三角形法(TRIANGLE)结合图像灰度值分布特性获取二值化的阈值,并将阈值以函数返回值的形式给出。因此,如果该函数最后一个参数设置了这两个标志中的任何一个,那么该函数第三个参数thresh将由系统自动给出,但是在调用函数时仍然不能默认,只是程序不会使用这个数值。另外,这两个标志目前只支持输入CV_8UC1类型的图像

实现

示例代码:

#include <opencv2/opencv.hpp>
using namespace cv;

int main()
{
    Mat_<Vec3b> img = imread("/home/kslas/OpenCV/lena.tif");
    imshow("Original", img);

    Mat_<uchar> gray;
    cvtColor(img, gray, COLOR_BGR2GRAY);

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

    // 灰度图BINARY二值化
    Mat_<uchar> gray_B, gray_B_V;
    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变换
    Mat_<uchar> gray_T, gray_T_V;
    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变换
    Mat_<uchar> gray_TRUNC;
    threshold(gray, gray_TRUNC, 125, 255, THRESH_TRUNC);
    imshow("gray_TRUNC", gray_TRUNC);

    // 灰度图像大津法和三角形法二值化
    Mat_<uchar> img_Thr = imread("/home/kslas/OpenCV/dark.png", 0);
    Mat_<uchar> img_Thr_O, img_Thr_T;
    threshold(img_Thr, img_Thr_O, 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_O", img_Thr_O);
    imshow("img_Thr_T", img_Thr_T);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

运行结果:

adaptiveThreshold()

简介

  • threshold()函数全局只使用一个阈值,在实际情况中,由于光照不均匀以及阴影的存在,全局只有一个阈值会使得在阴影处的白色区域也会被函数二值化成黑色,因此adaptiveThreshold()函数提供了两种局部自适应阈值的二值化方法
void cv::adaptiveThreshold(src, dst, maxValue, adaptiveMethod, thresholdType, blockSize, C)
  • src:输入图像,只能是CV_8UC1类型
  • dst:输出图像
  • maxValue:二值化的最大值
  • adaptiveMethod:自适应确定阈值的方法,分为均值法ADAPTIVE_THRESH_MEAN_C和高斯法ADAPTIVE_THRESH_GAUSSIAN_C两种
  • thresholdType:选择图像二值化方法的标志,只能是THRESH_BINARYTHRESH_BINARY_INV
  • blockSize:自适应确定阈值的像素邻域大小,一般为3、5、7的奇数
  • C:从平均值或加权平均值中减去的常数,可以为正,也可以为负

实现

示例代码:

#include <opencv2/opencv.hpp>
using namespace cv;

int main()
{
    Mat_<uchar> img_Thr = imread("/home/kslas/OpenCV/dark.png", 0);

    // 灰度图像自适应二值化
    Mat_<uchar> 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("img_Thr", img_Thr);
    imshow("adaptive_mean", adaptive_mean);
    imshow("adaptive_gauss", adaptive_gauss);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

运行结果:

posted @ 2022-01-22 15:12  TNTksals  阅读(1123)  评论(0编辑  收藏  举报