[CV] 联通状态估计
文章目录
简介
联通状态估计可以通过Two-Pass 算法实现,基于并查集。
假设对于一张图片,背景标记为-1
,前景标记为0
,统计图片中的联通区域。
下面动图可以展示:
算法流程
以8邻域联通为例。
第一次扫描
逐行扫描输入图片。初始化 label = 1
。
对于每个像素位置,若为前景,扫描当前位置正左、左上、正上、右上四个位置的标签。如下表:*
是当前位置,1
是需要统计的八邻域中标签的位置。
1 1 1
1 * 0
0 0 0
- 若邻域中有标签,则
*
处标签为邻域标签的最小值,同时通过并查集,合并邻域中所有标签 - 若邻域中没有标签,则
*
处标签为label
,label
作为新的节点加入并查集,同时更新label += 1
第二次扫描
更新并查集,每个节点都指向其根结点。
逐行扫描标签,对每个标签,都更新为其根结点的标签,同时对标签计数。
代码
程序员面试金典有道题类似,
你有一个用于表示一片土地的整数矩阵 land,该矩阵中每个点的值代表对应地点的海拔高度。若值为 0 则表示水域。由垂直、水平或对角连接的水域为池塘。池塘的大小是指相连接的水域的个数。编写一个方法来计算矩阵中所有池塘的大小,返回值需要从小到大排序。
示例:
输入:
[
[0,2,1,0],
[0,1,0,1],
[1,1,0,1],
[0,1,0,1]
]
输出: [1,2,4]
代码如下
int DX[] = {
0, -1, -1, -1};
int DY[] = {
-1, -1, 0, 1};
class Solution {
public:
vector<int> pondSizes(vector<vector<int>>& land) {
if (land.empty()) return {
};
int row = land.size(), col = land[0].size()