简体   繁体   中英

storing multiple images (3D arrays) into a 4D array, in R, with for loop

I am trying to get an average of 3 pictures. I made a function to do that, but i have an issue with storing each of the images following some image manipulation. I am getting an error:

Warning messages:
1: In b$b_arr[i] <- m :  number of items to replace is not a multiple of replacement length
2: In b$b_arr[i] <- m :  number of items to replace is not a multiple of replacement length
3: In b$b_arr[i] <- m :  number of items to replace is not a multiple of replacement length

This is the code that I used to do it. I know I can do this manually, but I want to make a function (and learn what is my issue with this for loop).

    library(OpenImageR)
    
    imgs <- c("img1.png", "img2.png", "img3.png")
    b <- data.frame(conc = imgs,
                    b_arr = array(dim = c(length(imgs),831, 651, 3)))
    base_fun <- functienter code hereon(imgs) {
      for (i in 1:length(imgs)) {
        m <- readImage(imgs[i])
        m[ , , 2] = 0
        m[ , , 3] = 0
        m <- cropImage(m, new_width = 250:1080, 
                       new_height = 650:1300, 
                       type = 'user_defined')
        b$b_arr[i] <<- m
      }
      avg_b <<- (b$b_arr[1,,,] +  b$b_arr[2,,,] +  b$b_arr[3,,,])/3
    }
    
    base_fun(img)

Within your code the problem is that b is a data.frame of dimension 3 times 2. This means that the b_arr column is actually three 4 dimensional arrays.

I don't have any images laying around, but something like the code below should work.

library(OpenImageR)

imgs <- c("img1.png", "img2.png", "img3.png")
b <- lapply(imgs, function(x){
  img <- readImage(x)
  cropImage(img, new_width = 250:1080, new_height = 650:1300, type = 'user_defined')
})
# Convert list to array
b_arr <- array(dim = c( length(imgs), 831, 651, 3))
for(i in seq(length(imgs))
  b_arr[,, i] <- b[[i]]
# calculate the mean across the first dimension (why?)
apply(b_arr, 1, mean)

Oliver's answer worked (with small modification), but I figured out how to do it in a function (helps with scalability and readability).

b <- function(imgs) {
  b <<- array(dim = c(length(imgs), w_to-w_from+1, h_to-h_from+1, 3))
  for (i in seq(length(imgs))) {
    m <- readImage(imgs[i])
    m[ , , 2] = 0
    m[ , , 3] = 0
    m <- cropImage(m, new_width = w_from:w_to, 
                   new_height = h_from:h_to, type = 'user_defined')
    b[i,,,] <<- m
  }
  m_avg <<- (b[1,,,] +  b[2,,,] +  b[3,,,])/3
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM