views:

3342

answers:

8

I've written an image processing program in MATLAB which makes heavy use of the MATLAB Image Processing Toolbox, especially the morphological operations (imopen, imclose) as well as imadjust. We do a lot of spline fit operations and medfilt2 and medfilt1 a lot also.

We have a client who wants us to convert this program to Java. I would like to hear a detailed description of a Java image processing library which can duplicate MATLAB's functionality in image processing and splines, especially how the interface compares with MATLAB's.

I have read about Java's Advanced Image Processing Library but I haven't been able to find any detailed documentation on it on the web. Also, the little documentation I've read about it seems to indicate that it uses a rather complex model of images, combining them into tiles and so-forth. It would be great if there was a Java library which allowed me to continue to treat gray scale images as just 2D or 3D arrays.

Also, it would be great to learn of any general gotchas in converting between MATLAB and Java.


Edit: our app currently segments images of a relatively simple object. It:

1. Starts with a 3D matrix of gray scale image slices representing a single area
2. Does a medfilt1 to even out each slice. 
3. Does some imopen, imclose and imadjust operations on the image to remove some fuzziness, 
4. Does some simple thresholding in various areas to find boundary points
5. Fits splines to the boundary points, 
6. Uses the 3rd dimension in various ways to further perfect the point matching, especially using medfilt2. 
7. Saves each slice with the boundary splines written in color on it.

I should note that we're doing "spline fitting" rather than spline matching - spline fitting is a least square match with a fixed number of knots - spline matching matches the points exactly with an arbitrary number of knots. I wouldn't want to implement spline matching from more simplistic spline functions.

MATLAB's Builder JA is an option but I would like to also know what's available in pure Java as well as know what kind of overhead Builder JA involves.


Edit 2:

Note that we are doing spine fitting - using a given point's fit to the spline as a way to decide whether to eliminate it - since the data is messy, we have a multi-step point elimination process, so splines are an integral part of the algorithm. And so, since I can't find any mention of splines in JAI at all, so if anyone knows a java library offering least-square spline fitting, that would be wonderful.


Edit 2.5: We're using a least-square approximation of a set of points using splines with a fixed number of knots (0-5 knots). If we have to re-implement that, things will get dicey, since right now we're using a MATLAB contributed library for it.

And we certainly don't want to revisit the algorithm. It was hard enough getting something that worked...

A: 

I believe Raster.getPixels and WritableRaster.setPixels allow the kind of pixel data modification you're talking about.

I'm not going to pretend this port will be simple, though.

Matthew Flaschen
But what would not be simple about it?
Joe Soul-bringer
Someone must have voted this answer down. Why, it is entirely useful
Joe Soul-bringer
+2  A: 

Without explicitly addressing the Matlab question you should look at ImageJ. This is an open source Java application with many contributed plugins for image analysis and manipulation. Median filtering is built in.

The biggest problem I have had with converting Matlab to Java is that you will be writing many loops to handle functions that are one line in Matlab.

If you can describe your spline operations in more detail I can most likely get you information on which ImageJ operations you need.

Example of spline fitting in java: http://www.mste.uiuc.edu/exner/java.f/leastsquares/

Clint
Maybe a link to where the mophological operation in this library are. From the entry link, I can't tell if its a library or an application
Joe Soul-bringer
It's an application. It's not a bad idea to write the core of your application as a plugin to ImageJ, and then write all the image-handling portions of your code after you've got the core stuff working as it should.
mmr
A: 

Generally, image processing operations are time-consuming, so they are often implemented in C or C++ for the sake of speed, so it is not surprising that you are having trouble finding Java code for what you need. You may end up having to roll your own for at least some of them. The operations you have mentioned such as morphology or the median filters are well documented and are fairly simple to implement, especially when you have the matlab functions to look at and to test against.

Dima
Actually pixastic is a javascript not a java library
jitter
Oops... I said it was a _quick_ google search.
Dima
+4  A: 

How about using the MATLAB Builder JA provided by The MathWorks itself, which is the developer of MATLAB itself.?

jitter
Only drawback to this is that it requires the Matlab runtime, which is freely distributable but fairly large (130mb)
Ian Hopkinson
+1  A: 

Just don't do it this way. I was going to recommend you find out what Weka uses to implement matrix operations (I've never used it) but I'm supposing it might not use another library for this. Even if it did, it may not be matlab-like, nor support images.

dlamblin
+1  A: 

You can compile a MATLAB script to have it run independently. This doesn't work in all cases but if it does, you can leave your fast MATLAB code alone and try calling the image processor from Java.

http://www.mathworks.com/products/compiler/

Paulo
+6  A: 

There are several general pitfalls about converting Matlab code to Java code. I've converted Matlab to C++ code, so my advice comes from those experiences.

  1. If you're using for loops in Matlab, in general, you're doing it wrong. Adding matrices (images, etc) is a fairly simple:

    a = b + c;

    no matter the size of the image. Filtering is also a fairly straightforward call:

    a = imfilter('median', b); #or something like this, I'm not in front of my matlab machine at the moment.

    Similar function calls exist in JAI (Java Advanced Imaging), so see if you can find them. I don't know the specifics of your median filtering requirements (I assume medfilt1 is meant to be a 3x3 local median filtering kernel, rather than a 1D filtering kernel run on the data, because that would mean that you're filtering only in one direction), so take a look at what's there in the documentation. But, if you write your own, the above addition can be as simple as a doubly-nested for loop, or a complicated class that implements something like

    MyMatrix a = MyMatrix.Add(b, c);

    My point is, the simplicity of Matlab can obscure all the design decisions you need to make in order to make this an efficient java program.

  2. Remember, when you do do for loops, matlab and java have reverse row/column order. Matlab is column-major, and java is row-major. You will need to rewrite your loops to take that change into account, or else your code will be slower than it should be.

  3. Personally, I'd tend to avoid the JAI except for specific operations that I need to have accomplished. For instance, just use it for the median filtering operations and so forth. I consider using it to be an optimization, but that's just because I'm Old School and tend to write my own image processing operations first. If you take that approach, you can write your code to be exactly what you want, and then you can add in the JAI calls and make sure that the output matches what your code already does. The problem with using advanced libraries like the JAI or the Intel IPP in C++ is that there are a lot of library-specific gotchas (like tiling, or whether or not each row is allocated like a bitmap with a few extra pixels on the end, or other such details), and you don't want to be dealing with those problems while at the same time moving your code over. JAI is fast, but it's not a magic bullet; if you don't know how to use it, better to make sure that you've got something before you've got something fast.

  4. If I can read between the lines a little bit, it looks like you're doing some kind of segmentation on medical imaging data. I don't know what the java libraries are for reading in DICOM images are, but gdcm works well for C++ and C#, and also has java wrappers. Matlab obscures the ease of image handling, especially DICOM image handling, so you may find yourself having to learn some DICOM library in order to handle the image file manipulations. I've learned a small fraction of the DICOM standard over the years; the specification is extremely complete, perhaps overly so, but you can figure out how to do what you need to do in excruciating detail. If you're trying to do segmentations of medical data, saving the spline on the data is not the right thing to do so that your images operate with other DICOM readers. Take a look at the way contours are specified.

Edit in response to further information:

Spline Fitting is probably best done from a numerical approach rather than a library approach. There may be a way to do this in JAI, but I'm not familiar enough with the language.

Instead, I'd check out Numerical Recipes, specifically Chapter 3, for code on spline fitting. The code is one based, not zero based, so it requires some translation, but it's entirely doable.

If you're trying to remove noise points from a boundary, you may also want to try blurring the edges that you're originally deriving your points from. Without knowing the spline fitting you're trying to do (there are many variations), it'd be hard to recommend an exact equivalent in another language.

Edit 2.5: If by spline fitting from a contributed library, do you mean something like this code? If worst comes to worst, you'd at least have the source code. If you do end up having to do something like this, another very useful tip is that Matlab is all doubles, nothing else unless you force it (and even then, a lot of operations don't work on non-doubles). So, you'll need to do your code in doubles as well, in order to maintain reasonable agreement. I'd also make several tests. If you do end up rewriting that code (or something like it), having a group of known inputs and expected outputs (within some reasonable margin of error, where you have to define what 'reasonable' means) will be critical in making sure that the wheel you're copying (not really reinventing) has the same rotations per distance as the original. There are probably too many paranthetical expressions in that last sentence.

Yet Another Edit: If all of the above is too much of a headache, then consider the JA builder already pointed out. Otherwise, the approach I've outlined, or something similar, will probably be where you end up.

mmr
Thanks, see my comments above...
Joe Soul-bringer
+2  A: 

When I've converted MATLAB code to Java code in the past I've found the CERN COLT libraries very helpful. They won't do your image processing, but they have saved me a lot of time by making converting matrix math code very quick.

Nick Fortescue