I would like to have R detect a given color in a section of an image.
I've been reading about RGB schemes, but I thought there would maybe a package or a way to have R detect a cluster of pixels where, for example, the color yellow takes place.
Is there a solution or am I just trapped in RGB?
Thanks.
Here you go:
install.packages('raster')
library(raster)
#Get some data
duck.jpg<-tempfile()
download.file('http://www.pilgrimshospices.org/wp-content/uploads/Pilgrims-Hospice-Duck.jpg',duck.jpg,mode="wb")
#Plug it into a stack object
duck.raster<-stack(duck.jpg)
names(duck.raster)<-c('r','g','b')
#Look at it
plotRGB(duck.raster)
duck.yellow<-duck.raster
duck.yellow$Yellow_spots<-0
duck.yellow$Yellow_spots[duck.yellow$r<250&duck.yellow$g<250&duck.yellow$b>5]<-1
plot(duck.yellow$Yellow_spots)
So, just a few teachable points here. A digital image is basically a bucket for holding pixel values. So all you need to do to subset a raster (read: digital image), is use some tool to read it into R; decide how you want to subset it; and subset it in the same way you would subset any other data in R.
Another way to think about a raster in R is a stack of same size matrices, with the number of matrices in the stack as the number of bands in the image. In this manner, you can manipulate the data as you would manipulate any other matrix in R.
Related
i'm rather new to image analysis in R and was wondering how i can assess the number of individual plants within a picture such as this one:
I thought of converting the picture to a black/white picture and then using the bwlabel function to count the number of objects within the picture like this:
R<-R(image)
G<-G(image)
B<-B(image)
ExGreen<-2*G-R-B
plot(ExGreen)
ExGreen<-threshold(ExGreen,thr = "auto",approx=FALSE,adjust=1)
plot(ExGreen)
ExGreen<-clean(ExGreen,10)
plot(ExGreen)
labels=bwlabel(ExGreen)
max(labels)
However, I'm running into the issue that my white colored potato plants do not always form 1 contiguous unity.
I was therefore wondering whether there is some option to connect the white pixels which are very close to each other or whether it is possible to draw a circle around every potato plant and then using the bwlabel function...
Or is there any other option to solve my problem.
Thanks in advance!
I was not aware that R has a package imager for image processing that already has a good deal of builtin functions for solving this problem. Thanks for pointing me to it through this interesting question.
Here is my solution (beware that some thresholds are hard coded and thus not scale invariant!):
library(imager)
image <- load.image("plants.png")
R<-R(image); G<-G(image); B<-B(image)
ExGreen<-2*G-R-B
plot(ExGreen)
# blur before thresholding to fill some gaps
ExGreen <- isoblur(ExGreen, 3)
ExGreen <- threshold(ExGreen, thr="auto", approx=FALSE, adjust=1)
plot(ExGreen)
# split into connected component and keep only large CCs
ccs <- split_connected(ExGreen)
largeccs <- purrr::keep(ccs, function(x) {sum(x) > 800})
plot(add(largeccs))
# count CCs
cat(sprintf("Number of large CCs: %i\n", length(largeccs)))
We have an image like this:
Where I have a skull, and the raw counts of how many bones were broken in each area of the skull.
I also have a 3d printer and can make things like this:
Which was made in R using a matrix and the r2stl package.
What I want to do is map the x's and y's of that skull into certain locations of a matrix so that I could add the raw counts to those cells and 3d print that skull in a way where each portion of the skull would be higher based on how many fractures were in that location. Thoughts? It didn't seem like an example where an example dataset would be useful, I apologize if I should have included that.
I have a scanned map from which i would like to extract the data into form of Long Lat and the corresponding value. Can anyone please tell me about how i can extract the data from the map. Is there any packages in R that would enable me to extract data from the scanned map. Unfortunately, i cannot find the person who made this map.
Thanks you very much for your time and help.
Take a look at OCR. I doubt you'll find anything for R, since R is primarily a statistical programming language.
You're better off with something like opencv
Once you find the appropriate OCR package, you will need to identify the x and y positions of your characters which you can then use to classify them as being on the x or y axis of your map.
This is not trivial, but good luck
Try this:
Read in the image file using the raster package
Use the locator() function to click on all the lat-long intersection points.
Use the locator data plus the lat-long data to create a table of lat-long to raster x-y coordinates
Fit a radial (x,y)->(r,theta) transformation to the data. You'll be assuming the projected latitude lines are circular which they seem to be very close to but not exact from some overlaying I tried earlier.
To sample from your image at a lat-long point, invert the transformation.
The next hard problem is trying to get from an image sample to the value of the thing being mapped. Maybe take a 5x5 grid of pixels and average, leaving out any gray pixels. Its even harder than that because some of the colours look like they are made from combining pixels of two different colours to make a new shade. Is this the best image you have?
I'm wondering what top-secret information has been blanked out from the top left corner. If it did say what the projection was that would help enormously.
Note you may be able to do a lot of the process online with mapwarper:
http://mapwarper.net
but I'm not sure if it can handle your map's projection.
I'm searching a data viewer/plotter for some data I've generated.
Facts
First some facts about the data I've generated:
There are several datasets with about 3 million data points each.
Each dataset currently is stored in ascii format.
Every line represents a point and consists of multiple columns.
The first two columns determine the position of the point (i.e. x and y value) whereas the first column is a timestamp and the second is a normalized float between 0 and 1.
The other columns contain additional data which may be used to colorize the plot or filter the data.
An example data point:
2012-08-08T01:02:03.040 0.0165719281 foobar SUCCESS XX:1
Current Approach
Currently I am generating multiple png files (with gnuplot) with different selection criteria like the following ones for each data set:
Display all points in grey.
Display all points in grey, but SUCCESS in red.
Display all points in grey, but SUCCESS in red, XX:-1 in green; if both SUCCESS and XX:-1 match use blue as coloring.
Drawbacks
With the current approach there are some drawbacks I'd like to have addressed:
I can't easily switch on/off some filters or colorings because I have to generate a new png file every time.
I need to use a limited resolution in my image file because the higher the resolution the slower is the viewer. So I can only zoom in to a limited level of detail.
I don't have the raw data available in the png viewer for each point. Ideally I'd like to have the data visible on selection of a point.
Already tested
I've already tested some other approaches:
Gnuplot itself has a viewer but it can't handle that amount of points efficiently - it is too slow and consumes too much memory.
I've had a quick look at KST, but I couldn't find a way to display 2D data and I don't think it will meet my wishes.
Wishes
I'd like to have a viewer which can operate on the raw data, can displays the points quickly if zoomed out, can also zoom in quickly and as well should resolve the aforementioned drawbacks.
Question
So finally, does anybody know of such a viewer or has another suggestion?
If there isn't a viewer some recommendations for programming it myself are welcome, too.
Thanks in advance
Stefan
i have a problem with plotting two Raster Data Sets in R.
I use two different IRS LISS III Scenes (with the same Extent) and what i want is to plot the pixel values of both scenes in one Scatterplot (x= Layer1 and y=Layer2).
My problem is now the handling of the big amount of data. Each Scene has about 80.000.000 pixels due reclassification and other processing i was able to scale down the values to a amount of 12.000.000 in each raster. But when i try to import these values e.g. in a data.frame or load them from an ascii file i always got problems with my memory.
Is it possible two plot such an amount of data, and when yes it would be great if someone could help me, i was trying it for two days now and right now im desperated.
Many thanks,
Stefan
Use the raster package, there's a good chance it will work out of the box since it has good "out-of-memory" handling. If it doesn't work with the ASCII grids, convert them to something more efficient (like an LZW-compressed and tiled GeoTIFF) with GDAL. And if they are still too big resize them, that's all the graphics rendering process will do anyway. (You don't say how you resized originally, or give any details on how you are trying to read them).