在R中为图像添加噪声效果

问题描述 投票:0回答:1

以下代码生成一些在白色背景上带有蓝色圆圈的图像,圆圈内有一些白色多边形。圆圈的颜色围绕蓝色变化。我想添加某种噪音,如下图蓝色圆圈内所示。我假设它必须创建一个随机噪声矩阵,然后将该层合并到图像顶部或在蓝色圆圈和白色多边形层之间合并。我不知道如何实现这一目标。

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()

enter image description here

虽然这个参考图像是黑白的,但这正是我在蓝色圆圈中寻找的效果。

enter image description here

r image png
1个回答
0
投票

这是一种不同的方法,但也许您可以利用它来获得您想要的效果。我将噪声层、聚光灯“焦点”层和圆形蒙版组合起来,以获得与参考类似的效果。也许有一种方法可以重新表述这一点,使旋转调整更加直观......

library(tidyverse)
expand_grid(x = seq(0, 1, length.out = 700), y = seq(0, 1, length.out = 500)) |>
  
  mutate(noise = runif(n(), min = 0, max = 1),
         focus = ((x - 0.5)^2 + (y - 0.7)^2)^0.5,
         in_circle = ((x - 0.5)^2 + (y - 0.5)^2)^0.5 < 0.4,
         value = pmin(0.2, pmax(0, (noise - 0.2) * (1-focus)^4 * in_circle))) |>
  ggplot(aes(x, y, fill = value)) +
  geom_raster() +
  scale_fill_gradient2(low = "black", midpoint = 0.2, high = "white") +
  coord_fixed() +
  theme_void()

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.