精华内容
下载资源
问答
  • 常用的分割方法有
    千次阅读
    2018-11-20 16:43:26

    图像分割有很多各种各样的方法:1)基于数学统计的方法(灰度直方图)2)基于纹理的方法3)基于阈值的方法4)基于深度学习的方法5)基于几何数学的方法。当然这五种方法也可以交叉使用,总之,挑选适用的方法效率最高,分割效果也最好。

    1)基于数学统计的方法

           数学统计主要是分析数据的直方图,根据直方图中概率模型进行分割,如统计图像某一个范围内的值所占比重,利用这种特定 的比重去分割图像;或者使用聚类的方法将图像聚类到不同类别;

    2)基于纹理的方法

          基于纹理的方法主要是根据地物纹理的不同特征(粗糙度,相似性等)对图像进行分割,主要用到灰度共生矩阵、分形理论、直方图矩等方法。纹理分析的一个弊端是:不能有效区分纹理相似但属性不同的地物(如山地雪和云,其粗糙度和自相似性基本一致,但是可以分割其他地物);

    3)基于阈值的方法

         阈值分割通常有两种:经验阈值和自适应阈值;在实际应用中,经验阈值较为常用,可以根据生产需求进行设定;自适应阈值在自动化过程中用的多,一般自适应算法都要选择自适应阈值。

    4)基于深度学习的方法

         目前深度学习还处在一个尴尬的时期,去学习自然界的地物特征需要大量经验的总结,进度缓慢。

    5)基于几何数学的方法

          几何学是从自然界中抽象出来的一门学科,其运行符合一定的自然运行规律,在某些图像分割中使用一些简单的几何图形(如三角形,方形,圆形,直线,角度,面积,周长)(高维的有分形几何)就可以将目标分割出来。

    6)几种方法的结合使用

         在进行图像分割时经常使用不同方法结合使用来达到分割效果良好的状态,分割步骤的不同,使用顺序也不同:数学统计的方法一般作为预处理和中间参考来使用(因为它是基于概率统计的,有一定 的参考性);纹理的方法是作为分割主要策略来进行的;阈值分割通常作为最后的分割手段,几乎在所有图像分割中都要用到,是作为结果输出的部分。深度学习迭代需要大量的样本进行训练,因为数据的供求和样本制作的耗时耗力,个人不太好做,需要机会。

    更多相关内容
  • 本文实例汇总了C++常用字符串分割方法,分享给大家供大家参考。具体分析如下: 我们在编程的时候经常会碰到字符串分割的问题,这里总结下,也方便我们以后查询使用。 一、用strtok函数进行字符串分割 原型: char *...
  • 主要介绍了js常用分割取字符串的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 本文大家整理了一些比较好用的关于python分割文件的方法方法非常的简单实用。分享给大家供大家参考。具体如下: 例子1 指定分割文件大小 配置文件 config.ini: 复制代码 代码如下:[global] #原文件存放目录 dir1=...
  • 点云常用分割方法

    千次阅读 2020-09-01 15:00:50
    转载自博客园IronStark点云分割系列:https://www.cnblogs.com/ironstark/p/5027269.html ... 点云分割  点云分割可谓点云处理的精髓,也是三维图像相对二维图像最大...而在现实点云数据中,往往对场景中的物体一定.

    转载自博客园IronStark点云分割系列https://www.cnblogs.com/ironstark/p/5027269.html

    转载自菜鸟知识搬运工https://blog.csdn.net/qq_30815237/article/details/91345015###

    点云分割

      点云分割可谓点云处理的精髓,也是三维图像相对二维图像最大优势的体现。

      点云分割的目的是提取点云中的不同物体,从而实现分而治之,突出重点,单独处理的目的。而在现实点云数据中,往往对场景中的物体有一定先验知识。比如:桌面墙面多半是大平面,桌上的罐子应该是圆柱体,长方体的盒子可能是牛奶盒......对于复杂场景中的物体,其几何外形可以归结于简单的几何形状。这为分割带来了巨大的便利,因为简单几何形状是可以用方程来描述的,或者说,可以用有限的参数来描述复杂的物体。而方程则代表的物体的拓扑抽象。于是,RanSaC算法可以很好的将此类物体分割出来。

    1、RanSaC算法

      RanSaC算法(随机采样一致)原本是用于数据处理的一种经典算法,其作用是在大量噪声情况下,提取物体中特定的成分。下图是对RanSaC算法效果的说明。图中有一些点显然是满足某条直线的,另外有一团点是纯噪声。目的是在大量噪声的情况下找到直线方程,此时噪声数据量是直线的3倍。

                             

      如果用最小二乘法是无法得到这样的效果的,直线大约会在图中直线偏上一点。关于随机采样一致性算法的原理参考博客:

    https://blog.csdn.net/qq_30815237/article/details/90405087

      这个算法就是从一堆数据里挑出自己最心仪的数据。所谓心仪当然是有个标准(目标的形式:满足直线方程?满足圆方程?以及能容忍的误差e)。平面中确定一条直线需要2点,确定一个圆则需要3点。

    1. 平面中随机找两个点,拟合一条直线,并计算在容忍误差e中有多少点满足这条直线
    2. 重新随机选两点,拟合直线,看看这条直线是不是能容忍更多的点,如果是则记此直线为结果
    3. 重复步骤二(循环迭代)
    4. 迭代结束,记录当前结果

         算法的优点是噪声可以分布的任意广,噪声可以远大于模型信息。这个算法有两个缺点,第一,必须先指定一个合适的容忍误差e。第二,必须指定迭代次数作为收敛条件

      综合以上特性,本算法非常适合从杂乱点云中检测某些具有特殊外形的物体。

    PCL中基于RanSaC的点云分割方法:

     
    1. //创建一个模型参数对象,用于记录结果

    2. pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);

    3. //inliers表示误差能容忍的点 记录的是点云的序号

    4. pcl::PointIndices::Ptr inliers (new pcl::PointIndices);

    5. // 创建一个分割器

    6. pcl::SACSegmentation<pcl::PointXYZ> seg;

    7. // Optional

    8. seg.setOptimizeCoefficients (true);

    9. // Mandatory-设置目标几何形状

    10. seg.setModelType (pcl::SACMODEL_PLANE);

    11. //分割方法:随机采样法

    12. seg.setMethodType (pcl::SAC_RANSAC);

    13. //设置误差容忍范围

    14. seg.setDistanceThreshold (0.01);

    15. //输入点云

    16. seg.setInputCloud (cloud);

    17. //分割点云

    18. seg.segment (*inliers, *coefficients);

    除了平面以外,PCL几乎支持所有的几何形状。作为点云分割的基础算法,RanSaC很强大且必收敛,可以作为机器人抓取,识别等后续任务的前处理。

    2、基于临近信息的点云分割

          分割给人最直观的影响大概就是邻居和我不一样。 除了之前提到的基于采样一致的分割方式以外,还存在基于邻近搜索的分割方式。通过对比某点和其最近一点的某些特征,来实现点云的分割。图像所能提供的分割信息仅是灰度或RGB向量,而三维点云却能够提供更多的信息。故点云在分割上的优势是图像所无法比拟的。

    kdTree&OcTree

      由于分割工作需要对点云的邻近点进行操作,不断对比和访问某个点的邻居,所以决定点云的相邻关系是非常重要的。对于Scan来说,邻居关系是天然的。但对于很多杂乱点云,或者滤波,分割后的点云来说,邻居关系就已经被破坏了。确定一个点云之间的相邻关系可以通过“树”来完成,目前比较主流的方法包括:kdTree和OcTree,这两种方法各有特点。

    2.1、kdTree---一种递归的邻近搜索策略

      kdTree实际上包括两个部分:1.建立kdTree,2.在kdTree中查找。建立kdTree实际上是一个不断划分的过程,首先选择最sparse的维度,然后找到该维度上的中间点,垂直该维度做第一次划分。此时k维超平面被一分为二,在两个子平面中再找最sparse的维度,依次类推知道最后一个点也被划分。那么就形了一个不断二分的树。如图所示。

      

         一般情况下,一个点的邻近点只需要在其父节点和子节点中搜索即可,大大缩小了邻近点的搜索规模。并且kdtree可以有效的对插入点进行判断其最近点在哪个位置。对于低层次视觉来说kdTree算法是非常重要的。在很多情况下需要给出某个点,再查k临近点的编号,或者差某半径范围内的点。

    2.2、OcTree

      OcTree是一种更容易理解也更自然的思想。对于一个空间,如果某个角落里有个盒子我们却不知道在哪儿。显而易见的方法就是把空间化成8个卦限,然后询问在哪个卦限内。再将存在的卦限继续化成8个。意思大概就是太极生两仪,两仪生四象,四象生八卦,就这么一直划分下去,最后一定会确定一个非常小的空间。对于点云而言,只要将点云的立方体凸包用octree生成很多很多小的卦限,那么在相邻卦限里的点则为相邻点。

      显然,对于不同点云应该采取不同的搜索策略,如果点云是疏散的,分布很广泛,且没什么规律(如lidar测得的点云或双目视觉捕捉的点云)kdTree能更好的划分,而octree则很难决定最小立方体应该是多少。太大则一个立方体里可能有很多点云,太小则可能立方体之间连不起来。如果点云分布非常规整,是某个特定物体的点云模型,则应该使用ocTree,因为很容易求解凸包并且点与点之间相对距离无需再次比对父节点和子节点,更加明晰。典型的例子是斯坦福的兔子。

    欧几里得与区域生长算法

      基于欧式距离的分割和基于区域生长的分割本质上都是用区分邻里关系远近来完成的。由于点云数据提供了更高维度的数据,故有很多信息可以提取获得。欧几里得算法使用邻居之间距离作为判定标准,而区域生长算法则利用了法线,曲率,颜色等信息来判断点云是否应该聚成一类。

    2.1.欧几里得算法

      从前有一个脑筋急转弯,说一个锅里有两粒豆子,如果不用手,要怎么把它们分开。当时的答案是豆子本来就是分开的,又没黏在一起,怎么不叫分开。OK,实际上欧几里德算法就是这个意思。两团点云就像是两粒豆子,只要找到某个合适的度量方式,就有办法把点云和点云分开。

         如果两团点云之间最近两点的距离小于单个点云内部点之间的距离,则可以由算法判断其分为两类。假设总点云集合为A,聚类所得点云团为Q

      具体的实现方法大致是:

    1. 找到空间中某点p10,用kdTree找到离他最近的n个点,判断这n个点到p的距离。将距离小于阈值r的点p12,p13,p14....放在类Q里
    2. 在 Q里找到一点p12,重复1
    3. 在 Q里找到一点p13,重复1,找到p22,p23,p24....全部放进Q里.
    4. 当 Q 再也不能有新点加入了,则完成搜索了

      听起来好像这个算法并没什么用,因为点云总是连成片的,很少有什么东西会浮在空中让你来分。但是如果和前面介绍的内容联系起来就会发现这个算法威力巨大了。比如:

    1. 半径滤波删除离群点
    2. 采样一致找到桌面,抽掉桌面

    显然,一旦桌面被抽,桌上的物体就自然成了一个个的浮空点云团。就能够直接用欧几里德算法进行分割了。如图所示。

    区域生长算法

    1、基于法线和曲率

      区域生长算法直观感觉上和欧几里德算法相差不大,都是从一个点出发,最终占领整个被分割区域。欧几里德算法是通过距离远近,来判断烧到哪儿。区域生长算法则不然,烧到哪儿靠燃料(点)的性质是否类似来决定。对于普通点云,其可由法线、曲率估计算法获得其法线和曲率值。通过法线和曲率来判断某点是否属于该类。其算法可以总结为:

    1. 种子周围的点和种子相比
    2. 法线方向是否足够相近
    3. 曲率是否足够小
    4. 如果满足1,2,则该点可用做种子
    5. 如果只满足1,则归类而不做种
    6. 从某个种子出发,直到其“子种子”不再出现,则一类聚集完成
    7. 类的规模既不能太大也不能太小

    显然,上述算法是针对小曲率变化面设计的。尤其适合对连续阶梯平面进行分割:比如SLAM算法所获得的建筑走廊。

    2、基于颜色:

          除了普通点云之外,还有一种特殊的点云,成为RGB点云。显而易见,这种点云除了结构信息之外,还存在颜色信息。颜色信息可以很好的将复杂场景中的特殊物体分割出来。而颜色点云也并不那么遥不可及,Xbox Kinect就可以轻松的捕捉颜色点云。

          基于颜色的区域生长分割原理上和基于曲率,法线的分割方法是一致的。只不过比较目标换成了颜色,去掉了点云规模上限的限制。可以认为,同一个颜色且挨得近,是一类的可能性很大,不需要上限来限制。所以这种方式比较适合用于室内场景分割。尤其是复杂室内场景,颜色分割可以轻松的将连续的场景点云变成不同的物体。哪怕是高低不平的地面,没法用采样一致分割器抽掉,颜色分割算法同样能完成分割任务。

    3.基于点云频率的分割(滤波)方法

    点云的频率

      点云和图像一样,有可能也存在频率的概念。点云表达的是三维空间中的一种信息,这种信息本身并没有一一对应的函数值。故点云本身并没有在讲诉一种变化的信号。点云虽然没有明确的时间关系,但应该会存在某种空间关系(例如LiDar点云)。我们可以人为的指定点云空间中的一个点(例如Scan的重心或LiDar的“源”),基于此点来讨论点云在各个方向上所谓的频率。

      在传统的信号处理中,高频信号一般指信号变化快,低频信号一般指信号变化缓慢。在图像处理中,高低频的概念被引申至不同方向上图像灰度的变化,在点云处理中,定义点云法线向量差为点云所表达的信号。换言之,如果某处点云曲率大,则点云表达的是一个变化的信号。如果点云曲率小,则其表达的是一个不变的信号。这和我们的直观感受也是相近的,地面曲率小,它表达的信息量也小;人的五官部分曲率大,表达更大的信息量。

    DoN算法

      使用频率信息的思想已经被广泛的应用在了各个方面,最著名的莫过于DoN算法。DoN算法被作者归类于点云分割算法中,但本质上DoN只是一种前处理,应该算是一种比较先进的点云滤波算法。分割本质上还是由欧式分割算法完成的。DoN 是 Difference of Normal 的简写。算法的目的是在去除点云低频滤波,低频信息(例如建筑物墙面,地面)往往会对分割产生干扰,高频信息(例如建筑物窗框,路面障碍锥)往往尺度上很小,直接采用 基于临近信息 的滤波器会将此类信息合并至墙面或路面中。所以DoN算法利用了多尺度空间的思想,算法如下:

    1. 在小尺度上计算点云法线1
    2. 在大尺度上计算点云法线2
    3. 法线1-法线2
    4. 滤去3中值较小的点
    5. 欧式分割

                                                                

      显然,在小尺度上是可以对高频信息进行检测的,此算法可以很好的小尺度高频信息。其在大规模点云中优势尤其明显。算法运行过程可用图表示为:

     

    from:http://www.pointclouds.org/documentation/tutorials/don_segmentation.php

    4、最小割算法

    点云分割的精度

       基于采样一致的点云分割算法显然是意识流的,它只能割出大概的点云(可能是杯子的一部分,但杯把儿肯定没分割出来)。基于欧式算法的点云分割面对有连接的点云就无力了(比如风筝和人,在不用三维形态学去掉中间的线之前,是无法分割风筝和人的)。基于法线等信息的区域生长算法则对平面更有效,没法靠它来分割桌上的碗和杯子。

        我们还需要一个方法来解决分割的“好不好”这个问题。也就是说,有没有哪种方法,可以在一个点不多,一个点不少的情况下,把目标和“其他”分开。

      最小割(min-cut)早就用在网络规划,求解桥问题,图像分割等领域,被移植到点云分割上也不足为奇。最小割算法是图论中的一个概念,其作用是以某种方式,将两个点分开,当然这两个点中间可能是通过无数的点再相连的。如图所示。

                                                                 

      如果要分开最左边的点和最右边的点,红绿两种割法都是可行的,但是红线跨过了三条线,绿线只跨过了两条。单从跨线数量上来论可以得出绿线这种切割方法更优的结论。但假设线上有不同的权值,那么最优切割则和权值有关了。它到底是怎么找到那条绿线的暂且不论。总而言之,就是有那么一个算法,当你给出了点之间的 “图” (广义的),以及连线的权值时,最小割算法就能按照你的要求把图分开。

    点云 “图”

      切割有两个非常重要的因素,第一个是获得点与点之间的拓扑关系,也就是生成一张“图”。第二个是给图中的连线赋予合适的权值。点云有天然分开的点,是一种非常适合分割的对象。有了点之后,只要把点云中所有的点连起来就可以了。连接算法如下:

    1. 找到每个点最近的n个点
    2. 将这n个点和父点连接
    3. 找到距离最小的两个块(A块中某点与B块中某点距离最小),并连接
    4. 重复3,直至只剩一个块

      现在已经有了“图”,只要给图附上合适的权值,就完成了所有任务。物体分割给人一个直观印象就是属于该物体的点,应该相互之间不会太远。也就是说,可以用点与点之间的欧式距离来构造权值。所有线的权值可映射为线长的函数。

                                                                 smoothCost=e^{-(\frac{dist}{ \sigma })^2}

     分割总是有一个目标的——目标需要人为指定(center),尺寸需要提前给出(radius)。

      我们指定了目标物体上的一个点,接下来要做的,就是让除此对象之外的物体被保护起来,保护的方法就是认为加重目标范围之外的权值(罚函数)

                              backgroundPenalty=(\frac{distanceToCenter}{radius})

    5、超体聚类分割方法

      超体(supervoxel)是一种集合,集合的元素是“体”。与体素滤波器中的体类似,其本质是一个个的小方块。与之前提到的所有分割手段不同,超体聚类的实质是对点云实施过分割(over segmentation),将场景点云化成很多小块,并研究每个小块之间的关系。将更小单元合并的分割思路。本质上这种方法是对局部的一种总结,纹理,材质,颜色类似的部分会被自动的分割成一块,有利于后续识别工作。比如对人的识别,如果能将头发,面部,四肢,躯干分开,则能更好的对各种姿态,性别的人进行识别。

     点云和图像不一样,其不存在像素邻接关系。所以,超体聚类之前,必须以八叉树对点云进行划分,获得不同点团之间的邻接关系。与图像相似点云的邻接关系也有很多,如面邻接,线邻接,点邻接。其具体解释如下图:

                          

      基于超体聚类的点云分割,使用点邻接(蓝色)作为相邻判据。

    超体聚类的实现步骤

        超体聚类实际上是一种特殊的区域生长算法,和无限制的生长不同,超体聚类首先需要规律的布置区域生长“晶核”。晶核在空间中实际上是均匀分布的,并指定晶核距离(Rseed)。再指定粒子距离(Rvoxel)。再指定最小晶粒(MOV),过小的晶粒需要融入最近的大晶粒。关系如图所示:

                                              

      有了晶粒和结晶范围之后,我们只需要控制结晶过程,就能将整个空间划分开了。结晶过程的本质就是不断吸纳类似的粒子(八分空间)。类似是一个比较模糊的概念,关于类似的定义有以下公式:

                                                   

       公式中的D_c表示颜色上的差异,D_n表示法线上的差异,D_s代表点距离上的差异。w_*表示一系列权重。用于控制结晶形状。在晶核周围寻找一圈,D最小的体素被认为是下一个“被发展的党员”。需要注意的是,结晶过程并不是长完一个晶核再长下一个,二是所有的晶核同时开始生长(虽然计算机计算时必然有先后,但从层次上来说是同时的)。其生长顺序如下图所示:

     

      接下来所有晶核继续公平竞争,发展第二个“党员”,以此循环,最终所有晶体应该几乎同时完成生长。整个点云也被晶格所分割开来。并且保证了一个晶包里的粒子都是类似的。

    6、基于凹凸型的分割

    对于二维图像而言,其凹凸性较难描述,但对于三维图像而言,凹凸几乎是与生俱来的性质。

    6.1、LCCP方法 

      LCCP是Locally Convex Connected Patches的缩写,翻译成中文叫做 ”局部凸连接“, LCCP方法并不依赖于点云颜色,所以只使用空间信息和法线信息。算法大致可以分成两个部分:

    1. 基于超体聚类的过分割。
    2. 在超体聚类的基础上再聚类。

    算法理论

      点云完成超体聚类之后,对于过分割的点云需要计算不同的块之间凹凸关系。凹凸关系通过 CC(Extended Convexity Criterion) 和 SC (Sanity criterion)判据来进行判断。其中 CC 利用相邻两片中心连线向量与法向量夹角来判断两片是凹是凸。显然,如果图中a1>a2则为凹,反之则为凸。

                                                   

      考虑到测量噪声等因素,需要在实际使用过程中引入门限值(a1需要比a2大出一定量)来滤出较小的凹凸误判。此外,为去除一些小噪声引起的误判,还需要引入“第三方验证”,如果某块和相邻两块都相交,则其凹凸关系必相同。CC 判据最终如CC_e

                                         

                                                       
       如果相邻两面中,有一个面是单独的,cc判据是无法将其分开的。举个简单的例子,两本厚度不同的书并排放置,视觉算法应该将两本书分割开。如果是台阶,则视觉算法应该将台阶作为一个整体。本质上就是因为厚度不同的书存在surface-singularities。为此需要引入SC判据,来对此进行区分。

                                                 

      如图所示,相邻两面是否真正联通,是否存在单独面,与θ角有关,θ角越大,则两面真的形成凸关系的可能性就越大。据此,可以设计SC判据:

      其中S(向量)为两平面法向量的叉积。最终,两相邻面之间凸边判据为:

      
       在标记完各个小区域的凹凸关系后,则采用区域增长算法将小区域聚类成较大的物体。此区域增长算法受到小区域凹凸性限制,既:只允许区域跨越凸边增长。

    6.2、CPC

      CPC方法的全称为Constrained Planar Cuts,和LCCP方法不同,此方法的分割对象是object。此方法能够将物体分成有意义的块:比如人的肢体等。

      本方法也需要先进行超体聚类。在完成超体聚类之后,采用和LCCP相同的凹凸性判据获得各个块之间的凹凸关系。在获得凹凸性之后,CPC方法所采取的措施是不同的。其操作称为半全局分割 。

      在分割之前,首先需要生成 EEC(Euclidean edge cloud), EEC的想法比较神奇,因为凹凸性定义在相邻两个”片“上,换言之,定义在连接相邻两“片”的edge上。将每个edge抽象成一个点云,则得到了附带凹凸信息的点云。如图所示,左图是普通点云,但附带了邻接和凹凸信息。右边是EEC,对凹边赋权值1,其他为0。此方法称作  weighted RanSac

                                            

     显而易见,某处如果蓝色的点多,那么就越,就越应该切开(所谓切开实际上是用平面划分)。问题就转化为利用蓝点求平面了。利用点云求一个最可能的平面当然需要请出我们的ransac但此处引入一个评价函数,用于评价此次分割的优良程度S_m,Pm 是EEC中的点.

                                                
     单纯的weighted RanSac算法并不够。其会导致对某些图形的错误分割,所以作者对此做了第一次“修补".错误的分割如下图所示

      此修补方法称作 directional weighted RanSac方法的原理很简单,垂直于凹边表面的点具有更高的权重,显然,对于EEC中的凹点,只要取其少量邻点即可估计垂直方向。这种修补后还有一个问题,如果这个分割面过长的情况下,有可能会误伤。如图所示:

      于是有了第二种修补方法,称为:Locally constrained cutting这种修补方法的原理就更加简单粗暴了,对凹点先进行欧式分割(限制增长上限),之后再分割所得的子域里进行分割。

    展开全文
  • 今天小编就为大家分享一篇java字符串常用操作方法(查找、截取、分割),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • Halcon-常用阈值分割方法总结

    千次阅读 2021-06-24 13:48:55
    本文主要阐述halcon中较为常见的几种分割算子 引言 halcon中分割算子: (1)全局阈值分割: threshold(Image : Region : MinGray, MaxGray : ) 该算子适用于环境稳定,光照变化不大,目标与背景存在明显的灰度差的...

    本文主要阐述halcon中较为常见的几种分割算子

    引言

    halcon中分割算子:
    (1)全局阈值分割:
    threshold(Image : Region : MinGray, MaxGray : )
    该算子适用于环境稳定,光照变化不大,目标与背景存在明显的灰度差的场合,根据灰度直方图确定阈值进行图像分割。

    read_image (Image, 'clip')
    gray_histo (Image, Image, AbsoluteHisto, RelativeHisto)
    gen_region_histo (Region, AbsoluteHisto, 255, 255, 1)
    *利用直方图获取阈值
    histo_to_thresh (AbsoluteHisto,10, MinThresh, MaxThresh)
    *全局阈值分割
    threshold (Image, Region1, MinThresh, MaxThresh)
    

    (2)自动全局阈值分割
    binary_threshold(Image : Region : Method, LightDark : UsedThreshold)
    该算子提供两种方法“max_separability”和“smooth_histo”。
    最大限度的可分性(max_separability):根据“灰度直方图的阈值选择方法”的灰度直方图自动阈值调用。该算子首先计算图像的直方图,然后利用统计矩找到将像素分割为前景和背景的最优阈值,并最大化这两个类之间的可分性。此方法仅适用于byte和uint2图像。
    直方图平滑(smooth_histo):首先确定灰度值的相对直方图。然后,从直方图提取相关的最小值,作为阈值操作的参数。为了减少最小值,直方图被平滑处理为一个高斯函数,就像在auto_threshold中一样。在平滑直方图中,掩模尺寸增大,直到得到2个波峰的最小值。然后,阈值设置为这个最小值的位置。

    read_image (Image, 'clip')
    binary_threshold (Image, Region, 'max_separability', 'dark', UsedThreshold)
    

    (3)动态局部阈值分割
    dyn_threshold(OrigImage, ThresholdImage : RegionDynThresh : Offset, LightDark : )
    (4)均值和标准偏差局部阈值分割
    var_threshold(Image : Region : MaskWidth, MaskHeight, StdDevScale, AbsThreshold, LightDark : )
    参数:
    MaskWidth、 MaskHeight是用于滤波平滑的掩膜尺寸;
    StdDevScale是标准差乘数因子(简称标准差因子);
    AbsThreshold是设定的绝对阈值;
    LightDark有4个值可选,’light’、’dark’、’equal’、’not_equal’。
    需要强调的是var_threshold算子和dyn_threshold算子极为类似。不同的是var_threshold集成度更高, 并且加入了“标准差×标准差因子”这一变量。可以有效地减少噪声对分割的影响。
    (5)自动全局阈值分割
    auto_threshold(Image : Regions : Sigma : )
    运行原理:
    1.计算灰度直方图。
    2.高斯平滑后从直方图提取最小值。
    3.根据提取的最小值进行阈值分割,sigma越大提取区域越少。

    read_image (Image, 'fabrik')
    median_image (Image, Median, 'circle', 3, 'mirrored')
    auto_threshold (Median, Regions, 3)
    

    (6)快速全局阈值分割
    fast_threshold(Image : Region : MinGray, MaxGray, MinSize : )
    灰度值满足Gamma公式展示MinGray<=g<=MaxGray聚合为一个区域,为了节省时间按两步执行。
    1.先处理行列间隔Minsize的所有像素点。
    2.处理上一步选择点的领域。和threshold相比分割速度快。
    (7)分水岭阈值分割
    watersheds_threshold(Image : Basins : Threshold : )

    算子分割实例

    测试图片:硅片分选机隐裂站成像


    图1.1 隐裂站运行时硅片成像灰度均值为110±10
    在这里插入图片描述
    图1.2 硅片较厚时会出现成像较黑
    在这里插入图片描述
    图1.3 硅片较薄时成像较亮

    (1)使用全局阈值三种样片测试效果
    在这里插入图片描述
    正常片分割效果:硅片全覆盖
    在这里插入图片描述
    厚片分割效果:有多余背景和中间空隙

    在这里插入图片描述
    薄片分割效果:硅片全覆盖

    测试代码:

    全局阈值分割threshold (GrayImage, Region, 40, 255)

    dev_update_off ()
    dev_close_window ()
    * Image Acquisition 01: Code generated by Image Acquisition 01
    ImageFiles := []
    ImageFiles[0] := 'C:/Users/yangguowei/Desktop/片子/薄片.png'
    ImageFiles[1] := 'C:/Users/yangguowei/Desktop/片子/厚片.png'
    ImageFiles[2] := 'C:/Users/yangguowei/Desktop/片子/正常片.png'
    for Index := 0 to |ImageFiles| - 1 by 1
        read_image (Image, ImageFiles[Index])
        get_image_size (Image, Width, Height)
        *打开窗口用于显示三种类型图片分割效果展示
        dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
        * Image Acquisition 01: Do something
        rgb1_to_gray (Image, GrayImage)
        threshold (GrayImage, Region, 40, 255)
        dev_set_window (WindowHandle)
        dev_set_draw ('fill')
        dev_set_color ('red')
        dev_display (Image)
        dev_display (Region)
    endfor
    

    在这里插入图片描述

    展开全文
  • 主要介绍了js数组常用操作方法,结合实例总结了javascript数组的增加、删除、合并、分割等操作技巧,需要的朋友可以参考下
  • 遥感影像分割方法研究,孔令然,曾繁慧,图像分割是数字图像处理中的一项关键技术,它使得其后的图像分析,识别等高级处理阶段所要处理的数据量大大减少,同时又保留有关
  • matlab开发-使用常用方法进行图像分割。它是一种基于聚类的图像阈值。
  • 数字医疗图像与普通图像相比本质上具有模糊性和不均匀的特点 ,使得其特征及边缘提取...依据数字口腔牙 X线根尖片 ,对常用数字医疗图像特征分割方法进行实验、分析、比较 ,并给出总结 ,从而为进一步处理和分析奠定基础。
  • 法进行了综述,阐述了基于阈值、基于聚类、基于区域以及基于特定理论的几类分割方法各自的优缺点和应用场景。 最后根据基于过完备字典的稀疏表示能够刻画图像细节信息、实现图像最优逼近的特点,提出将其推广至彩色...
  • 下面一一介绍一下: 1、最简单最常用方法,以一个指定的字符进行的分割 打开vs.net新建一个控制台项目。然后在Main()方法下输入下面的程序。 代码如下: string s=”abcdeabcdeabcde”; string[] sArray=s.Split(...
  • 提出了一种自适应的细胞图像分割方法。该方法结合生物细胞图像的自身特性,通过多色判定及单通道选择的综合方法选取与之相适应的常用分割算法,实现了具有较强普遍性及鲁棒性的自适应分割。
  • 用于图像分割的方法很多,其中基于K均值的图像分割方法较为常用,本程序附有详细注解
  • 为了解该问题的研究现状、存在问题及发展前景,在广泛调研现有文献和最新成果的基础上,针对2000年之后主流的图像分割方法进行了研究,将之分为四类:基于图论的方法、基于聚类的方法、基于分类的方法以及结合聚类和...
  • 主要介绍了JS截取与分割字符串常用技巧,以实例形式分析你了JavaScript针对字符串的截取与分割常用函数的定义、功能及使用技巧,并补充分析了substr和substring方法的区别,需要的朋友可以参考下
  • numpy常用方法

    2020-12-22 12:58:36
    #常用参数 np.loadtext(frame,delimiter,dtype,skiprows,usecols,unpack) #eg file_path = “” np.loadtext(file_path,delimiter=”,”,dtype=”int”,skiprows=0,usecols=(0,),unpack=ture) 参数 注释 ...
  • 图像处理——常用阈值分割方法及源码

    万次阅读 多人点赞 2018-07-18 20:37:18
    1、Otsu阈值分割 2、自适应阈值分割 3、 最大熵阈值分割法 4、 迭代阈值分割  5、测验   1、Otsu阈值分割  Otsu(大津法或最大类间方差法)使用的是聚类的思想,把图像的灰度数按灰度级分成2个部分,...

    目录

     

    1、Otsu阈值分割

    2、自适应阈值分割

    3、 最大熵阈值分割法

    4、 迭代阈值分割

     5、测验

     

    1、Otsu阈值分割

            Otsu(大津法或最大类间方差法)使用的是聚类的思想,把图像的灰度数按灰度级分成2个部分,使得两个部分之间的灰度值差异最大,每个部分之间的灰度差异最小,通过方差的计算来寻找一个合适的灰度级别来划分。 所以可以在二值化的时候采用otsu算法来自动选取阈值进行二值化。otsu算法被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响。因此,使类间方差最大的分割意味着错分概率最小。

    参考链接:https://www.cnblogs.com/moon1992/p/5092726.html

    opencv调用格式为:threshold(sourceImage, dstImage, 0, 255, CV_THRESH_OTSU);

    sourceImage:输入图像;

    dstImage:输出图像;

    otsu算法的源码如下:

    Mat OtsuAlgThreshold(Mat &image)
    {
    	if (image.channels() != 1)
    	{
    		cout << "Please input Gray-image!" << endl;
    	}
    	int T = 0; //Otsu算法阈值  
    	double varValue = 0; //类间方差中间值保存
    	double w0 = 0; //前景像素点数所占比例  
    	double w1 = 0; //背景像素点数所占比例  
    	double u0 = 0; //前景平均灰度  
    	double u1 = 0; //背景平均灰度  
    	double Histogram[256] = { 0 }; //灰度直方图,下标是灰度值,保存内容是灰度值对应的像素点总数  
    	uchar *data = image.data;
    
    	double totalNum = image.rows*image.cols; //像素总数
    
    	for (int i = 0; i < image.rows; i++)
    	{
    		for (int j = 0; j < image.cols; j++)
    		{
    			if (image.at<uchar>(i, j) != 0) Histogram[data[i*image.step + j]]++;
    		}
    	}
    	int minpos, maxpos;
    	for (int i = 0; i < 255; i++)
    	{
    		if (Histogram[i] != 0)
    		{
    			minpos = i;
    			break;
    		}
    	}
    	for (int i = 255; i > 0; i--)
    	{
    		if (Histogram[i] != 0)
    		{
    			maxpos = i;
    			break;
    		}
    	}
    
    	for (int i = minpos; i <= maxpos; i++)
    	{
    		//每次遍历之前初始化各变量  
    		w1 = 0;       u1 = 0;       w0 = 0;       u0 = 0;
    		//***********背景各分量值计算**************************  
    		for (int j = 0; j <= i; j++) //背景部分各值计算  
    		{
    			w1 += Histogram[j];   //背景部分像素点总数  
    			u1 += j*Histogram[j]; //背景部分像素总灰度和  
    		}
    		if (w1 == 0) //背景部分像素点数为0时退出  
    		{
    			break;
    		}
    		u1 = u1 / w1; //背景像素平均灰度  
    		w1 = w1 / totalNum; // 背景部分像素点数所占比例
    		//***********背景各分量值计算**************************  
    
    	    //***********前景各分量值计算**************************  
    		for (int k = i + 1; k < 255; k++)
    		{
    			w0 += Histogram[k];  //前景部分像素点总数  
    			u0 += k*Histogram[k]; //前景部分像素总灰度和  
    		}
    		if (w0 == 0) //前景部分像素点数为0时退出  
    		{
    			break;
    		}
    		u0 = u0 / w0; //前景像素平均灰度  
    		w0 = w0 / totalNum; // 前景部分像素点数所占比例  
    		//***********前景各分量值计算**************************  
    
    		//***********类间方差计算******************************  
    		double varValueI = w0*w1*(u1 - u0)*(u1 - u0); //当前类间方差计算  
    		if (varValue < varValueI)
    		{
    			varValue = varValueI;
    			T = i;
    		}
    	}
    	Mat dst;
    	threshold(image, dst, T, 255, CV_THRESH_OTSU);
    	return dst;
    }

    2、自适应阈值分割

    这一部分讲解的是opencv自带的adaptiveThreshold()函数,其算法流程:

             二值化算法是用输入像素的值I与一个值C来比较,根据比较结果确定输出值。

            自适应二值化的每一个像素的比较值C都不同,比较值C由这个像素为中心的一个块范围计算在减去差值delta得到。

            其中,C的常用计算方法有两种:

             a、平均值减去差值delta(使用盒过滤boxfilter,性能会非常不错)

             b、高斯分布加权和减去差值delta (使用高斯滤波GaussionBlur)

    adaptiveThreshold()源码如下:

    void myadaptive(InputArray _src, OutputArray _dst, double maxValue,
    	int method, int type, int blockSize, double delta)
    {
    	Mat src = _src.getMat();
    
    	CV_Assert(src.type() == CV_8UC1);
    	CV_Assert(blockSize % 2 == 1 && blockSize > 1);
    	Size size = src.size();
    
    	_dst.create(size, src.type());
    	Mat dst = _dst.getMat();
    
    	if (maxValue < 0)
    	{
    		dst = Scalar(0);
    		return;
    	}
    
    	Mat mean;
    	if (src.data != dst.data)
    		mean = dst;
    	if (method == ADAPTIVE_THRESH_GAUSSIAN_C)
    	{
    		GaussianBlur(src, mean, Size(blockSize, blockSize), 0, 0, BORDER_REPLICATE);
    	}
    	else if (method == ADAPTIVE_THRESH_MEAN_C)
    	{
    		boxFilter(src, mean, src.type(), Size(blockSize, blockSize),
    			Point(-1, -1), true, BORDER_REPLICATE);
    	}
    	else
    	{
    		CV_Error(CV_StsBadFlag, "Unknown/unsupported adaptive threshold method");
    	}
    
    	int i, j;
    	uchar imaxval = saturate_cast<uchar>(maxValue);
    	int idelta = type == THRESH_BINARY ? cvCeil(delta) : cvFloor(delta);
    	uchar tab[768];
    
    	if (type == CV_THRESH_BINARY)
    		for (i = 0; i < 768; i++)
    			tab[i] = (uchar)(i - 255 > -idelta ? imaxval : 0);
    	else if (type == CV_THRESH_BINARY_INV)
    		for (i = 0; i < 768; i++)
    			tab[i] = (uchar)(i - 255 <= -idelta ? imaxval : 0);
    	else
    	{
    		CV_Error(CV_StsBadFlag, "Unknown/unsupported threshold type");
    	}
    
    	if (src.isContinuous() && mean.isContinuous() && dst.isContinuous())
    	{
    		size.width *= size.height;
    		size.height = 1;
    	}
    
    	for (i = 0; i < size.height; i++)
    	{
    		const uchar* sdata = src.data + src.step*i;
    		const uchar* mdata = mean.data + mean.step*i;
    		uchar* ddata = dst.data + dst.step*i;
    
    		for (j = 0; j < size.width; j++)
    			// 将[-255, 255] 映射到[0, 510]然后查表
    			ddata[j] = tab[sdata[j] - mdata[j] + 255];
    	}
    }

    3、 最大熵阈值分割法

    参考链接:https://blog.csdn.net/qq_27668313/article/details/77949596

    https://blog.csdn.net/robin__chou/article/details/53931442

    https://blog.csdn.net/xw20084898/article/details/22760169

    最大熵阈值分割函数源码如下:

    Mat EntropySeg(Mat src)
    {
    	int tbHist[256] = { 0 };
    	int index = 0;
    	double Property = 0.0;
    	double maxEntropy = -1.0;
    	double frontEntropy = 0.0;
    	double backEntropy = 0.0;
    	int TotalPixel = 0;
    	int nCol = src.cols*src.channels();
    	for (int i = 0; i < src.rows; i++)
    	{
    		uchar* pData = src.ptr<uchar>(i);
    		for (int j = 0; j < nCol; j++)
    		{
    			++TotalPixel;
    			tbHist[pData[j]] += 1;
    		}
    	}
    
    	for (int i = 0; i < 256; i++)
    	{
    		double backTotal = 0;
    		for (int j = 0; j < i; j++)
    		{
    			backTotal += tbHist[j];
    		}
    
    		for (int j = 0; j < i; j++)
    		{
    			if (tbHist[j] != 0)
    			{
    				Property = tbHist[j] / backTotal;
    				backEntropy += -Property*logf((float)Property);
    			}
    		}
    
    		for (int k = i; k < 256; k++)
    		{
    			if (tbHist[k] != 0)
    			{
    				Property = tbHist[k] / (TotalPixel - backTotal);
    				frontEntropy += -Property * logf((float)Property);
    			}
    		}
    
    		if (frontEntropy + backEntropy > maxEntropy) 
    		{
    			maxEntropy = frontEntropy + backEntropy;
    			index = i;
    		}
    
    		frontEntropy = 0.0;
    		backEntropy = 0.0;
    	}
    
    	Mat dst;
    	threshold(src, dst, index, 255, 0);
    	return dst;
    }

    4、 迭代阈值分割

    通过迭代方法选择阈值, 计算方法如下:

    (1)选择灰度图的平均值作为初始阈值T0 ;

    (2)计算小于等于T0的平均值T1, 和大于T0的平均值T2;

    (3)新的阈值为T = (T1 + T2)/ 2;

    (4)比较T和T0,若相等,则返回T,即为迭代阈值; 否则 T0 = T,重复(1)-(3)

    迭代阈值分割的源码如下:

    Mat IterationThreshold(Mat src)
    {
    	int width = src.cols;
    	int height = src.rows;
    	int hisData[256] = { 0 };
    	for (int j = 0; j < height; j++)
    	{
    		uchar* data = src.ptr<uchar>(j);
    		for (int i = 0; i < width; i++)
    			hisData[data[i]]++;
    	}
    
    	int T0 = 0;
    	for (int i = 0; i < 256; i++)
    	{
    		T0 += i*hisData[i];
    	}
    	T0 /= width*height;
    
    	int T1 = 0, T2 = 0;
    	int num1 = 0, num2 = 0;
    	int T = 0;
    	while (1)
    	{
    		for (int i = 0; i < T0 + 1; i++)
    		{
    			T1 += i*hisData[i];
    			num1 += hisData[i];
    		}
    		if (num1 == 0)
    			continue;
    		for (int i = T0 + 1; i < 256; i++)
    		{
    			T2 += i*hisData[i];
    			num2 += hisData[i];
    		}
    		if (num2 == 0)
    			continue;
    
    		T = (T1 / num1 + T2 / num2) / 2;
    
    		if (T == T0)
    			break;
    		else
    			T0 = T;
    	}
    
    	Mat dst;
    	threshold(src, dst, T, 255, 0);
    	return dst;
    }

     5、测验

    void main()
    {
    	Mat src = imread("1.jpg");
    	cvtColor(src, src, COLOR_RGB2GRAY);
    
    	Mat bw1, bw2, bw3, bw4;
    	myadaptive(src, bw1, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 15, 10);
    	bw2 = EntropySeg(src);
    	bw3 = OtsuAlgThreshold(src);
    	bw4 = IterationThreshold(src);
    
    	imshow("source", src);
    	imshow("自适应阈值分割", bw1);
    	imshow("最大熵阈值分割", bw2);
    	imshow("Otsu阈值分割", bw3);
    	imshow("迭代阈值分割", bw4);
    	waitKey(0);
    }

    测验结果:

     

     

     

    展开全文
  • 主要介绍了Javascript中String的常用方法,实例分析了String常用的字符转换、截取、分割等技巧,需要的朋友可以参考下
  • C++常用字符串分割方法

    千次阅读 2021-04-10 09:56:53
    一、用strtok函数进行字符串分割 原型: char *strtok(char *str, const char *delim); 功能:分解字符串为一组字符串。 参数说明:str为要分解的字符串,delim为分隔符字符串。 返回值:从str开头开始的一个个被...
  • 本文对近年在图像分割技术上出现的常用图像分割算法以及它们的优缺点进行了综述,并介绍了其在遥感图像中的应用,提出了图像分割算法的前景和面临的挑战。
  • 语义分割(Semantic segmentatio)是计算机视觉中的关键任务之 一。现实中,越来越多的应用场景需要从影像中推理出相关的知识或语义(即由具体到抽象 的过程)。作为计算机视觉的核心问题,语义分割对于场景理解的...
  • 好了看其它方法、最简单最常用方法,以一个指定的字符进行的分割 打开vs.net新建一个控制台项目。然后在Main()方法下输入下面的程序。 代码如下:string s=”abcdeabcdeabcde”; string[] sArray=s.Split(‘c’); ...
  • 常见的图像分割方法有以下几种

    万次阅读 多人点赞 2018-04-19 18:33:08
    常见的图像分割方法有以下几种:1.基于阈值的分割方法 灰度阈值分割法是一种最常用的并行区域技术,它是图像分割中应用数量最多的一类。阈值分割方法实际上是输入图像f到输出图像g的如下变换: 其中,T为阈值;...
  • 外医学图像分割相关文献进行研究总结的基础上,对国内外常用医学图像分割方法的基本理论和特 点进行了较为全面的论述,对各种分割方法的优缺点及其应用效果进行了总结。 [关键词]医学图像;图像分割;综述
  • 常用数字图像分割方法

    千次阅读 2018-11-05 06:52:50
    图像分割是一种重要的图像处理技术。 人们在对图像的认知,理解和应用中,往往仅对其中的某些特定部分感兴趣,这些部分通常被称为目标或前景,它们一般对应图像中特定的,具有独特性质的区域。 这里所说的特定部分...
  • 图像语义分割原理及常用方法

    千次阅读 2020-04-17 11:03:50
    1图像语义分割的概念 1.1图像语义分割的概念与原理 图像语义分割可以说是图像理解的基石性技术,在自动驾驶系统(具体为街景识别与理解)、无人机应用(着陆点判断)以及穿戴式设备应用中举足轻重。我们都知道,...
  • Otsu法是常用的基于阈值的图像分割方法之一,二维Otsu法利用图像的像素灰度值分布及邻域像素的平均灰度分布构成的二维直方图对图像进行阈值分割。由于红外图像具有低对比度、低信噪比、边缘模糊的特点,仅采用二维...
  • 常见的图像分割方法

    千次阅读 2020-06-16 21:20:38
    常见的图像分割方法有以下几种: 1.基于阈值的分割方法 灰度阈值分割法是一种最常用的并行区域技术,它是图像分割中应用数量最多的一类。阈值分割方法实际上是输入图像f到输出图像g的如下变换: 其中,T为阈值;对于...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 258,815
精华内容 103,526
热门标签
关键字:

常用的分割方法有