opencv分水岭实践
opencv有一个例子,这个例子是分割相互接触的物体。
得到的结果一定是相互接触的。
除去白点噪声,可以用开操作。如果里面有黑色的孔洞,可以用闭操作去除。上面的意思就是说因为结果是连着的,所以其实物体的边界是不太确定的。
先用开操除去了一些噪点,其实iterations=1或者2结果都一样。这上面前景的获得是通过一个距离变换,然后二值化得到的。用到的函数是distanceTransform。
距离有很多类型的定义。
这个就是模板的大小。也就是在多大的正方形内计算距离。
这里用距离变换只是为了得到硬币比较中心的位置而已,因为这些位置我们可以确定是单个硬币的区域,我觉得腐蚀完全可以完成这个功能,不过可能得多腐蚀几次或者用比较大的探针。
这个距离变换之后二值化的阈值也是随便选的而已,并没有什么太大的讲究,只要得到一个比较小的区域就可以。
这里得到位置区域的意思是,这些区域并不能分辨出来是属于哪一个硬币的或者是背景,所以是unknow。
这个函数可能就是用形态学操作提取出来的连通区域(上面简单说过这种方法)。
背景标签,背景应该就被认为是黑色的部分。可以选择4邻域或者8邻域的算法,并且算法也有很多。
不过这个函数还有一种输入时不需要这个参数的,这个函数输出有retval和lables,等会试验一下都是什么。
但是如果背景被标记为0,那么分水岭算法会把它视作未知区域(前面介绍过),所以我们想要用一个不同的整数来标记它。我们把未知区域标记为0,而不是背景。markers=markers+1就是为了不让背景为1。
然后把unknow区域的都标记为0,在unknow图里面白色的是位置区域,所以是==255。
最后让输出的边界也就是值==-1的都化成红色,代表边界。
下面就来整体试验一下:
一般都是先滤波。滤波之后是这样的。
这个可以不用开运算滤波了。得到的未知区域为。