`

Java图像处理最快技术:ImageJ

    博客分类:
  • java
阅读更多
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入门第一篇,介绍一些基本操作,它的扩张机制和实现方式都很值得研究。希望更多的人参与进来。
 

 

分享到:
评论

相关推荐

    ImageJ java中文开发教程

    ImageJ是一个非常受欢迎的开源图像处理软件,它基于Java语言开发,具有强大的图像处理功能,并且支持通过插件进行二次开发,从而扩展图像处理能力。ImageJ适用于科研、医学影像分析、机器视觉、地理信息系统等多个...

    ImageJ jar包

    ImageJ jar包 ImageJ是世界上最快的纯Java的图像处理程序 警告:请勿用于商业用途,仅供学习研究,如任何版权纠纷,本人概不负责!

    ImageJ的大量插件

    ImageJ是一个强大的图像处理与分析工具。ImageJ具有很强的扩展性,其已经有300多个插件可用。ImageJ也可以做为一个图像处理工具包,用于开发applets,servlets或其它应用程序。ImageJ是当前最快的纯Java图像处理程序。

    Fiji(ImageJ) Win64安装包

    **Fiji(ImageJ) Win64安装包**是一款专用于图像处理的强大软件,适用于64位Windows操作系统。ImageJ是由Wayne Rasband开发的开源图像分析平台,而Fiji是其一个高度集成的、功能丰富的扩展版本。Fiji在ImageJ的基础上...

    image4j jar

    `image4j`是一个专注于图像处理的Java库,尤其在处理BMP和ICO格式上表现出色。它提供了丰富的API,使得开发者可以方便地进行BMP到ICO以及ICO到BMP的转换操作。在这个库的帮助下,Java开发者无需依赖额外的图形处理...

    Java Tess4J 实现OCR 可运行Demo

    3. **读取图像**:你可以使用Java的`java.awt.image.BufferedImage`类来读取图像文件,或者直接传递图像文件路径给Tess4J。 4. **执行OCR**:调用`TessBaseAPI.init()`方法初始化OCR引擎,然后使用`TessBaseAPI....

    java开源包8

    它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步...

    图片剪裁java

    3. **Java图像处理库**: 虽然Java的标准库已经提供了基本的图像处理功能,但如果你需要更复杂或高效的处理,可以考虑使用第三方库,如`ImageJ`或`JavaFX`。`ImageJ`是一个强大的科学图像处理库,而`JavaFX`提供了...

    java开源包6

    它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步...

    java开源包9

    它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步...

    java开源包4

    它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步...

    java开源包101

    它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步...

    java开源包5

    它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步...

    java开源包10

    它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步...

    java开源包1

    它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步...

    java开源包3

    它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步...

    Java资源包01

    它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加起来就不小了),而相比之下 C3P0 要六百多K。 异步...

    Java三种生成条形码的源码(barcode4j、jbarcode、google-zxing)

    - 创建`ImageWriter`对象,选择图像格式(如JPEG或PNG)。 - 调用`writeToFile`或`writeToStream`方法生成并保存条形码图像。 3. **google-zxing(ZXing,意为“快速可扩展”)**: ZXing是一个多平台的开源条形...

    Java三种生成条形码(barcode4j、jbarcode、google-zxing)

    本文将深入探讨三种主流的Java条形码生成库:barcode4j、jbarcode和google-zxing,以及如何利用它们创建条形码。 首先,**barcode4j**是一个基于XML的、可扩展的条形码生成库,它使用Apache Batik来渲染SVG(可缩放...

Global site tag (gtag.js) - Google Analytics