如何从图像裁剪多边形并移至其他区域,用ggplot2绘制结果
图像多边形裁剪移动与ggplot2绘制实现
下面是针对需求的完整实现方案,包含两种处理思路(数据框层面和栅格层面),你可以根据图像大小选择合适的方法:
一、基础数据准备(复用你的代码)
首先完成图像加载与格式转换:
# 加载所需包 library(terra) library(ggplot2) # 下载并读取示例猫图 cat_url <- "https://images.pexels.com/photos/104827/cat-pet-animal-domestic-104827.jpeg?auto=compress&cs=tinysrgb&w=600" download.file(url = cat_url, destfile = "cat.jpeg") cat_path <- list.files(pattern = "cat.jpeg", full.names = TRUE) cat_rast <- rast(cat_path) cat_df <- as.data.frame(cat_rast, xy = TRUE)
二、方法1:数据框层面处理(适合小图像)
这种方法直接操作像素坐标,直观易懂:
1. 获取图像坐标范围
先确定图像的边界,方便定义多边形:
# 获取图像的x/y轴极值 img_ext <- ext(cat_rast) x_min <- xmin(img_ext) x_max <- xmax(img_ext) y_min <- ymin(img_ext) y_max <- ymax(img_ext)
2. 定义多边形并移动像素
这里以左侧梯形和底部不规则多边形为例,你可以根据需求修改顶点坐标:
library(sp) # 用于判断点是否在多边形内 # --- 处理左侧多边形 --- # 定义左侧多边形顶点(按顺时针/逆时针顺序) left_poly <- matrix(c( x_min, y_min, x_min + 150, y_min, x_min + 100, y_max, x_min, y_max ), ncol = 2, byrow = TRUE) # 筛选多边形内的像素 left_pixel_idx <- point.in.polygon(cat_df$x, cat_df$y, left_poly[,1], left_poly[,2]) == 1 # 设置x轴偏移量,将左侧像素移到右侧空白区域 x_offset <- x_max - (x_min + 150) cat_df$x[left_pixel_idx] <- cat_df$x[left_pixel_idx] + x_offset # --- 处理底部多边形 --- # 定义底部多边形顶点 bottom_poly <- matrix(c( x_min, y_min, x_max, y_min, x_max, y_min + 100, x_min, y_min + 150 ), ncol = 2, byrow = TRUE) # 筛选多边形内的像素 bottom_pixel_idx <- point.in.polygon(cat_df$x, cat_df$y, bottom_poly[,1], bottom_poly[,2]) == 1 # 设置y轴偏移量,将底部像素移到上方空白区域 y_offset <- y_max - (y_min + 150) cat_df$y[bottom_pixel_idx] <- cat_df$y[bottom_pixel_idx] + y_offset
3. ggplot2绘制最终图像
绘制完整RGB图像,隐藏冗余元素:
ggplot(cat_df, aes(x, y)) + geom_raster(aes(fill = rgb(cat_1/255, cat_2/255, cat_3/255))) + scale_fill_identity() + # 直接识别RGB颜色值 coord_fixed() + # 保持图像比例 theme_void() # 移除坐标轴、背景等元素
三、方法2:栅格层面处理(适合大图像,效率更高)
直接在terra栅格对象上操作,避免处理海量数据框行,性能更优:
library(terra) # 1. 处理左侧区域 left_poly_vec <- vect(left_poly, type = "polygons") # 转成terra矢量对象 left_rast <- mask(cat_rast, left_poly_vec) # 提取左侧区域栅格 ext(left_rast) <- ext(x_min + x_offset, x_max + x_offset, y_min, y_max) # 修改栅格位置 cat_rast_masked <- mask(cat_rast, left_poly_vec, inverse = TRUE) # 原栅格移除左侧区域 new_cat_rast <- merge(cat_rast_masked, left_rast) # 合并移动后的左侧区域 # 2. 处理底部区域 bottom_poly_vec <- vect(bottom_poly, type = "polygons") bottom_rast <- mask(cat_rast, bottom_poly_vec) ext(bottom_rast) <- ext(x_min, x_max, y_min + y_offset, y_max + y_offset) cat_rast_masked2 <- mask(new_cat_rast, bottom_poly_vec, inverse = TRUE) final_cat_rast <- merge(cat_rast_masked2, bottom_rast) # 3. 转数据框并绘图 final_cat_df <- as.data.frame(final_cat_rast, xy = TRUE) ggplot(final_cat_df, aes(x, y)) + geom_raster(aes(fill = rgb(cat_1/255, cat_2/255, cat_3/255))) + scale_fill_identity() + coord_fixed() + theme_void()
补充说明
- 多边形顶点坐标可以根据实际需求调整,确保顶点按顺时针或逆时针顺序排列,避免判断点在多边形内时出错
- 如果需要处理复杂多边形,推荐使用
sf包的st_point_in_polygon函数,相比sp::point.in.polygon兼容性更好 - 栅格层面的处理方法更适合大分辨率图像,能有效减少内存占用和运算时间
内容的提问来源于stack exchange,提问作者bird
相关产品推荐
相关产品推荐

