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...
Answers (1) There is a Mathworks Product named "Java Builder", which will create Java code that can execute the MATLAB. This is, however, not a code conversion: it creates a data file that has a MATLAB internal format and interprets that.
MATLAB is one of the most important software inventions of the twentieth century. From a DSP point of view, its syntax is simply the best in the world. And, image processing is one of its strongest points.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With