Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I would like to measure the density of my western blot band by measuring the area under the peak from this plot.

More specifically, my image will have several lanes with a pattern of bands in each lane (see link below). I would like to select an area and then measure the intensity of the bands as scanned from top to bottom.

I would do this for each lane by selecting same area (essentially move my rectangle over to the new lane) and then plot the density vs length of gel (down direction). I would then like to integrate the area under each curve to get a value which can then be compared to the pattern and density (increased or decreased) of the neighboring lane.

Is this possible to do in Mathematica and, if so, how can I do it. I'm very new to Mathematica and any help would greatly be appreciated.

http://i2.wp.com/homemadeprojects.org/wp-content/uploads/2014/02/gel.png


Keywords: line, lines, spectrum, spectral

share|improve this question
2  
Share the code you are working on ? –  Sektor Feb 26 at 8:05

2 Answers 2

Here's my go:

pic = Import["http://www.agrisera.com/dokument/bibliotek/sample_quality1.jpg"];
Framed[pic]

enter image description here

Isolate the picture by deleting rows and columns with mostly white, and reorient for convenience.

pic2 = pic // ImageData // {#, Transpose@#} & // Count[#, {1., 1., 1.}]/Length[#] & /@ # & /@ # & // Flatten[Position[#, n_ /; n < .35]] & /@ # & // {Min@#, Max@#} & /@ # & // ImageTake[pic, Sequence @@ #] & // ImageRotate[#, -Pi/2] & // ImageReflect[#, Left] &

enter image description here

Crop picture by creating a bounding box around black pixels, with minor manual adjustments (+ {-5, -25}), then split the picture into 10 evenly spaced rows. Convert to grayscale to simplify density calculations.

lanes = pic2 // ImageData // Position[#, {0., 0., 0.}, Infinity] & // Transpose // {First@#, Last@#} &@First@# & // ImageTake[ColorNegate@pic2, # + {-5, -25}] & // ImagePartition[ColorConvert[#, "Grayscale"], {1, .1}*ImageDimensions[#]] & // Flatten;

enter image description here

For each lane, take the mean gray level, by column, and plot it. I had trouble interpolating and then integrating, so instead as a lazy option I rasterized each plot and took the ratio of blue (filling) to white (background).

plots = (Mean /@ Transpose[ImageData[#] - .1] &@# // ListPlot[#, Joined -> True, Filling -> Axis, PlotRange -> {Automatic, {0, 1}}] &) & /@ lanes};
scores = Divide @@ Reverse[SortBy[Tally[Flatten[ImageData[Rasterize[#]], 1]], -Last@# &][[;;2, -1]]] & /@ plots // N;
{lanes, plots, scores} // Transpose // Grid

enter image description here

share|improve this answer

This tries to "automatically" detect equal width bands (although they can be unequally spaced):

i = Import["http://www.agrisera.com/dokument/bibliotek/sample_quality1.jpg"]; 
mask = FillingTransform[DeleteSmallComponents[
         Binarize@ImageMultiply[Erosion[i, 3], EntropyFilter[i, 3]], 1000], 1];
u = ImageMultiply[i, mask]; 
v = Quiet[Variance /@ ((Transpose@ImageData@ColorConvert[u, "Grayscale"]) /. 
     0. | 1. -> Sequence[])];
minima = Flatten@Position[v, x_ /; x < .003];
width = Round@N@Mean[Differences@minima /. 1 -> Sequence[]];
centers = Round@N@Mean[minima[[{#, # + 1}]]] & /@ 
                 Flatten@Position[Differences@minima, x_ /; x > 5, Heads -> False];
lims = Round@N@{# - width/2, # + width/2} & /@ centers;
rs = Rectangle[{#[[1]], 1}, {#[[2]], Last@ImageDimensions@i}] & /@ lims
Show[i, Graphics[{Thick, Orange, Line@lines1, Yellow, Opacity[.5], rs}]]

Mathematica graphics

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.