如何提取含孔洞的不规则像素图像的边缘索引?
提取不规则带孔洞图像的边缘像素索引
核心思路
边缘像素指的是自身存在(有(x,y,Int)记录),但至少有一个上下左右相邻像素不存在(无对应记录)的像素。孔洞内部的像素因四周均有存在的像素,不会被判定为边缘。
实现步骤(R语言)
- 将原始数据转换为布尔矩阵,标记像素是否存在,便于快速查询相邻像素状态
- 对每个存在的像素,检查其上下左右四个方向的邻居是否在数据集中
- 只要有一个有效邻居不存在,该像素即为边缘像素
代码实现
set.seed(20) test <- expand.grid(1:25, 1:50) test$Int <- rnorm(nrow(test), 7, 1) edge_rows <- which(test$Var1 %in% c(1, 25) | test$Var2 %in% c(1, 50)) rows_to_remove <- sample(edge_rows, 50) test <- test[-rows_to_remove, ] edge_rows <- which(test$Var1 %in% c(2, 24) | test$Var2 %in% c(2, 49)) rows_to_remove <- sample(edge_rows, 25) test <- test[-rows_to_remove, ] test <- test[-sample(nrow(test), 50), ] # 创建布尔矩阵标记像素存在状态 pixel_matrix <- matrix(FALSE, nrow = max(test$Var1), ncol = max(test$Var2)) pixel_matrix[cbind(test$Var1, test$Var2)] <- TRUE # 判断单个像素是否为边缘的函数 is_edge_pixel <- function(x, y, mat) { # 定义上下左右四个相邻位置 neighbor_positions <- list( c(x-1, y), c(x+1, y), c(x, y-1), c(x, y+1) ) # 筛选出在矩阵范围内的有效邻居 valid_neighbors <- Filter(function(pos) { pos[1] >= 1 && pos[1] <= nrow(mat) && pos[2] >= 1 && pos[2] <= ncol(mat) }, neighbor_positions) # 只要有一个有效邻居不存在,即为边缘像素 any(sapply(valid_neighbors, function(pos) !mat[pos[1], pos[2]])) } # 为每个像素标记是否为边缘 test$is_edge <- mapply(is_edge_pixel, test$Var1, test$Var2, MoreArgs = list(mat = pixel_matrix)) # 提取边缘像素在原数据框中的索引 edge_pixel_indices <- which(test$is_edge) # 可视化验证结果 library(ggplot2) ggplot(test) + geom_tile(aes(Var1, Var2, fill = ifelse(is_edge, "边缘像素", "内部像素"))) + scale_fill_manual(values = c("边缘像素" = "red", "内部像素" = "lightgray")) + labs(title = "边缘像素提取结果", fill = "像素类型")
关键说明
- 布尔矩阵
pixel_matrix:将稀疏的坐标数据转换为密集矩阵,大幅提升相邻像素的查询效率 is_edge_pixel函数:仅检查上下左右四个正交方向的邻居(若需包含对角线可自行扩展),同时排除超出图像边界的无效位置edge_pixel_indices:最终得到的边缘像素在原test数据框中的行索引,可直接用于提取对应像素的(x,y,Int)信息
内容的提问来源于stack exchange,提问作者MarinaZav
相关产品推荐
相关产品推荐

