Scaling An R Image

╄→尐↘猪︶ㄣ 提交于 2019-12-23 20:15:07

问题


I'd like to scale an image in R for further analysis rather than for immediate plotting.

EBImage's resize() would be ideal for this if I could use EBImage, but I need to avoid it so I have to find an alternative.

I haven't had any luck searching. I could implement bilinear filtering by hand, but before I do that I'd like to confirm that there aren't any alternatives.


回答1:


Nearest neighbour resizing is the most common and simplest to implement.

Assuming your image is one layer/channel, and thus one matrix:

resizePixels = function(im, w, h) {
  pixels = as.vector(im)
  # initial width/height
  w1 = nrow(im)
  h1 = ncol(im)
  # target width/height
  w2 = w
  h2 = h
  # Create empty vector
  temp = vector('numeric', w2*h2)
  # Compute ratios
  x_ratio = w1/w2
  y_ratio = h1/h2
  # Do resizing
  for (i in 0:(h2-1)) {
    for (j in 0:(w2-1)) {
      px = floor(j*x_ratio)
      py = floor(i*y_ratio)
      temp[(i*w2)+j] = pixels[(py*w1)+px]
    }
  }

  m = matrix(temp, h2, w2)
  return(m)
}

I'll let you figure out how to apply this to a RGB image

Heres a test run for the code above on the red channel of this image:

lena = readImage('~/Desktop/lena.jpg')[,,1]
display(lena)

r = resizePixels(lena, 150, 150)
display(r)

r2 = resizePixels(lena, 50, 50)
display(r2)

Note:

  1. be careful, the target widths and heights must maintain the aspect ratio of the original image or it wont work
  2. If you're trying to avoid EBImage, to read/write images try the package jpeg methods readJPEG and writeJPEG



回答2:


Nearest neighbour scaling (no interpolation) can be implemented quite easily.
While the answer by @by0 is clear, I'd like to offer an alternate implementation. It works on the matrix representation of the image, which I find simpler than indexing into a vector.

resizeImage = function(im, w.out, h.out) {
  # function to resize an image 
  # im = input image, w.out = target width, h.out = target height
  # Bonus: this works with non-square image scaling.

  # initial width/height
  w.in = nrow(im)
  h.in = ncol(im)

  # Create empty matrix
  im.out = matrix(rep(0,w.out*h.out), nrow =w.out, ncol=h.out )

  # Compute ratios -- final number of indices is n.out, spaced over range of 1:n.in
  w_ratio = w.in/w.out
  h_ratio = h.in/h.out

  # Do resizing -- select appropriate indices
  im.out <- im[ floor(w_ratio* 1:w.out), floor(h_ratio* 1:h.out)]

  return(im.out)
}

This works with arbitrary image scalings, not just square. On the other hand, it will only preserve the aspect ratio of the image if w.out/w.in = h.out/h.in.



来源:https://stackoverflow.com/questions/10865489/scaling-an-r-image

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!