现在知道了那些是背景那些是硬币(确定的前景区域)了。那我们就可以创建标签(一个与原图像大小相同,数据类型为 uint8 的数组),并标记其中的区域了。
对我们已经确定分类的区域(无论是前景还是背景)使用不同的正整数标记,对我们不确定的区域(unknown区域)使用 0 标记。
我们可以使用函数 cv2.connectedComponents()来做这件事。它会把对标签进行操作,将背景标记为 0,其他的对象使用从 1 开始的正整数标记(其实这就是我们的种子,水漫时会从这里漫出)。然后将这个标签返回给我们markers。但是,我们知道如果背景标记为 0,那分水岭算法就会把它当成未知区域了。(我们要将未知区域标记为0,所以我们要将背景区域变为其他整数,例如+1)
所以我们想使用不同的整数标记它们。而对不确定的区域(函数cv2.connectedComponents 输出的结果中使用 unknown 定义未知区域)标记为 0。
ret, maker = cv2.connectedComponents(sure_fg) # 对sure_fg中的轮廓从[0,N-1]进行编号,把背景编号为0
# 分水岭算法中,是对未知区域编号为0,而不是背景编号为0,所以对maker进行+1操作,使背景编号为1
maker += 1
# 将unknow区域编号为0, 即unknow图像中白色部分
maker[unknow == 255] = 0