9

Can anyone help me on how to get the RGB pixel data from an image in R?

I need this information to compare differences in bird plumage to aid in the understanding of a speciation event.

My photos are taken by a digital camera and are now as a NEF-file. It doesn't matter which type of file that's needed, I have the possibility to convert the file to whatever I want. However, I would prefer to maintain as much information as possible in the file (i. e. PNG-files are good).

I have tried many packages in R: Pixmap, Raster, ImageMetrics and browsed the internet, tested methods, asked co-students etc. for several weeks trying to solve this problem. Here at Stackoverflow I've tried this: How to extract the pixel data Use R's pixmap package?, with no luck. My files are also too big for the R window (the entire array doesn't show), and I have difficulties understanding the array produced. The best thing for me would be to get the data as a matrix or in another way that makes it easier to understand what is what. I have found loads of similar questions, but in other programs (such as Java, C++, IOS, Matlab, Python etc) which I unfortunately don't know how to use.

My problems might be due to my low skills with this type of work, but I am trying as hard as I can with the background that I have. If anyone can help me or give me som tips, I will be very grateful.

Community
  • 1
  • 1
MariaBioStudent
  • 105
  • 1
  • 1
  • 5
  • 3
    What do you mean "no luck"? Kohske gave a very good answer to your [previous question](http://stackoverflow.com/questions/6085090/how-to-extract-the-pixel-data-use-rs-pixmap-package). Be more specific. Have you tried to adapt his solution? Why doesn't it work? – Andrie Feb 08 '13 at 09:51
  • You'll probably be a lot happier using ImageJ (or even GraphicConverter if you've got access to OS X). Meanwhile, assuming the birdfeathers only cover part of the image, extract array subsets to minimize the size of the data you're mucking with. – Carl Witthoft Feb 08 '13 at 12:35
  • @Andrie, I am sorry for not seeing that, as you can see in my edit, I have misunderstood what I was doing. However, if you are interested, I got this error message trying to test bill_080 answer: picture@size "Error: trying to get slot "size" from an object of a basic class ("array") with no slots" – MariaBioStudent Feb 08 '13 at 12:53
  • @CarlWitthoft, yes I've just been looking into that. ImageJ or Bio7 which combine R and ImageJ. Thanks for suggestions! :) – MariaBioStudent Feb 08 '13 at 12:56
  • You should open new questions instead of editing your original one and adding them into it. – juba Feb 08 '13 at 13:00
  • @juba, Thanks for letting me know, I'm new to these forums. I've made another question, http://stackoverflow.com/questions/14773830/how-to-interpret-a-rgb-array-in-r, if anyone is interested. – MariaBioStudent Feb 08 '13 at 13:42

2 Answers2

8

First I generate an example png image :

png("/tmp/test.png")
plot(rnorm(100))
dev.off()

Then I convert it to a format readable by pixmap : here I convert the png to a ppm file as I want to keep colors information. I use ImageMagick from the command line, but you can use whatever program you want :

$ convert /tmp/test.png /tmp/test.ppm

Next, you can read the image with the read.pnm function from the pixmap package :

x <- read.pnm("/tmp/test.ppm")

And then, you can use the x@red, x@blue, x@green slots (or x@grey for a greyscale image) to get the pixels value for each channel as a matrix. You can check that the dimensions of the matrices are the same as the size of your picture :

dim(x@red)
[1] 480 480
juba
  • 47,631
  • 14
  • 113
  • 118
  • If this solved your question, you can check the green mark in order to indicate it to other users. – juba Feb 08 '13 at 12:59
4

Take this tiny sample 3x3 pixel png image:

sample image

Then:

library('png')
download.file('https://i.stack.imgur.com/hakvE.png', 'sample.png')
img <- readPNG('sample.png')
pix.top.left <- img[1,1,]     # row 1, column 1
pix.bottom.left <- img[3,1,]  # row 3, column 1
pix.top.right <- img[1,3,]    # row 1, column 3

If you're reading a PNG image with alpha channel (as the sample image above), then each of the pix. variables is a vector with four entries, each entry corresponding to Red ,Green, Blue and Alpha values of the pixel.

> pix.top.left
[1] 1 0 0 1
Marijn
  • 10,367
  • 5
  • 59
  • 80