python - How detect and plot intensity of asc file -
i have photo of flame - data asc file contains matrix of pixels. in each pixel value of light intensity.
my code of plotting:
import os import numpy np import matplotlib.pyplot plt # open file path = "input/" dirs = os.listdir( path ) number_of_files = 0 # print files , directories file in dirs: if file.endswith(".asc"): img = np.genfromtxt (path+file) file = os.path.splitext(file)[0] #pasukamas vaizdas img = img.transpose () # figure , 1 subplot fig, ax = plt.subplots(1,figsize=(20,20)) ax.set_title(file, fontsize=60, y=1.03) plt.imshow (img, interpolation='nearest', origin='lower') plt.colorbar () plt.savefig ('output/' + file + '.png', bbox_inches = 'tight') number_of_files = number_of_files + 1 plt.close(fig) print (number_of_files)
result:
how can plot images in 3 ranges:
- from max intensity 36000 (red zone)
- from max intensity 27000 (yellow zone)
- from max intensity 12000 (blue zone)
and detect bottom , top pixels? left , right pixels? connect top , bottom pixels line. need same thing left , right pixels. how show pixel distance on lines?
result must
you seem want thresholded version of image(s), area labeling on thresholded values, , fancy measures afterwards.
for convenience form 3d ndarray of image sequences , operation can done in 1 go numpy :
filelist = filter(lambda s: s.endswith(".asc"), os.listdir(path)) # open first image have dimensions initialize array firstimage = np.genfromtxt (path+filelist[0]) imagearray = np.zeros((len(filelist),) + firstimage.shape)
now assign values
imagearray[0,:,:] = firstimage i,file in enumerate(filelist[1:]): # skip first item because have imagearray[i+1,:,:] = np.genfromtxt (path+file)
ok, have 3d array of image, let's range images
boolmaskredzone = imagearray > 36000 boolmaskyellowzone = imagearray > 27000 boolmaskyellowzone = imagearray > 12000
these masks of same size images of booleans. let's fiddle :
redparts = image*boolmaskredzone # images 0 thresholded values plt.imshow(redparts[0,:,:],cmap="hot")
notice again redparts , else still in 3d, made 2d view of array plotting purposes.
now easy / fun part : labeling ! can use scipy.ndimage.measurements.label()
from scipy.ndimage import label labelsred, nblabelsred = label(boolmaskredzone)
labelsred array ints label indices.
ideally have nblabelsred == 1, if not, "islands" can closed with
from scipy.ndimage import morphology closedlabels = morphology.binary_closing(labelsred) # fiddle optional iterations parameter if needed
we can compute area of labels = thresholded areas using np.where give positions of pixels, counting number of items :
x,y,z = np.where(labelsred == 1) # x, y ,z arrays area = len(x) # number of pixels brighter red
as computing top/bottommost pixels , can become tricky if want line diagonal one, if want top / bottom (aligned images axes) can make numpy check when masks become true each axis, plainly doing difference (derivation) between array , and offset version, first nonzero element along each axis
differencearray = boolmaskredzone - np.roll(boolmaskredzone,1,axis=1) # check along each column when array first becomes true uselessimageindex,xtopmostpixel,ytopmostpixel= numpy.where(differencearray == true) # found crossings , put them in 2 arrays
for exact diagonal measurement, might want specialized image measurement libraries, scikit-image, have want
if want yourself, recommend approach based on finding object centre, computing diagonal lines position, , measuring max length, happens if find 45 degree line ? become "top-bottom" or "left-right" ? or want longest line close horizontal ? or want bi-orthogonal measurement ? (pick biggest line first measurement, second diameter line whatever length of line 90 degrees first one)
assuming have points in image, plotting line plot plt.plot =)
i have admit didn't think through derivation part much, assumed once you'd have label happy camper =)
edit : of course operations can computed directly iterating on array, posted approach produces one-liners use numpy's array manipulation efficiency stuff. indeed each operation doing
for x in range(image.shape[0]): y in range(image.shape[1]): if(image[x,y] > 36000): mask[x,y]=true
but nesting of loops very slow compared numpy's compiled , hardware-accelerated functions (see http://www.astro.washington.edu/users/vanderplas/astr599/notebooks/11_efficientnumpy demo of speed on python/numpy)
edit 2: project of mine i've been researching more of scipy's ndimage functions, , there's : ndimage.center_of_mass().
this function finds center of mass in (potentially labelled) array. finding center of mass of labelled array, have center of axis find diagonals from, , rest piece of cake ^^
Comments
Post a Comment