业务场景:
有个二维矩阵 513 * 513 ,取值只有 0 或 1 ,根据值绘图,0 白色 1 黑色。 现在需要把不规则的黑色绘制成矩形,如下图:
代码如下:
func findConnectedRegion(matrix: [[Int]]) -> [[(Int, Int)]] {
var result: [[(Int, Int)]] = []
// var visited: Set<(Int, Int)> = []
var visited: Set<String> = []
let numRows = matrix.count
let numCols = matrix[0].count
for i in 0..<matrix.count {
for j in 0..<matrix[0].count {
let position = (i, j)
let str = String(i)+"-"+String(j)
if matrix[i][j] == 1 && !visited.contains(str) {
var region: [(Int, Int)] = []
dfs(matrix: matrix, rows: numRows,cols: numCols,position: position, visited: visited, region: ®ion)
result.append(region)
}
}
}
return result
}
func dfs(matrix: [[Int]],rows:Int,cols:Int,position: (Int, Int), visited: Set<String>, region: inout [(Int, Int)]) {
// let numRows = matrix.count
// let numCols = matrix[0].count
let numRows = rows
let numCols = cols
let (row, col) = position
self.str = String(position.0)+"-"+String(position.1)
// Check if the current position is within bounds and is part of the region
guard row >= 0, row < numRows, col >= 0, col < numCols, matrix[row][col] == 1, !visited.contains(str) else {
return
}
self.visited.insert(str)
region.append(position)
// Explore neighbors in all four directions
dfs(matrix: matrix,rows: numRows,cols: numCols, position: (row - 1, col), visited: visited, region: ®ion) // Up
dfs(matrix: matrix, rows: numRows,cols: numCols,position: (row + 1, col), visited: visited, region: ®ion) // Down
dfs(matrix: matrix, rows: numRows,cols: numCols,position: (row, col - 1), visited: visited, region: ®ion) // Left
dfs(matrix: matrix, rows: numRows,cols: numCols,position: (row, col + 1), visited: visited, region: ®ion) // Right
}
好几处局部变量改成了属性,但还是不同位置报相同的错:Thread 1: EXC_BAD_ACCESS (code=2, address=0x16b6a7fc0)
完全不知道问题出在哪了,请大佬指点
2
iOCZS 2023-11-14 18:11:14 +08:00
要进行图像分割,确定哪一些点是一个整体的,那么获取最小 x ,最大 x 以及最小 y 和最大 y 就能圈定这个矩形了。
|
3
nagisaushio 2023-11-14 18:16:32 +08:00 via Android
self.visited.insert?
|
4
magic3584 OP |
5
magic3584 OP @nagisaushio #3
本来用的局部变量,但是一直报错,改成全局了以后,别的地方又报错了[笑哭] |
6
bing89757 2023-11-14 19:24:00 +08:00
没接触过,不过我感觉找边界就行了吧 找到后再取每个边界的最大最小值 就可以了
|
7
hefish 2023-11-14 19:27:32 +08:00
我想应该是 先遍历找起点,找到起点之后,找联通,凡是联通的都记录下来,表示是一个形状里面的,联通找完之后,继续遍历,找下一个起点,直到所有点找完。。
|
8
churchill 2023-11-14 19:36:18 +08:00
先找联通区域呀,BFS ,然后每个联通区域算包围盒
|
10
czfy 2023-11-14 20:09:30 +08:00
试试这样?
func findConnectedRegions(matrix: [[Int]]) -> [[[(Int, Int)]]] { var result: [[[(Int, Int)]]] = [] for i in 0..<matrix.count { for j in 0..<matrix[0].count { if matrix[i][j] == 1 { var region: [(Int, Int)] = [] var visited = Set<(Int, Int)>() dfs(matrix: matrix, position: (i, j), visited: &visited, region: ®ion) let bound = getRegionBounds(region) result.append(bound) } } } return result } func dfs(matrix: [[Int]], position: (Int, Int), visited: inout Set<(Int, Int)>, region: inout [(Int, Int)]) { let (row, col) = position guard row >= 0, row < matrix.count, col >= 0, col < matrix[0].count, matrix[row][col] == 1, !visited.contains((row, col)) else { return } visited.insert((row, col)) region.append((row, col)) dfs(matrix: matrix, position: (row-1, col), visited: &visited, region: ®ion) dfs(matrix: matrix, position: (row+1, col), visited: &visited, region: ®ion) // ... } func getRegionBounds(_ region: [(Int, Int)]) -> [(Int, Int)] { // return bounding box } |
11
magic3584 OP |
12
magic3584 OP |
13
magic3584 OP |
14
QingchuanZhang 2023-11-15 11:34:41 +08:00
为什么不 bfs ?
|
15
magic3584 OP |
17
churchill 2023-11-15 13:05:14 +08:00
https://codesandbox.io/s/focused-cloud-zrpxfx
简单试了下,js 写的,将就看吧 |