(7条消息) 自适应阈值(adaptiveThreshold)分割原理及实现

背景介绍及原理

前面介绍了OTSU算法和最大熵算法,但这两种算法都属于全局阈值法,所以对于某些光照不均的图像,这种全局阈值分割的方法会显得苍白无力,如下图:

显然,这样的阈值处理结果不是我们想要的,那么就需要一种方法来应对这样的情况。

这种办法就是自适应阈值法(adaptiveThreshold),它的思想不是计算全局图像的阈值,而是根据图像不同区域亮度分布,计算其局部阈值,所以对于图像不同区域,能够自适应计算不同的阈值,因此被称为自适应阈值法。(其实就是局部阈值法)

如何确定局部阈值呢?可以计算某个邻域(局部)的均值、中值、高斯加权平均(高斯滤波)来确定阈值。值得说明的是:如果用局部的均值作为局部的阈值,就是常说的移动平均法(听起来挺高大上,其实......逃)。

OpenCV提供的API:

  1. void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue,
  2. int adaptiveMethod, int thresholdType, int blockSize, double C)

说明下各参数:

InputArray src:源图像

OutputArray dst:输出图像,与源图像大小一致

int adaptiveMethod:在一个邻域内计算阈值所采用的算法,有两个取值,分别为 ADAPTIVE_THRESH_MEAN_C 和 ADAPTIVE_THRESH_GAUSSIAN_C 。

ADAPTIVE_THRESH_MEAN_C的计算方法是计算出领域的平均值再减去第七个参数double C的值。

ADAPTIVE_THRESH_GAUSSIAN_C的计算方法是计算出领域的高斯均值再减去第七个参数double C的值。

int thresholdType:这是阈值类型,只有两个取值,分别为 THRESH_BINARY 和THRESH_BINARY_INV  具体的请看官方的说明,这里不多做解释。

int blockSize:adaptiveThreshold的计算单位是像素的邻域块,这是局部邻域大小,3、5、7等。

double C:这个参数实际上是一个偏移值调整量,用均值和高斯计算阈值后,再减或加这个值就是最终阈值。

注:相比OpenCV的API,我多用了一个中值法确定阈值。

 

基于OpenCV实现

  1. #include <iostream>
  2. #include <opencv2/core.hpp>
  3. #include <opencv2/highgui.hpp>
  4. #include <opencv2/imgproc.hpp>
  5. enum adaptiveMethod{meanFilter,gaaussianFilter,medianFilter};
  6. void AdaptiveThreshold(cv::Mat& src, cv::Mat& dst, double Maxval, int Subsize, double c, adaptiveMethod method = meanFilter){
  7. if (src.channels() > 1)
  8. cv::cvtColor(src, src, CV_RGB2GRAY);
  9. cv::Mat smooth;
  10. switch (method)
  11. {
  12. case meanFilter:
  13. cv::blur(src, smooth, cv::Size(Subsize, Subsize)); //均值滤波
  14. break;
  15. case gaaussianFilter:
  16. cv::GaussianBlur(src, smooth, cv::Size(Subsize, Subsize),0,0); //高斯滤波
  17. break;
  18. case medianFilter:
  19. cv::medianBlur(src, smooth, Subsize); //中值滤波
  20. break;
  21. default:
  22. break;
  23. }
  24. smooth = smooth - c;
  25. //阈值处理
  26. src.copyTo(dst);
  27. for (int r = 0; r < src.rows;++r){
  28. const uchar* srcptr = src.ptr<uchar>(r);
  29. const uchar* smoothptr = smooth.ptr<uchar>(r);
  30. uchar* dstptr = dst.ptr<uchar>(r);
  31. for (int c = 0; c < src.cols; ++c){
  32. if (srcptr[c]>smoothptr[c]){
  33. dstptr[c] = Maxval;
  34. }
  35. else
  36. dstptr[c] = 0;
  37. }
  38. }
  39. }
  40. int main(){
  41. cv::Mat src = cv::imread("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Img\\Fig1049(a)(spot_shaded_text_image).tif");
  42. if (src.empty()){
  43. return -1;
  44. }
  45. if (src.channels() > 1)
  46. cv::cvtColor(src, src, CV_RGB2GRAY);
  47. cv::Mat dst, dst2;
  48. double t2 = (double)cv::getTickCount();
  49. AdaptiveThreshold(src, dst, 255, 21, 10, meanFilter); //
  50. t2 = (double)cv::getTickCount() - t2;
  51. double time2 = (t2 *1000.) / ((double)cv::getTickFrequency());
  52. std::cout << "my_process=" << time2 << " ms. " << std::endl << std::endl;
  53. cv::adaptiveThreshold(src, dst2, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 21, 10);
  54. cv::namedWindow("src", CV_WINDOW_NORMAL);
  55. cv::imshow("src", src);
  56. cv::namedWindow("dst", CV_WINDOW_NORMAL);
  57. cv::imshow("dst", dst);
  58. cv::namedWindow("dst2", CV_WINDOW_NORMAL);
  59. cv::imshow("dst2", dst2);
  60. //cv::imwrite("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Image Filtering\\MeanFilter\\TXT.jpg",dst);
  61. cv::waitKey(0);
  62. }

效果

这个效果就好很多了。

(0)

相关推荐

  • opencv python智能车道检测,助力无人驾驶

    近年来,基于人工智能的车道检测算法得到了广泛的研究.与传统的基于特征的方法相比,许多方法表现出了优越的性能.然而,当使用具有挑战性的图像时,其准确率通常仍在低80%或高90%之间,甚至更低. 准确可靠 ...

  • python进阶—OpenCV之常用图像操作函数说明

    文章目录 cv2.threshold cv2.bitwise_and cv2.bitwise_or cv2.bitwise_not cv2.inRange cv2.resize cv2.adaptiv ...

  • 二值化处理与边缘检测

    问题:我在提取图像边缘的时候,首先对图像进行灰度变换,之后进行二值处理,最后进行边缘检测得到边缘图像. 但是在查阅资料的过程中我经常发现很多人忽略二值化的步骤,直接进行边缘检测:还有很多人在实现某些功 ...

  • python进阶—OpenCV之图像处理(一)

    文章目录 颜色空间转换 RGB色彩空间 HSV色彩空间 YUV色彩空间 简单的物体跟踪示例 HSV空间目标阈值选取 图像几何变换 图像的缩放 图像的位移 图像的旋转 图像的仿射 图像的投射 图像阈值( ...

  • 【从零学习OpenCV 4】图像二值化

    重磅干货,第一时间送达 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍<从零学习OpenCV 4>.为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通 ...

  • 使用OpenCV实现图像增强

    重磅干货,第一时间送达 本期将介绍如何通过图像处理从低分辨率/模糊/低对比度的图像中提取有用信息. 下面让我们一起来探究这个过程: 首先我们获取了一个LPG气瓶图像,该图像取自在传送带上运行的仓库.我 ...

  • (21条消息) 自适应阈值(adaptiveThreshold)分割原理及实现

    背景介绍及原理 前面介绍了OTSU算法和最大熵算法,但这两种算法都属于全局阈值法,所以对于某些光照不均的图像,这种全局阈值分割的方法会显得苍白无力,如下图: 显然,这样的阈值处理结果不是我们想要的,那 ...

  • (6条消息) 图像阈值化

    阈值化是一种将我们想要在图像中分析的区域分割出来的方法.旨在提取图像中的目标物体,将背景以及噪声区分开来 二进制阈值化.反二进制阈值化.截断阈值化.反阈值化为0.阈值化为0

  • (21条消息) 使用积分图像的自适应阈值处理

    论文:Adaptive Thresholding Using the Integral Image 应用:matlab二值化函数 T = adaptthresh(I) 这应该是adapthresh中的 ...

  • 自适应阈值化操作:adaptiveThreshold()函数

    在图像阈值化操作中,更关注的是从二值化图像中,分离目标区域和背景区域,但是仅仅通过设定固定阈值很难达到理想的分割效果.而自适应阈值,则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值.这样 ...

  • (12条消息) 一文读懂BERT(原理篇)

    一文读懂BERT(原理篇) 2018年的10月11日,Google发布的论文<Pre-training of Deep Bidirectional Transformers for Langua ...

  • (3条消息) 特征提取、分割、分类、物体识别

    特征提取.分割.分类.物体识别 特征提取是一个过程,在该过程中,单个点或一组点可以根据低级属性检测某种类型的点."低级属性"是指没有语义(例如,位置,高程,几何形状,颜色,强度,点 ...

  • (6条消息) GPS、WiFi、基站、AGPS几种定位原理介绍与区别

    定位器的原理: "三角定位法",知道了用户到三个固定点的距离,就能计算出用户的位置. 1.GPS GPS(Global Positioning System)即全球定位系统,它是由 ...

  • (3条消息) Mongodb存储特性与内部原理

    一.存储引擎(Storage)mongodb 3.0默认存储引擎为MMAPV1,还有一个新引擎wiredTiger可选,或许可以提高一定的性能.mongodb中有多个databases,每个datab ...

  • (4条消息) ZipKin原理学习

    ZipKin入门介绍 Zipkin是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于 Google Dapper的论文设计而来,由 Twitter 公司 ...