自适应阈值分割

1.原理
       最简单的阈值分割即为手动设置阈值对图像进行二值化,大于设定的阈值像素值设置为255,小于设定阈值则为0.这种方法一般称为全局阈值分割,接下来想介绍的是一种局部阈值分割算法,其原理很简单,通俗地讲就是图片的每个局部都会通过处理得到一个阈值,这个区域就用这个阈值来进行分割,同理,每个区域都有不同的阈值来处理,如何来获取这个阈值就是整个算法的关键。
       这里用opencv的API接口来进行说明,opencv库有接口函数
void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C)
src为输入图像,
dst为输出图像,
maxValue为设定的像素最大值,
adptiveMethod为使用的滤波方法,opencv给出了两种方法,分别为ADAPTIVE_THRESH_MEAN_C 和ADAPTIVE_THRESH_GAUSSIAN_C,
thresholdType为阈值类型,THRESH_BINARY 和THRESH_BINARY_INV,
blockSize指的是邻域的大小,也就是通常说的核的大小,一般为奇数,
C为阈值的偏移量。
        当使用ADAPTIVE_THRESH_MEAN_C方法时阈值为邻域的均值减去C,当使用ADAPTIVE_THRESH_GAUSSIAN_C方法时,阈值为邻域的高斯均值减去C。

2.代码展示
自己的自适应阈值分割方法,加入了中值滤波

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

using namespace std;
using namespace cv;

enum FliterMethod {
 meanFliter,
 gaaussianFliter,
 medianFliter
};
void AdaptiveThreshold(Mat &src, Mat &dst,double Maxval, int Subsize,double C ,FliterMethod method )
{
 if (src.channels() > 1)
  cvtColor(src,src,CV_RGB2GRAY);
 Mat smooth;
 switch (method)
 {
 case meanFliter:
  blur(src, smooth, Size(Subsize, Subsize));
  break;
 case gaaussianFliter:
  GaussianBlur(src, smooth, Size(Subsize, Subsize), 0, 0);
  break;
 case medianFliter:
  medianBlur(src, smooth, Subsize);
  break;
 default:
  break;
 }
 smooth = smooth - C;
 src.copyTo(dst);
 int r = dst.rows;
 int c = dst.cols;
 for (int i = 0; i < r; i++)
 {
  for (int j = 0; j < c; j++)
  {
   if (dst.at<uchar>(i,j) > smooth.at<uchar>(i,j))
    dst.at<uchar>(i,j) = Maxval;
   else
    dst.at<uchar>(i,j) = 0;
  }
 }
}

为了看下实时处理的效果,调用了电脑摄像头,代码如下

int Capture() {
 VideoCapture cap;
 cap.open(0);
 Mat frame;
 //Mat src;
 if (!cap.isOpened())
  return -1;
 while (1)
 {
  cap.read(frame);
  if (frame.empty())
   break;
  //GaussianBlur(frame, src, Size(5, 5), 3, 3);
  Mat src,tmp;
  AdaptiveThreshold(frame, src, 255, 7, 5, meanFliter);
  adaptiveThreshold(frame, tmp, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 7, 10);
  //imshow(" ", frame);
  imshow("AdaptiveThreshold",src);
  imshow("opencv", tmp);
  waitKey(10);
 }
 cap.release();
 destroyAllWindows();
}

以下为测试代码

int main()
{
 Mat img = imread("C:/Users/94077/Desktop/QQ截图20200307162029.bmp");
 Mat src,tmp;
 AdaptiveThreshold(img, src, 255, 7, 10, gaaussianFliter);
 adaptiveThreshold(img, tmp, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY,7, 10);
 imshow("function", src);
 imshow("opencv", tmp);
 waitKey(0);
 //Capture();
 return 0}

3.结果展示
       这里放几张处理的图片对比一下,发现还是opencv的库函数处理效果好一点,但是针对不同的图片,在某些时候中值滤波的效果可能要比其余两种效果好。
在这里插入图片描述在这里插入图片描述

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值