问题
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:
- be careful, the target widths and heights must maintain the aspect ratio of the original image or it wont work
- If you're trying to avoid
EBImage
, to read/write images try the packagejpeg
methodsreadJPEG
andwriteJPEG
回答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