Laplacian边缘检测算法

用途:可以用来找Tilemap的一圈边界

 

public static void FindBoundaryCells(string[, ] cells)
{
    Vector3Int[] fourDirs = //格式: cellX, cellY, bitFlag
    {
        new Vector3Int(-1, 0, 1), //left
        new Vector3Int(1, 0, 2), //right
        new Vector3Int(0, -1, 4), //up
        new Vector3Int(0, 1, 8), //down
    };

    // 8邻域Laplacian卷积核(边缘检测)
    int[,] kernel = { { 1, 1, 1 }, { 1, -8, 1 }, { 1, 1, 1 } };
    
    int rows = cells.GetLength(0);
    int cols = cells.GetLength(1);
    
    for (int cellY = 0; cellY < rows; ++cellY)
    {
        for (int cellX = 0; cellX < cols; ++cellX)
        {
            string cellVal = cells[cellY, cellX];
            if ("00" == cellVal) continue;

            int conv = 0;
            for (int subY = -1; subY <= 1; ++subY)
            {
                for (int subX = -1; subX <= 1; ++subX)
                {
                    int tempX = cellX + subX;
                    int tempY = cellY + subY;
                    bool isNonEmpty = tempX >= 0 && tempX < cols && tempY >= 0 && tempY < rows && "00" != cells[tempY, tempX];
                    conv += (isNonEmpty ? 1 : 0) * kernel[subY + 1, subX + 1];
                }
            }

            if (conv != 0) // 卷积结果非零,说明是边界单元格
            {
                int boundaryFlag = 0;
                // 检查四个方向的边界
                foreach (var dir in fourDirs)
                {
                    int tempX = cellX + dir.x;
                    int tempY = cellY + dir.y;
                    bool isEmpty = tempX < 0 || tempX >= cols || tempY < 0 || tempY >= rows || "00" == cells[tempY, tempX];
                    if (isEmpty)
                        boundaryFlag += dir.z;
                }
                if (boundaryFlag > 0)
                    cells[cellY, cellX] = $"{boundaryFlag:00}";
            }
        }
    }
}

 

打印结果

public static void PrintCells(string[,] cells)
{
    var sb = new StringBuilder();
    for (int cellY = 0; cellY < cells.GetLength(0); ++cellY)
    {
        for (int cellX = 0; cellX < cells.GetLength(1); ++cellX)
        {
            string cellVal = cells[cellY, cellX];
            sb.Append(cellVal).Append(" ");
        }
        sb.Append('\n');
    }
    Debug.Log(sb.ToString());
}

测试代码

string[,] cells =
{
    { "00", "00", "AA", "00", "00" },
    { "AA", "AA", "AA", "00", "00" },
    { "AA", "AA", "AA", "AA", "AA" },
    { "AA", "AA", "AA", "AA", "AA" },
    { "AA", "00", "00", "00", "00" },
};
FindBoundaryCells(cells);
PrintCells(cells);

测试结果

00 00 07 00 00
05 04 02 00 00
01 AA AA 04 06
01 08 08 08 10
11 00 00 00 00

 

posted @ 2026-04-25 00:18  yanghui01  阅读(3)  评论(0)    收藏  举报