阈值处理

图像阈值处理是实现图像分割的一种方法,常用的阈值分割方法有简单阈值,自适应阈值,Otsu's二值化等。

cv2.threshold()可以用来进行图像阈值处理,cv2.threshold(src, thresh, maxval, type) 第一个参数是原图像,第二个参数是对像素值进行分类的阈值,第三个参数是当像素值高于(小于)阈值时,应该被赋予的新的像素值,第四个参数是阈值方法。函数有两个返回值,一个为retVal, 一个阈值化处理之后的图像。

常用的阈值方法有:

图像二值化:基于图像的直方图来实现的,0白色 1黑色

一 二值化

  定义:图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。

   一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(Binarization)。

method阈值类型一般分为五种: 

  • cv2.THRESH_BINARY——大于阈值的部分像素值变为最大值,其他变为0                       //阈值二值化
  • cv2.THRESH_BINARY_INV——大于阈值的部分变为0,其他部分变为最大值                  //阈值反二值化
  • cv2.THRESH_TRUNC——大于阈值的部分变为阈值,其余部分不变                                //截断阈值化 -> 大于阈值为阈值,小于阈值不变
  • cv2.THRESH_TOZERO——大于阈值的部分不变,其余部分变为0                                  //阈值取零
  • cv2.THRESH_TOZERO_INV——大于阈值的部分变为0,其余部分不变                         //阈值反取零 (threshold to zero inverted)

具体可参考:https://www.jianshu.com/p/497bc5497bde

总之:

  1. 阈值可以视作最简单的图像分割方法:基于图像中物体与背景之间的灰度差异,此分割属于像素级的分割
  2. 该函数的典型应用是对灰度图像进行阈值操作得到二值图像或者去掉噪声,例如过滤很小或很大像素的图像点

具体实例如下:

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>

    using namespace cv;

  // 原图像
  Mat srcImage, dstImage;

  // 调整阈值类型的变量
  int g_ThresholdType = 0;
  int g_ThresholdValue = 128;

  // 回调函数
  static void OnThresholdMethod(int, void*);


  int main(int argc, char** argv)
  {
      // 载入图像
      srcImage = imread("E:\VS2015Opencv\vs2015\project\picture\01.jpg");

      // 判断图像是否为空
      if (srcImage.empty())
      {
          printf("image error!");
          return 0;
      }

      // 对原图像进行备份
      dstImage = srcImage.clone();

      namedWindow("原图");
      imshow("原图", dstImage);

      // 判断图像是彩色图像还是灰度图像
      // 如果图像是彩色图像,需要将图像转换为灰度图像
      if (srcImage.channels() == 3)
      {
          cvtColor(srcImage, srcImage, COLOR_BGR2GRAY);
      }

      namedWindow("【效果图】");

      createTrackbar("阈值大小:",
          "【效果图】",
          &g_ThresholdValue,
          255,
          OnThresholdMethod);

      createTrackbar("阈值类型:",
          "【效果图】",
          &g_ThresholdType,
          8,
          OnThresholdMethod);

      // 调用回调函数
      OnThresholdMethod(0, 0);

      waitKey(0);
      return 0;
  }

  void OnThresholdMethod(int, void*)
  {
      Mat tmpImage = srcImage.clone();
      // 设置二值化的类型
      //目前,Otsu或者Triangle算法仅支持8位单通道图像的实现
      // 因此与这两个算法组合的时候,需要将图像转换为灰度图像
      if (g_ThresholdType == 5)
      {
          if (srcImage.channels() == 3)
              cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);
          g_ThresholdType = THRESH_OTSU + THRESH_BINARY;
      }
      if (g_ThresholdType == 6)
      {
          if (srcImage.channels() == 3)
              cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);
          g_ThresholdType = THRESH_OTSU + THRESH_BINARY_INV;
      }
      if (g_ThresholdType == 7)
      {
          if (srcImage.channels() == 3)
              cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);
          g_ThresholdType = THRESH_TRIANGLE + THRESH_BINARY;
      }
      if (g_ThresholdType == 8)
      {
          if (srcImage.channels() == 3)
              cvtColor(srcImage, tmpImage, COLOR_BGR2GRAY);
          g_ThresholdType = THRESH_TRIANGLE + THRESH_BINARY_INV;
      }

      // 二值化处理
      threshold(tmpImage,
          dstImage,
          g_ThresholdValue,
          255,
          g_ThresholdType);

      imshow("【效果图】", dstImage);
  }
原文地址:https://www.cnblogs.com/fcfc940503/p/11246838.html