Opencv 图像分割: 阈值化分割 区域分割 边缘分割

Opencv 图像分割: 阈值化分割 区域分割 边缘分割

卷积
就是两个函数之间的相互关系,然后得出一个新的值,在连续空间做积分计算,然后在离散空间内求和的过程。
在计算机视觉里面,可以把卷积当做一个抽象的过程,就是把小区域内的信息统计抽象出来

图像阈值化分割
按照灰度级,对像素集合进行一个划分,得到的每个子集形成一个与现实景物相对应的区域,
各个区域内部具有一致的属性,而相邻区域不具有这种一致属性。
它是一种传统的最常用的图像分割方法,因计算简单、运算效率较高、速度快、性能较稳定而成为图像分割中最基本和应用最广泛的分割技术。
它特别适用于目标和背景占据不同灰度级范围的图像,在极大的压缩数据量的同时也大大简化了分析和处理步骤,是进行图像分析、特征提取与模式识别之前的必要的图像预处理过程。
它有全局阈值、自适应阈值、最佳阈值等

二值化cvThreshold

/* Applies fixed-level threshold to grayscale image.
   This is a basic operation applied before retrieving contours */
CVAPI(double)  cvThreshold( const CvArr*  src, CvArr*  dst,
                            double  threshold, double  max_value,
                            int threshold_type );

src输入图像,须为单通道灰度图。
dst输出的边缘图像,为单通道黑白图。
threshold表示阈值
max_value表示最大值。
threshold_type表示二值化类型(即对图像取阈值的方法)

/* Threshold types */
enum
{
    CV_THRESH_BINARY      =0,  /* value = value > threshold ? max_value : 0       */
    //if src(x,y)>threshold dst(x,y) = max_value, 
    //otherwise  dst(x,y) = 0,

    CV_THRESH_BINARY_INV  =1,  /* value = value > threshold ? 0 : max_value       */
    //if src(x,y)>threshold dst(x,y) = 0, 
    //otherwise  dst(x,y) = max_value,

    CV_THRESH_TRUNC       =2,  /* value = value > threshold ? threshold : value   */
    //if src(x,y)>threshold dst(x,y) = threshold, 
    //otherwise  dst(x,y) = src(x,y),

    CV_THRESH_TOZERO      =3,  /* value = value > threshold ? value : 0           */
     //if src(x,y)>threshold dst(x,y) = src(x,y), 
    //otherwise  dst(x,y) = 0,

    CV_THRESH_TOZERO_INV  =4,  /* value = value > threshold ? 0 : value           */
     //if src(x,y)>threshold dst(x,y) = 0, 
    //otherwise  dst(x,y) = src(x,y),

    CV_THRESH_MASK        =7,
    CV_THRESH_OTSU        =8  /* use Otsu algorithm to choose the optimal threshold value;
                                 combine the flag with one of the above CV_THRESH_* values */
    //threshold_type使用CV_THRESH_OTSU,则cvThreshold()将使用大律法OTSU得到的全局自适应阈值来进行二值化图像,而参数中的threshold不再起作用
};
如:cvThreshold(grayImg, binaryImg, 145, 255, CV_THRESH_BINARY); //二值图

自适应二值化cvAdaptiveThreshold
函数使用Otsu算法(大律法或最大类间方差法)来计算出一个全局阈值,然后根据这个阈值进行二值化
Otsu实现思路
1、计算0~255各灰阶对应的像素个数,保存至一个数组中,该数组下标是灰度值,保存内容是当前灰度值对应像素数
2、计算背景图像的平均灰度、背景图像像素数所占比例
3、计算前景图像的平均灰度、前景图像像素数所占比例
4、遍历0~255各灰阶,计算并寻找类间方差极大值,此时对应的阈值就是大津法(OTSU算法)所求的阈值

/* Applies adaptive threshold to grayscale image.
   The two parameters for methods CV_ADAPTIVE_THRESH_MEAN_C and
   CV_ADAPTIVE_THRESH_GAUSSIAN_C are:
   neighborhood size (3, 5, 7 etc.),
*/

CVAPI(void)  cvAdaptiveThreshold( const CvArr* src, CvArr* dst, double max_value,
                                  int adaptive_method CV_DEFAULT(CV_ADAPTIVE_THRESH_MEAN_C),
                                  int threshold_type CV_DEFAULT(CV_THRESH_BINARY),
                                  int block_size CV_DEFAULT(3),
                                  double param1 CV_DEFAULT(5));

src输入图像
dst输出图像
max_value表示最大值
adaptive_method
自适应阈值算法使用:CV_ADAPTIVE_THRESH_MEAN_C 或 CV_ADAPTIVE_THRESH_GAUSSIAN_C .
threshold_type
阈值类型:必须是CV_THRESH_BINARY或者CV_THRESH_BINARY_INV.
block_size
用来计算阈值的象素邻域大小: 3, 5, 7, …,block_size比较小的时候,相当于提取边缘
param1
与方法有关的参数,它是一个从均值或加权均值提取的常数,它可以是负数。
对方法 CV_ADAPTIVE_THRESH_MEAN_C,先求出块中的均值,再减掉param1。
对方法 CV_ADAPTIVE_THRESH_GAUSSIAN_C ,先求出块中的加权和(gaussian),再减掉param1。

区域分割
图像按照相似性准则分成不同的区域,主要包括区域增长,区域分裂合并和分水岭等几种类型

边缘分割
通过边缘检测,即检测灰度级或者结构具有突变的地方,表明一个区域的终结,也是另一个区域开始的地方。
这种不连续性称为边缘。不同的图像灰度不同,边界处一般有明显的边缘,利用此特征可以分割图像

图像中边缘处像素的灰度值不连续,这种不连续性可通过求导数来检测到。
对于阶跃状边缘,其位置对应一阶导数的极值点,对应二阶导数的过零点(零交叉点)。
因此常用微分算子进行边缘检测。常用的:
一阶微分算子有Roberts算子、Prewitt算子和Sobel算子、LoG算子,
二阶微分算子有Laplace算子和Kirsh算子、Canny算子等。
在实际中各种微分算子常用小区域模板来表示,微分运算是利用模板和图像卷积来实现。这些算子对噪声敏感,只适合于噪声较小不太复杂的图像。

由于边缘和噪声都是灰度不连续点,在频域均为高频分量,直接采用微分运算难以克服噪声的影响。因此用微分算子检测边缘前要对图像进行平滑滤波。LoG算子和Canny算子是具有平滑功能的二阶和一阶微分算子,边缘检测效果较好

边缘检测算法:
滤波:边缘检测算法主要是基于图像强度的一阶和二阶导数,但导数的计算对噪声很敏感,因此必须使用滤波器来改善与噪声有关的边缘检测器的性能.
增强:将邻域(或局部)强度值有显著变化的点突显出来.边缘增强一般是通过计算梯度幅值来完成的.
检测:确定边缘,最简单的边缘检测判据是梯度幅值阈值判据.
定位:边缘的位置、方位可在子像素分辨率上估计出来.

CV_EXPORTS_W void Canny( InputArray image, OutputArray edges,
                         double threshold1, double threshold2,
                         int apertureSize=3, bool L2gradient=false );

1、高斯平滑滤波器卷积降噪,默然采用size = 5的高斯内核
2、运用一对卷积阵列 (分别作用于x和y方向)求导,Sobel内核大小3 X 3,计算梯度幅值和方向
3、根据阀值、梯度幅值得出边缘

Canny边缘检测算法
一个多级边缘检测算法,普遍认为是边缘检测的最优算法,Canny使用滞后阈值,滞后阈值需要两个阈值(高阈值和低阈值)
Canny使用两种不同的阈值分别检测强边缘和弱边缘,并且仅当弱边缘和强边缘相连时,才将边缘包含在输出图像中。因此不容易被噪声“填充”,更容易检测出真正的弱边缘

原灰度图像: image single-channel 8-bit input image.
输出图像 (支持原地计算,可为输入图像): edges output edge map; it has the same size and type as image
低阈值的: threshold1 first threshold for the hysteresis procedure.
高阈值的3倍 (Canny 推荐的 高:低 阈值比在 2:1 到3:1之间): threshold2 second threshold for the hysteresis procedure.

//! applies generalized Sobel operator to the image
CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth,
                         int dx, int dy, int ksize=3,
                         double scale=1, double delta=0,
                         int borderType=BORDER_DEFAULT );

Sobel算子
(对灰度渐变和噪声较多的图像处理效果较好。Sobel算子对于边缘定位比较准确)
是一个离散微分算子 (discrete differentiation operator), 它用来计算图像灰度函数的近似梯度。
通过像素点空间邻域内上下,左右相邻点的灰度加权运算,求取物体边缘(边缘是指一个物体与另一个物体的分界处,一般边缘内外处都会有灰度值上的差异)
Sobel 算子结合了高斯平滑和微分求导, Scharr更准确地计算 3 X 3 核(Gx、Gy卷积因子)的导数
X\Y两个方向求导(输入图像与卷积核Gx和Gy进行卷积)-> 图像的每一点,结合以上两个结果求出近似梯度 -> 定位梯度值大于邻域的相素,作为边缘
ddepth: value as below
CV_8U = 0,
CV_8S = 1,
CV_16U = 2,
CV_16S = 3,
CV_32S = 4,
CV_32F = 5,
CV_64F = 6,
CV_USRTYPE1 = 7;

  • 5
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值