Python Image Processing: Measuring Layer Widths from Electron Micrograph -


i have image electron micrograph depicting dense , rare layers in biological system, shown below.

vdtap.png

the layers in question in middle of image, starting near label "re" , tapering left. to:

1) count total number of dark/dense , light/rare layers

2) measure width of each layer, given black scale bar in bottom right 1 micron long

i've been trying in python. if crop image beforehand contain parts of few layers, such 3 dark , 3 light layers shown here:

test.png

i able count number of layers using code:

import numpy np import matplotlib.pyplot plt scipy import ndimage pil import image  tap = image.open("vdtap.png").convert('l') tap_a = np.array(tap)  tap_g = ndimage.gaussian_filter(tap_a, 1) tap_norm = (tap_g - tap_g.min())/(float(tap_g.max()) - tap_g.min()) tap_norm[tap_norm < 0.5] = 0 tap_norm[tap_norm >= 0.5] = 1  result = 255 - (tap_norm * 255).astype(np.uint8)  tap_labeled, count = ndimage.label(result)  plt.imshow(tap_labeled) plt.show() 

however, i'm not sure how incorporate scale bar , measure widths of these layers have counted. worse, when analyzing entire image include scale bar having trouble distinguishing layers else going on in image.

i appreciate insight in tackling problem. in advance.

edit 1:

i've made bit of progress on problem far. if crop image beforehand contain bit of layers, i've been able use following code @ thicknesses of each layer.

import numpy np import matplotlib.pyplot plt scipy import ndimage pil import image skimage.measure import regionprops  tap = image.open("vdtap.png").convert('l') tap_a = np.array(tap)  tap_g = ndimage.gaussian_filter(tap_a, 1) tap_norm = (tap_g - tap_g.min())/(float(tap_g.max()) - tap_g.min()) tap_norm[tap_norm < 0.5] = 0 tap_norm[tap_norm >= 0.5] = 1  result = 255 - (tap_norm * 255).astype(np.uint8)  tap_labeled, count = ndimage.label(result)  props = regionprops(tap_labeled) ds = np.array([])  in xrange(len(props)):     if i==0:         ds = np.append(ds, props[i].bbox[1] - 0)     else:         ds = np.append(ds, props[i].bbox[1] - props[i-1].bbox[3])      ds = np.append(ds, props[i].bbox[3] - props[i].bbox[1]) 

essentially, discovered python module skimage, can take labeled image array , return 4 coordinates of boundary box each labeled object; 1 , [3] positions give x coordinates of boundary box, difference yields extent of each layer in x-dimension. also, first part of loop (the if-else condition) used light/rare layers precede each dark/dense layer, since dark layers labeled ndimage.label.

unfortunately still not ideal. firstly, not have crop image beforehand, intend repeat procedure many such images. i've considered perhaps (rough) periodicity of layers highlighted using sort of filter, i'm not sure if such filter exists? secondly, code above gives me relative width of each layer - still haven't figured out way incorporate scale bar actual widths.

i don't want party-pooper, think problem harder first thought. can't post working code snippet because there many parts of post require in depth attention. have worked in several bio/med labs , work usual done human tag specific image points , computer calculate distances. being said, 1 should try automate =d.

to you, problem simple, yet tedious job, of getting out ruler , making few hundred measurements. perfect computer right? yes , no. computer has no idea how identify of bands in picture , has told exactly looking for, , tricky.

identifying scale bar

what know scale bars in images. same number of vertical , horizontal pictures, solid black? there 1 bar (what solid line letter r)? suggestion try wavelet transform. imagine 2d analog function

(probably helps draw function) f(x) = 0 if |x| > 1, 1 if |x| <1 && |x| > 0.5 -1 if |x| < 0.5

then when our wavelet f(x, y) convolved on image, output image have high values when finds black scale bar. length set 1 can tuned wavelets , find scale bar too.

finding ridges

i'd solve above problem first because seems easier , sets one. i'd construct wavelet 1 preprocessing step. wavelet i'd try 2d 0-sum box function again, try match 3 (or more) boxes next each other. in addition height , width parameters box, need spacing , tilt angle parameter. don't have close actual value, close enough rest of image blackens out.

measuring ridges

there lots , lots of ways this, let's use our previous step simplicity. take 3 box wavelet answer , should centered @ middle ridge , report box "width" average width of 3 ridges has captured. close enough considering how widths changing!

good hunting!


Comments

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

Python ctypes access violation with const pointer arguments -