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

浙公网安备 33010602011771号