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

在R语言中为图像蓝色圆形区域添加噪声效果的技术问询

为蓝色圆形区域添加噪声纹理的R语言实现

我现有一段R语言代码,可生成白色背景、带有渐变蓝色圆形及内部白色多边形的图像,希望为蓝色圆形区域添加类似参考图的颗粒状噪声效果(参考图为黑白噪点样式,需在蓝色区域实现该效果)。我推测需要创建随机噪声矩阵并进行图层叠加,但不清楚具体实现方式,现有代码如下:

library(plotrix)
library(grDevices)
library(doParallel)
library(foreach)

# Function to add noise to the circle
shape_noise <- function(x, y, radius, noise_level = 0.025) {
  angles <- seq(0, 2 * pi, length.out = 100)
  radii <- radius + rnorm(100, mean = 0, sd = noise_level)
  x_noise <- x + radii * cos(angles)
  y_noise <- y + radii * sin(angles)
  list(x = x_noise, y = y_noise)
}

# Function to generate noise texture
generate_noise <- function(width, height) {
  matrix(runif(width * height), nrow = width, ncol = height)
}

# Set the number of cores for parallel processing
num.cores <- detectCores() - 1
registerDoParallel(cores = num.cores)

num.sample <- 10 # Number of images to generate
min_plaque.count <- 5
max_plaque.count <- 20

circle_results <- foreach(i = 1:num.sample, .packages = c("plotrix", "grDevices")) %dopar% {
  num.spots <- sample(min_plaque.count:max_plaque.count, 1)
  file_name <- paste0("./data_raw/image_id_", i, "_", num.spots, ".png")
  mask_file_name <- paste0("./data_mask/image_id_", i, "_", num.spots, "_mask.png")
  
  area <- c()
  circumference <- c()
  polygons <- list()
  
  # Generate the raw image
  png(file_name, width = 1024, height = 1024, res = 200, type = "cairo-png")
  par(mar = c(0, 0, 0, 0))  # Remove margins
  plot(0:10, 0:10, type = "n", asp = 1, xlab = "", ylab = "", xaxt = 'n', yaxt = 'n', bty = 'n')
  
  blue_start <- rgb(0, 0, runif(1, 0.4, 1))
  blue_end <- rgb(0, 0, runif(1, 0.4, 1))
  gradient_col <- colorRampPalette(c(blue_start, blue_end))(100)
  
  # Add noise to the circle
  circle_noise <- shape_noise(5, 5, 5)
  polygon(circle_noise$x, circle_noise$y, col = gradient_col, border = NA)
  
  # Generate and overlay noise texture
  noise_texture <- generate_noise(1024, 1024)
  noise_texture_scaled <- (noise_texture - min(noise_texture)) / (max(noise_texture) - min(noise_texture))
  noise_col <- rgb(0, 0, 1, alpha = noise_texture_scaled)
  
  for (k in 1:length(circle_noise$x)) {
    polygon(circle_noise$x, circle_noise$y, col = noise_col[k], border = NA)
  }
  
  num_faded <- sample(num.spots, 1)  # Number of spots to have fading effect, randomly chosen
  fade_indices <- sample(num.spots, num_faded)  # Randomly choose which spots will fade
  
  for (k in 1:num.spots) {
    plot <- 0
    while (plot == 0) {
      x <- runif(1, 0, 10)
      y <- runif(1, 0, 10)
      d <- runif(1, 0.1, 0.3)  # diameter of the spot
      if ((x + d - 5)^2 + (y + d - 5)^2 < 4.5^2) {  # Check if inside the larger circle
        plot <- 1
      }
    }
    # Create random vertices for irregular shape
    vertices <- 10
    angles <- sort(runif(vertices, 0, 2 * pi))
    radii <- rnorm(vertices, mean = d, sd = 0.03)
    x_vertices <- x + radii * cos(angles)
    y_vertices <- y + radii * sin(angles)
    
    # Applying fading effect conditionally
    if (k %in% fade_indices) {
      distances <- sqrt((x_vertices - x)^2 + (y_vertices - y)^2)
      fade_factors <-  1 - (0.9 * distances / max(distances))  # normalize and invert to fade from center to edge
      col <- rgb(1, 1, 1, fade_factors)  # apply fade based on distance
    } else {
      col <- "white"
    }
    
    polygon(x_vertices, y_vertices, col = col, border = NA)
  }
  
  dev.off()

}

# Stop parallel backend
stopImplicitCluster()

原代码中通过循环绘制多边形叠加噪声的方式无法实现均匀颗粒效果,以下是修改后的解决方案,核心是生成噪声纹理后通过遮罩限制仅在蓝色圆形区域内叠加:

library(plotrix)
library(grDevices)
library(doParallel)
library(foreach)

# 为圆形边缘添加噪声
shape_noise <- function(x, y, radius, noise_level = 0.025) {
  angles <- seq(0, 2 * pi, length.out = 100)
  radii <- radius + rnorm(100, mean = 0, sd = noise_level)
  x_noise <- x + radii * cos(angles)
  y_noise <- y + radii * sin(angles)
  list(x = x_noise, y = y_noise)
}

# 生成噪声纹理,支持均匀噪声或Perlin噪声(需安装noise包)
generate_noise <- function(width, height, noise_type = "uniform", noise_intensity = 0.2) {
  if (noise_type == "uniform") {
    noise <- matrix(runif(width * height), nrow = width, ncol = height)
  } else if (noise_type == "perlin") {
    library(noise)
    noise <- noise::perlin.noise(dim = c(width, height), scale = 20)
    noise <- (noise - min(noise)) / (max(noise) - min(noise))
  }
  # 调整噪声强度,让效果更柔和
  noise <- (noise - 0.5) * noise_intensity + 0.5
  noise
}

# 创建圆形遮罩,仅保留圆形区域内的噪声
create_circle_mask <- function(width, height, center_x, center_y, radius, plot_range = c(0,10)) {
  x_coords <- seq(plot_range[1], plot_range[2], length.out = width)
  y_coords <- seq(plot_range[1], plot_range[2], length.out = height)
  mask <- matrix(FALSE, nrow = width, ncol = height)
  
  for (i in 1:width) {
    for (j in 1:height) {
      distance <- sqrt((x_coords[i] - center_x)^2 + (y_coords[j] - center_y)^2)
      if (distance <= radius) {
        mask[i,j] <- TRUE
      }
    }
  }
  mask
}

# 设置并行核心数
num.cores <- detectCores() - 1
registerDoParallel(cores = num.cores)

num.sample <- 10 # 生成图像数量
min_plaque.count <- 5
max_plaque.count <- 20

circle_results <- foreach(i = 1:num.sample, .packages = c("plotrix", "grDevices")) %dopar% {
  num.spots <- sample(min_plaque.count:max_plaque.count, 1)
  file_name <- paste0("./data_raw/image_id_", i, "_", num.spots, ".png")
  
  # 生成图像
  png(file_name, width = 1024, height = 1024, res = 200, type = "cairo-png")
  par(mar = c(0, 0, 0, 0))  # 移除边距
  plot(0:10, 0:10, type = "n", asp = 1, xlab = "", ylab = "", xaxt = 'n', yaxt = 'n', bty = 'n')
  
  blue_start <- rgb(0, 0, runif(1, 0.4, 1))
  blue_end <- rgb(0, 0, runif(1, 0.4, 1))
  gradient_col <- colorRampPalette(c(blue_start, blue_end))(100)
  
  # 绘制带边缘噪声的蓝色圆形
  circle_noise <- shape_noise(5, 5, 5)
  polygon(circle_noise$x, circle_noise$y, col = gradient_col, border = NA)
  
  # 生成噪声纹理
  noise_texture <- generate_noise(1024, 1024, noise_type = "uniform", noise_intensity = 0.3)
  # 创建圆形遮罩
  mask <- create_circle_mask(1024, 1024, 5, 5, 5)
  
  # 将噪声转换为蓝色调半透明图层,仅在遮罩区域显示
  noise_rgb <- array(NA, dim = c(1024, 1024, 3))
  noise_rgb[,,1] <- 0  # R通道
  noise_rgb[,,2] <- 0  # G通道
  noise_rgb[,,3] <- noise_texture * 1  # B通道随噪声调整
  # 控制噪声透明度,遮罩外完全透明
  alpha_layer <- matrix(0.2, nrow=1024, ncol=1024)
  alpha_layer[!mask] <- 0
  
  # 叠加噪声到图像
  noise_raster <- as.raster(noise_rgb)
  rasterImage(noise_raster, xleft=0, ybottom=0, xright=10, ytop=10, interpolate = FALSE, alpha = alpha_layer)
  
  # 绘制内部白色多边形
  num_faded <- sample(num.spots, 1)
  fade_indices <- sample(num.spots, num_faded)
  
  for (k in 1:num.spots) {
    plot <- 0
    while (plot == 0) {
      x <- runif(1, 0, 10)
      y <- runif(1, 0, 10)
      d <- runif(1, 0.1, 0.3)
      if ((x - 5)^2 + (y - 5)^2 < (5 - d)^2) {  # 修正内部点判断逻辑
        plot <- 1
      }
    }
    vertices <- 10
    angles <- sort(runif(vertices, 0, 2 * pi))
    radii <- rnorm(vertices, mean = d/2, sd = 0.03)  # 半径改为直径的一半
    x_vertices <- x + radii * cos(angles)
    y_vertices <- y + radii * sin(angles)
    
    if (k %in% fade_indices) {
      distances <- sqrt((x_vertices - x)^2 + (y_vertices - y)^2)
      fade_factors <- 1 - (0.9 * distances / max(distances))
      col <- rgb(1, 1, 1, fade_factors)
    } else {
      col <- "white"
    }
    
    polygon(x_vertices, y_vertices, col = col, border = NA)
  }
  
  dev.off()

}

# 停止并行后端
stopImplicitCluster()

关键修改说明

  • 噪声生成优化:支持均匀噪声和更自然的Perlin噪声,可通过noise_intensity调整噪声强度
  • 圆形遮罩控制:确保噪声仅出现在蓝色圆形区域内,避免污染背景
  • 正确图层叠加:使用rasterImage实现半透明噪声叠加,替代原代码中错误的多边形循环绘制
  • 逻辑修正:调整内部白色多边形的位置判断逻辑,避免超出圆形范围

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:40:55