文章来源:http://www.itnose.net/detail/6038297.html?更多文章:http://www.itnose.net/type/1.html
ImageJ是世界上?
最快的纯Java的图像处理程序。它可以过滤一个2048x2048的图像在0.1秒内(*)。这是每秒40万像素!ImageJ的扩展通过使用内置的文本编辑器和Java编译器的ImageJ的开发插件。500多插件可用。
数据类型:8位灰度或索引色,16位无符号整数,32位浮点和RGB色彩。
文件格式:读写所有支持的数据类型为TIFF(非压缩)或原始数据。打开和保存GIF,JPEG,BMP,
PNG,PGM,FITS和ASCII。打开DICOM。使用URL打开的TIFF、GIF文件、JPEG文件、DICOMs和原始数据。也可以扩展许多其他格式 的插件。
图像增强:支持平滑,锐化,边缘检测,中值滤波和阈值的8位灰度和RGB彩色图像。交互方式调整亮度和8位,16位和32位图像的对比度。
几何操作:裁剪,缩放,调整大小和旋转。翻转垂直或水平。
分析:测量面积,平均值,标准偏差,最小的选择和最大或整个图像。测量长度和角度。使用现实世界中的度量单位,如毫米。校准使用密度标准。生成
柱状图和剖面图。
色彩处理:分裂一个32位彩色图像转换成RGB或HSV分量。合并8位组件成彩色图像。RGB图像转换为8位索引颜色。应用伪彩色调色板为灰度图像。
?
基于ImageJ的项目有、CellProfiler(细胞图像分析)、idoimaging(医学影像)、ImageSurfer(3D可视化和分析)、MIPAV(3D成像和可视化)、NITRC(神经影像学工具和资源)等。
下面对ImageJ的编程基础介绍一下。
一、ImageJ的图像剖析
ImageJ的 图像由三个部分组成:
1、ImageProcessor对象实例:持有并提供了访问像素的方法。
2、Image对象实例:即java.awt.Image画在屏幕上。
3、ImagePlus对象实例:包括所有的元数据(标题,属性)、ImageProcessor和Image。
ImageJ的 图像
堆栈由四部分组成:
1、ImageStack对象实例:持有像素阵列的阵列(LUT变化通过临时实例StackProcessor)
2、Image对象实例:即java.awt.Image画在屏幕上。
3、ImageProcessor对象实例:提供访问当前切片像素。
4、ImagePlus对象实例:持有ImageStack、ImageProcessor和Image。
?
使用堆栈时,要谨记以下几点:
1、ImagePlus的ImageProcessor实例在任何调用setSlice(INT)时都由它的像素替换对象。
2、ImageStack.getProcessor(int)在每次调用时都返回一个新的ImageProcessor,是?一个消耗大的操作。
3、ImagePlus的java.awt.Image中在每次调用setSlice(int)时被更新。
?
当ImagePlus调用updateAndDraw()时重新创建 java.awt.Image对象。如果你想改变被反映当前显示在屏幕上的图像,必须修改的像素之后调用updateAndDraw()。
?
二、创建图像
? ? 1、创建一个图像(详细)
int?width?=?400; ??
int?height?=?400; ??
ImageProcessor ip?=??
new?ByteProcessor(width, height); ??
String title?=?"My new image"; ??
ImagePlus imp?=??
new?ImagePlus(title, ip); ??
imp.show(); ?
?
? ??有几个ImageProcessor类,每个都有自己专门的
构造函数。ByteProcessor,ShortProcessor,FloatProcessor和ColorProcessor。
? ? 2、创建一个图像(简单方式)
?
? ??? ???
new?ImagePlus("My new image",??
new?ByteProcessor(400,?400)).show();?
?
? ? 3、创建任意数量任何类型的
? ??? ???A、一个简单的8位的400x400像素的灰度图像
ImagePlus imp?=?IJ.createImage("My new image",?"8-bit black",?400,?400,?1);?
imp.show();?
// or, without getting back a reference:?
IJ.newImage("My new image",?"8-bit black",?400,?400,?1);
B、堆栈的400×400像素的10色图片
ImagePlus imp?=?IJ.createImage("My new image",?"RGB white",?400,?400,?10); ??
imp.show(); ??
// again, without getting back a reference: ??
IJ.newImage("My new image",?"RGB white",?400,?400,?10);?
三、销毁图像?
调用flush()将释放所使用的ImagePlus所有
内存资源。
ImagePlus imp?=?... ??
imp.flush(); ?
?
注意:如果你持有一个从ImagePlus.getProcessor()方法获得ImageProcessor。即ImageProcessor的像素
数组指针将被设置为null。你应该改为调用ImageProcessor的duplicate(),或直接通过getPixels()得到它的像素,并把它们存储在相同的尺寸的新ImageProcessor。
?
同样,java.awt.Image中获取自己的flush()方法调用也是如此。
四、打开图像
? ??所有方法都围绕着ij.io.Opener类展开。
? ? 1、高层次的方式,从文件或URL
?
ImagePlus imp?=?IJ.openImage("/path/to/image.tif"); ??
imp.show(); ??
???
ImagePlus imp?=?IJ.openImage("http://www.example.org/path/to/image.tif"); ??
imp.show(); ??
???
// Without getting back a pointer, and automatically showing it: ??
IJ.open("/path/to/image.tif"); ??
// Same but from an URL ??
IJ.open("http://www.example.org/path/to/image.tif");?
?
? ? 2、从文件打开
Opener opener?=??
new?Opener(); ??
ImagePlus imp?=?opener.openImage("/path/to/image.tif"); ??
imp.show(); ?
? ? 3、从URL打开
Opener opener?=??
new?Opener(); ??
ImagePlus imp?=?opener.openImage("http://www.example.org/path/to/image.tif"); ??
imp.show();?
?
以上注意URL 包含http://如何的自动检测并正确
解析。如果需要,可以直接调用:
ImagePlus?imp?=?opener.openURL("http://www.example.org/path/to/image.tif"); ?
?
五、编辑像素?
1、运行ImageJ命令方式,这是一个高层次的方法,像素可以通过调用ImageJ的命令编辑图像:
ImagePlus imp?=?... ??
// Making a binary image ??
IJ.run(imp,?"Convert to Mask",?"");?// "" means no arguments ??
???
// Resizing, opens a copy in a new window (the 'create'
command keyword) ??
IJ.run(imp,?"Scale...",?"x=0.5 y=0.5 width=344 height=345 interpolate create title=[Scaled version of "?+imp.getTitle()?+?"]"); ??
??... ??
任何ImageJ命令可能被应用。你可以找出哪些命令来使用,哪些参数通过运行插件,并手动调用的ImageJ打开的图像上的菜单命令。
2、中级层次编辑方式:ImageProcessor(ROIs/selections)
在图像上绘制或填充ROI(感兴趣区域):
ImagePlus imp?=?... ??
ImageProcessor ip?=?imp.getProcessor(); ??
???
// Assuming 8-bit image ??
???
// fill a rectangular region with 255 (on grayscale this is white color): ??
Roi roi?=??
new?Roi(30,?40,?100,?100);?// x, y, width, height of the rectangle ??
ip.setRoi(roi); ??
ip.setValue(255); ??
ip.fill(); ??
???
// fill an oval region with 255 (white color when grayscale LUT): ??
OvalRoi oroi?=??
new?OvalRoi(50,?60,?100,?150);?// x, y, width, height of the oval ??
ip.setRoi(oroi); ??
ip.setValue(255); ??
ip.fill(ip.getMask());?// notice different fill method ??
? ? ? ? ? ? ? ? ? ? ? ?// regular fill() would fill the entire bounding box rectangle of the OvalRoi ??
// The method above is valid at least for PolygonRoi and ShapeRoi as well. ??
???
???
// draw the contour of any region with 255 pixel intensity ??
Roi roi?=?... ??
ip.setValue(255); ??
ip.draw(); ??
???
// update screen view of the image ??
imp.updateAndDraw(); ?
?
3、ROIs的一些事情:
A、有很多selection/ROI类型:Roi(矩形之一,也是所有其它类型的父类),Line, OvalRoi, PolygonRoi, PointRoi, FreehandRoi, ShapeRoi, TextRoi。另外有一些子类型,如PolygonRoi里的POLYGON、POLYLINE 类型。
B、大部分的ROI是用于编辑图像非常有用; 一些用于图像分析(Line,PointRoi,TextRoi)。
C、最强大的ROI是ShapeRoi:java.awt.geom.GeneralPath支持它,它能够存储任意数量的任何形状的不连续区域的。
D、ip.fill(ip.getMask())方法是最安全的,可在各种场合使用,只需要检查ImageProcessor的mask通过getMask()返回的不为null。
?
旋转,翻转和缩放图像(或者ROI)
ImagePlus imp?=?... ??
ImageProcessor ip?=?imp.getProcessor(); ??
???
ip.flipHorizontal(); ??
???
ip.flipVertical(); ??
???
ip.
rotateLeft(); ??
???
ip.rotateRight(); ??
???
// rotate WITHOUT enlarging the
canvas to fit ??
double?angle?=?45; ??
ip.setInterpolate(true);?// bilinear ??
ip.rotate(45); ??
???
// rotate ENLARGING the canvas and filling the new areas with background color ??
double?angle?=?45; ??
IJ.run(imp,?"Arbitrarily...",?"angle="?+?angle?+?" grid=1 interpolate enlarge"); ??
???
// scale WITHOUT
modifying the canvas dimensions ??
ip.setInterpolate(true);?// bilinear ??
ip.scale(2.0,?2.0);?// in X and Y ??
???
// scale ENLARGING or SHRINKING the canvas dimensions ??
double?sx?=?2.0; ??
double?sy?=?0.75; ??
int?new_width?=?(?
int)(ip.getWidth()?*?sx); ??
int?new_height?=?(?
int)(ip.getHeight()?*?sy); ??
ip.setInterpolate(true);?// bilinear ??
ImageProcesor ip2?=?ip.resize(new_width, new_height);?// of the same type as the
original ??
imp.setProcessor(imp.getTitle(), ip2);?// UPDATE the original ImagePlus ??
???
// update screen view of the image ??
imp.updateAndDraw(); ?
ImageProcessor类提供了绘制线条、文字和点等。看看在ImageProcessor的API。
?
4、低层次的编辑方式:像素数组
ImagePlus imp?=?... ??
ImageProcessor ip?=?imp.getProcessor(); ??
???
// Editing the pixel array ??
if?(imp.getType()?==?ImagePlus.GRAY8) { ??
? ???
byte[] pixels?=?(?
byte[])ip.getPixels(); ??
? ??// ... do whatever
operations directly on the pixel array ??
} ??
???
// Replacing the pixel array: ONLY if same size ??
if?(imp.getType()?==?ImagePlus.GRAY8) { ??
? ???
int?width?=?ip.getWidth(); ??
? ???
int?height?=?ip.getHeight(); ??
? ???
byte[] new_pixels?=??
new??
byte[width?*?height]; ??
? ??// set each pixel value to whatever, between -128 and 127 ??
? ???
for?(?
int?y=0; y<height; y++) { ??
? ? ? ???
for?(?
int?x=0; x<width; x++) { ??
? ? ? ? ? ??// Editing pixel at x,y position ??
? ? ? ? ? ? new_pixels[y?*?width?+?x]?=?...; ??
? ? ? ? } ??
? ? } ??
? ??// update ImageProcessor to new array ??
? ? ip.setPixels(new_pixels); ??
} ??
???
// Replacing the pixel array but of different length: for example, to resize 2.5 times in width and height ??
int?new_width?=?(?
int)(ip.getWidth()?*?2.5); ??
int?new_height?=?(?
int)(ip.getHeight()?*?2.5); ??
ImageProcessor ip2?=?ip.createProcessor(new_width, new_height);?// of same type ??
imp.setProcessor(imp.getTitle(), ip2); ??
???
if?(imp.getType()?==?ImagePlus.GRAY8) { ??
? ???
byte[] pix?=?(?
byte[])imp.getProcessor().getPixels();?// or ip2.getPixels(); ??
? ??// .. process pixels ... ??
? ???
for?(?
int?y=0; y<height; y++) { ??
? ? ? ???
for?(?
int?x=0; x<width; x++) { ??
? ? ? ? ? ??// Editing pixel at x,y position ??
? ? ? ? ? ? new_pixels[y?*?width?+?x]?=?...; ??
? ? ? ? } ??
? ? } ??
} ??
???
// DON'T forget to update the screen image! ??
imp.updateAndDraw(); ?
如果要显示的ImagePlus,更新图像只有必须的,
?
六、保存图像?
1、高层次的方式
ImagePlus imp?=?... ??
IJ.saveAs(imp,?"tif",?"/path/to/image.tif"); ??
???
// or by using the file format extension: ??
IJ.save(imp,?"/path/to/image.tif");
? ??
很多格式都支持。在?IJ类里搜索方法?"saveAs"
2、通过FileSaver类
ImagePlus imp?=?... ??
new?FileSaver(imp).saveAsTiff("/path/to/image.tif");?
该FileSaver类有更多的选择:saveAsTiffStack,saveAsJpeg,saveAsPng,saveAsGif ...等。
?
?
这算是ImageJ入门第一篇,介绍一些基本操作,它的扩张机制和实现方式都很值得
研究。希望更多的人参与进来。
?
?