You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用R语言导入PGM文件并将其转换为方形TSV文件?

R语言实现PGM文件导入并转换为方形TSV文件

核心逻辑

PGM分ASCII(P2)和二进制(P5)两种格式,需先提取像素数据转为向量,再将向量转换为宽高相等的方形矩阵,最后导出为TSV文件。


方案一:处理ASCII格式PGM(P2)

适用于文本存储像素值的PGM文件,用基础R即可实现:

# 1. 读取并解析PGM文件
pgm_path <- "your_image.pgm"
pgm_lines <- readLines(pgm_path)

# 过滤注释行(以#开头的行)
pgm_lines <- pgm_lines[!grepl("^#", pgm_lines)]

# 提取图像宽高
dimensions <- as.integer(strsplit(pgm_lines[2], "\\s+")[[1]])
img_width <- dimensions[1]
img_height <- dimensions[2]

# 验证是否为方形图像
if (img_width != img_height) {
  stop("该PGM文件不是方形图像,无法转换为方形TSV")
}

# 提取像素值并转为数值向量
pixel_vector <- as.integer(unlist(strsplit(paste(pgm_lines[4:length(pgm_lines)], collapse = " "), "\\s+")))

# 2. 转换为方形矩阵
pgm_matrix <- matrix(pixel_vector, nrow = img_height, ncol = img_width, byrow = TRUE)

# 3. 导出为TSV文件
write.table(pgm_matrix, file = "square_output.tsv", sep = "\t", row.names = FALSE, col.names = FALSE)

方案二:处理二进制格式PGM(P5)

针对二进制存储的PGM文件,需用readBin读取像素数据:

# 1. 读取二进制PGM文件
pgm_path <- "binary_image.pgm"
pgm_con <- file(pgm_path, "rb")

# 读取头信息并过滤注释
pgm_header <- readLines(pgm_con, n = 3)
pgm_header <- pgm_header[!grepl("^#", pgm_header)]

# 提取宽高和最大灰度值
dimensions <- as.integer(strsplit(pgm_header[2], "\\s+")[[1]])
img_width <- dimensions[1]
img_height <- dimensions[2]
max_gray <- as.integer(pgm_header[3])

# 验证方形图像
if (img_width != img_height) {
  close(pgm_con)
  stop("该PGM文件不是方形图像,无法转换为方形TSV")
}

# 读取二进制像素数据(根据最大灰度值判断字节大小)
pixel_vector <- readBin(
  pgm_con, 
  integer(), 
  n = img_width * img_height, 
  size = ifelse(max_gray > 255, 2, 1), 
  endian = "big"
)
close(pgm_con)

# 2. 转换为方形矩阵并导出TSV
pgm_matrix <- matrix(pixel_vector, nrow = img_height, ncol = img_width, byrow = TRUE)
write.table(pgm_matrix, file = "binary_square_output.tsv", sep = "\t", row.names = FALSE, col.names = FALSE)

封装为复用函数

将上述逻辑整合为函数,支持自动识别PGM格式:

pgm_to_square_tsv <- function(input_pgm, output_tsv) {
  # 尝试读取ASCII格式
  tryCatch({
    pgm_lines <- readLines(input_pgm)
    pgm_lines <- pgm_lines[!grepl("^#", pgm_lines)]
    
    if (pgm_lines[1] != "P2") {
      stop("不是ASCII格式PGM,尝试二进制读取")
    }
    
    dimensions <- as.integer(strsplit(pgm_lines[2], "\\s+")[[1]])
    img_width <- dimensions[1]
    img_height <- dimensions[2]
    
    if (img_width != img_height) stop("非方形图像")
    
    pixel_vector <- as.integer(unlist(strsplit(paste(pgm_lines[4:length(pgm_lines)], collapse = " "), "\\s+")))
  }, error = function(e) {
    # 切换为二进制读取
    pgm_con <- file(input_pgm, "rb")
    on.exit(close(pgm_con))
    
    pgm_header <- readLines(pgm_con, n = 3)
    pgm_header <- pgm_header[!grepl("^#", pgm_header)]
    
    if (pgm_header[1] != "P5") stop("不支持的PGM格式(仅支持P2/P5)")
    
    dimensions <- as.integer(strsplit(pgm_header[2], "\\s+")[[1]])
    img_width <<- dimensions[1]
    img_height <<- dimensions[2]
    
    if (img_width != img_height) stop("非方形图像")
    
    max_gray <- as.integer(pgm_header[3])
    pixel_vector <<- readBin(
      pgm_con, 
      integer(), 
      n = img_width * img_height, 
      size = ifelse(max_gray > 255, 2, 1), 
      endian = "big"
    )
  })
  
  # 转换矩阵并导出
  pgm_matrix <- matrix(pixel_vector, nrow = img_height, ncol = img_width, byrow = TRUE)
  write.table(pgm_matrix, file = output_tsv, sep = "\t", row.names = FALSE, col.names = FALSE)
  cat("转换完成,文件已保存至:", output_tsv, "\n")
}

# 使用示例
pgm_to_square_tsv("test_image.pgm", "result.tsv")

内容的提问来源于stack exchange,提问作者Aoife

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:05:22