DMelt:Image/1 Image Manipulation

From HandWiki
Member


Image manipulation using Java scripting

Viewing an image

Run this code to display an image file:

from jhplot import *
IView("a.png")

This tool is designed for image viewing, without editing option.

Grabbing image data

Images can be manipulated with DataMelt using several ways. Try to open an image using the ImageJ editor as [Tools]->[ImageJ]. Using the ImageJ GUI, open any file. Once opened, you can do verious manipulations.

You can also work with images without GUI. You can use Java API of this package IJ package IJ package. Here is the example how to import the main class:

>>> from ij import IJ
>>> print  dir(IJ)

This prints all methods associated with the class ij.IJ ij.IJ class.

from ij import *
imp = IJ.openImage("http://jwork.org/dmelt/logo.png") # grab an image from URL or a file
imp.show()               # display it in a new window

The following methods can be used to access information on image:

pixels = imp.getProcessor().getPixels() # get array of bytes
width = imp.getWidth()                 # get width (in Nr pixels)
high=imp.getHight()                     # get height 
r = imp.getProcessor().getRoi()   # java.awt.Rectangle of this image

You can also find more information about this image as:

print "number of pixels:", imp.width * imp.height
print "number of slices:", imp.getNSlices()
print "number of channels:", imp.getNChannels()
types = {ImagePlus.COLOR_RGB : "RGB",
         ImagePlus.GRAY8 : "8-bit",
         ImagePlus.GRAY16 : "16-bit",
         ImagePlus.GRAY32 : "32-bit",
         ImagePlus.COLOR_256 : "8-bit color"}

print "image type:", types[imp.type]


Getting pixel arrays and getting the image back

from ij import *
from ij.process import *
imp = IJ.openImage("https://datamelt.org/logo.png")
pix = imp.getProcessor().convertToRGB().getPixels() # RGB version of this image as a ColorProcessor
print pix

The one-dimensional array has the length equal to width time hight, i.e. it is equal to

imp.getWidth()*imp.getHeight()

ColorProcessors return the pixel array as an int[]. The values of the three color components (integer values 0-255) are packed into one int variable. They can be accessed as follows:

red =    (pix[i] & 0xff0000)>>16
green =  (pix[i] & 0x00ff00)>>8
blue  =  (pix[i] & 0x0000ff)

Here red,green,blue have values from 0 - 255. If you know (red,green,blue), then you can generate a new arrays as:

pix[i]= ((red & 0xff)<<16)+((green & 0xff)<<8) + (blue & 0xff)

Let us print (red,green,color) of the current image:

w=imp.getWidth()
h=imp.getHeight()
for  i in range(h):
     offset = i*w
     for  j in range(w):
          c=pixRB[offset+j]
          red =    (c & 0xff0000)>>16
          green =  (c & 0x00ff00)>>8
          blue  =  (c & 0x0000ff)
          print red,green,blue

You can use a useful class jhplot.utils.ColorPixel jhplot.utils.ColorPixel which performs conversions between pixel colors and the usual RGB integer values (0-255).

The image can be created again from the array "pix" as:

img1=ImagePlus("New image", ColorProcessor(imp.width, imp.height, pix))
img1.show()

Similarly, pixels can be extracted using 32-bit float version of this image as a FloatProcessor. In this case the image will be converted to gray color representation using the formula g=(r+g+b)/3 and returns it as a float.

from ij import *
from ij.process import *
imp = IJ.openImage("https://datamelt.org/logo_dmelt.png")
pix = imp.getProcessor().convertToFloat().getPixels() # Graystyle image using 32-bit float representation
img1=ImagePlus("New image from pixels", FloatProcessor(imp.width, imp.height, pix, None))
img1.show()

Analysis and manipulation using Jython scripting will be discussed below.ere we will show how to create a random image using Jython

from ij import *
from ij.process import *
from java.util import Random
imp = IJ.createImage("A Random Image", "8-bit", 200, 200, 1)
Random().nextBytes(imp.getProcessor().getPixels())
imp.show()

This will show a frame 200x200 with an image containing random points. The API of ImageJ (and this is what is used by DataMelt) is very powerful for performing a detailed analysis of images, transformation and manipulation.


Image analysis

As example of the above methods, below we show how to make histograms of image colors, extracting a vector with pixel colors, converting it to 3 arrays for red, green and blue and building histograms using DataMelt API. To speed-up the code, we use jhplot.utils.ColorPixel jhplot.utils.ColorPixel which converts ImageJ pixel colors into the usual 3 integer RGB values (0-255). This class also helps integrate image manipulation methods into the API of dmelt.

from ij import *
from ij.process import *
from jhplot import *
from jhplot.utils import ColorPixel
from java.awt import Color

imp = IJ.openImage("https://datamelt.org/logo.png")
imp.show()
# Returns an RGB version of this image as a ColorProcessor.
pix=imp.getProcessor().convertToRGB().getPixels()

rgb=ColorPixel.getP0I(pix) # get pixels in the usual R,G,B 

c1 = HPlot("Image colors",500,500,1, 3)
c1.setGTitle("Histogram of image colors")
c1.visible()

red = H1D("Red",125, 0, 255)
green = H1D("green",125, 0, 255)
blue = H1D("blue", 125, 0, 255)

red.setFill(1)
red.setColor(Color.red)
red.setFillColor(Color.red)

green.setFill(1)
green.setColor(Color.green)
green.setFillColor(Color.green)

blue.setFill(1)
blue.setColor(Color.blue)
blue.setFillColor(Color.blue)

red.fill(rgb[0])     # fill histograms in one go
green.fill(rgb[1])
blue.fill(rgb[2])

# fill histograms
max=200
c1.cd(1,1)
c1.setRange(0,255,0,max)
c1.draw(red)

c1.cd(1,2)
c1.setRange(0,255,0,max)
c1.draw(green)

c1.cd(1,3)
c1.setRange(0,255,0,max)
c1.draw(blue)

The output shows frequencies of each color in form of histograms (axis range is 0-255).

DMelt example: Analysis of a histogram of image colors (RGB)

One can use many statistical methods to study the image as described in section DMelt:Statistics/1_General_Topics. For example, print all statistical characteristics for each color as:

print rgb[0].getStatString()     # print detailed characteristics for red
print rgb[1].getStatString()     # print detailed characteristics for blue
print rgb[2].getStatString()     # print detailed characteristics for green