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

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

1. 每个像素位置处的二值化阈值不是固定不变的,而是由其周围邻域像素的分布来决定的。

2. 亮度较高的图像区域的二值化阈值通常会较高,而亮度低的图像区域的二值化阈值则会相适应的变小。

3. 不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值。

函数原型

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

参数说明

参数1:InputArray类型的src,输入图像,填单通道,单8位浮点类型Mat即可。
参数2:函数运算后的结果存放在这。即为输出图像(与输入图像同样的尺寸和类型)。
参数3:预设满足条件的最大值。
参数4:指定自适应阈值算法。可选择ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C两种。(具体见下面的解释)。
参数5:指定阈值类型。可选择THRESH_BINARY或者THRESH_BINARY_INV两种。(即二进制阈值或反二进制阈值)。
参数6:表示邻域块大小,用来计算区域阈值,一般选择为3、5、7......等。
参数7:参数C表示与算法有关的参数,它是一个从均值或加权均值提取的常数,可以是负数。(具体见下面的解释)。
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

对参数4与参数7内容的解释:
自适应阈值化计算大概过程是为每一个象素点单独计算的阈值,即每个像素点的阈值都是不同的,就是将该像素点周围B*B区域内的像素加权平均,然后减去一个常数C,从而得到该点的阈值。B由参数6指定,常数C由参数7指定。

ADAPTIVE_THRESH_MEAN_C,为局部邻域块的平均值,该算法是先求出块中的均值,再减去常数C。

ADAPTIVE_THRESH_GAUSSIAN_C,为局部邻域块的高斯加权和。该算法是在区域中(x, y)周围的像素根据高斯函数按照他们离中心点的距离进行加权计算,再减去常数C。

举个例子:如果使用平均值方法,平均值mean为190,差值delta(即常数C)为30。那么灰度小于160的像素为0,大于等于160的像素为255。如下图:

如果是反向二值化,如下图:

delta(常数C)选择负值也是可以的。

代码演示

/*
    自适应阈值:adaptiveThreshold()函数
*/

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main()
{
    //------------【1】读取源图像并检查图像是否读取成功------------
    Mat srcImage = imread("D:\\OutPutResult\\ImageTest\\build.jpg");
    if (!srcImage.data)
    {
        cout << "读取图片错误,请重新输入正确路径!\n";
        system("pause");
        return -1;
    }
    imshow("【源图像】", srcImage);
    //------------【2】灰度转换------------
    Mat srcGray;
    cvtColor(srcImage, srcGray, CV_RGB2GRAY);
    imshow("【灰度图】", srcGray);
    //------------【3】初始化相关变量---------------
    Mat dstImage;        //初始化自适应阈值参数
    const int maxVal = 255;
    int blockSize = 3;    //取值3、5、7....等
    int constValue = 10;
    int adaptiveMethod = 0;
    int thresholdType = 1;
    /*
        自适应阈值算法
        0:ADAPTIVE_THRESH_MEAN_C
        1:ADAPTIVE_THRESH_GAUSSIAN_C
        --------------------------------------
        阈值类型
        0:THRESH_BINARY
        1:THRESH_BINARY_INV
    */
    //---------------【4】图像自适应阈值操作-------------------------
    adaptiveThreshold(srcGray, dstImage, maxVal, adaptiveMethod, thresholdType, blockSize, constValue);

    imshow("【自适应阈值】", dstImage);
    waitKey(0);
    return 0;
}

显示结果

可以发现自适应阈值能很好的观测到边缘信息。阈值的选取是算法自动完成的,很方便。

滤波处理

另外,做不做滤波处理等对图像分割影响也比较大。

1. adaptiveThreshold分割

Mat img=imread("D:/ImageTest/sudoku.png",CV_LOAD_IMAGE_COLOR);
    Mat dst1;
    Mat dst2;
    Mat dst3;
    cv::cvtColor(img,img,COLOR_RGB2GRAY);//进行,灰度处理
    medianBlur(img,img,5);//中值滤波
    threshold(img,dst1, 127, 255, THRESH_BINARY);//阈值分割
    adaptiveThreshold(img,dst2,255,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,11,2);//自动阈值分割,邻域均值
    adaptiveThreshold(img,dst3,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,11,2);//自动阈值分割,高斯邻域
    //ADAPTIVE_THRESH_MEAN_C : threshold value is the mean of neighbourhood area
    //ADAPTIVE_THRESH_GAUSSIAN_C : threshold value is the weighted sum of neighbourhood values where weights are a gaussian window.
    imshow("dst1", dst1);
    imshow("dst2", dst2);
    imshow("dst3", dst3);
    imshow("img", img);
    waitKey(0);

效果对比,很明显加入邻域权重后处理更理想:

2. 加入滤波处理的最大类间方差分割

Mat img=imread("D:/ImageTest/pic2.png",CV_LOAD_IMAGE_COLOR);
    Mat dst1;
    Mat dst2;
    Mat dst3;
    cv::cvtColor(img,img,COLOR_RGB2GRAY);//进行,灰度处理
    //    medianBlur(img,img,5);
    threshold(img,dst1, 127, 255, THRESH_BINARY);
    threshold(img,dst2,0, 255, THRESH_OTSU);//最大类间方差法分割 Otsu algorithm to choose the optimal threshold value
    Mat img2=img.clone();
    GaussianBlur(img2,img2,Size(5,5),0);//高斯滤波去除小噪点
    threshold(img2,dst3, 0, 255, THRESH_OTSU);
    imshow("BINARY dst1", dst1);
    imshow("OTSU dst2", dst2);
    imshow("GaussianBlur OTSU dst3", dst3);
    imshow("original img", img);
    waitKey(0);

效果如下,显然不滤波和滤波差别明显:

参考文章:https://blog.csdn.net/sinat_36264666/article/details/77586964

https://blog.csdn.net/abcvincent/article/details/78822191

(0)

相关推荐

  • 使用OpenCV实现图像增强

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

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

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

  • 基于OpenCV的区域分割、轮廓检测和阈值处理

    重磅干货,第一时间送达 OpenCV是一个巨大的开源库,广泛用于计算机视觉,人工智能和图像处理领域.它在现实世界中的典型应用是人脸识别,物体检测,人类活动识别,物体跟踪等. 现在,假设我们只需要从整个 ...

  • 【从零学习OpenCV 4】两图像间的像素操作

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

  • 基于OpenCV的实用图像处理操作

    重磅干货,第一时间送达 图像处理适用于图像和视频.良好的图像处理结果会为后续的进一步处理带来很大的帮助,例如提取到图像中的直线有助于对图像中物体的结构进行分析,良好的特征提取会优化深度学习的结果等.今 ...

  • OpenCV探索之路(十一):轮廓查找和多边形包围轮廓

    Canny一类的边缘检测算法可以根据像素之间的差异,检测出轮廓边界的像素,但它没有将轮廓作为一个整体.所以要将轮廓提起出来,就必须将这些边缘像素组装成轮廓. OpenCV中有一个很强大的函数,它可以从 ...

  • OpenCV探索之路(五):图片缩放和图像金字塔

    对图像进行缩放的最简单方法当然是调用resize函数啦! resize函数可以将源图像精确地转化为指定尺寸的目标图像. 要缩小图像,一般推荐使用CV_INETR_AREA来插值:若要放大图像,推荐使用 ...

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

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

  • opencv中自适应阈值函数的实现(c++)

    根据<面向飞机蒙皮接缝的线结构光检测技术研究_张卡>论文中的原理,编写了自适应阈值函数 原理: 1 //计算灰度最大最小值 2 void MaxGrayValue(Mat image,in ...

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

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

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

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

  • 自适应阈值二值化算法

    一.前言 当用照像机拍摄一副黑纸白字的纸张时,照相机获得的图像并不是真正的黑白图像.不管从什么角度拍摄,这幅图像实际上是灰度或者彩色的.除非仔细的设置灯光,否则照相机所拍摄的放在桌子上的纸张图像并不能 ...

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

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

  • httprunner 2.x学习8-参数化(引用 debugtalk 函数)

    前言 httprunner 参数化数据源指定支持三种方式: 在 YAML/JSON 中直接指定参数列表:该种方式最为简单易用,适合参数列表比较小的情况 通过内置的 parameterize(可简写为P ...

  • 在家访工作中需要“精准化”操作

    安徽 高维公 汪亚明 <深化新时代教育评价改革总体方案>,明确要求落实中小学教师家访制度,将家校联系情况纳入教师考核,指出教师家访在强化一线学生工作方面的重要作用.山东省<中小学家访 ...

  • 海鲜爆炒酱炒花甲,花甲香辣可口特好吃,简单方便,酱汁化操作

    海鲜爆炒酱炒花甲,花甲香辣可口特好吃,简单方便,酱汁化操作

  • 最全任期制和契约化操作模板.doc

    ××公司经理层成员 任期制和契约化管理办法(试行) (征求意见稿) 第一章 总则 第一条 为深入贯彻落实党中央.国务院和省委.省政府关于深化国有企业改革三年行动方案和省国资委关于推行保障经理层成员依法 ...