代码之家  ›  专栏  ›  技术社区  ›  Joe Soul-bringer

如何将MATLAB图像处理程序转换为java?

  •  10
  • Joe Soul-bringer  · 技术社区  · 17 年前

    我用MATLAB编写了一个图像处理程序,该程序充分利用了MATLAB图像处理工具箱,特别是形态学运算(imopen、imclose)和imadjust。我们做了很多样条拟合操作,还做了很多medfilt2和medfilt1。

    我们有一个客户希望我们将这个程序转换成Java。我想听听Java图像处理库的详细描述,它可以复制MATLAB在图像处理和样条曲线中的功能,特别是界面与MATLAB的比较。

    我读过Java的高级图像处理库,但在网上找不到任何详细的文档。另外,我读到的关于它的小文档似乎表明它使用了一个相当复杂的图像模型,将它们组合成瓷砖等等。如果有一个Java库允许我继续将灰度图像作为2D或3D数组处理,那将是一件非常棒的事情。

    此外,了解MATLAB和Java之间的转换中的任何一般性问题也会很好。


    编辑:我们的应用程序目前分割一个相对简单对象的图像。 它:

    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. 
    

    MATLAB的Builder JA是一个选项,但我还想知道纯Java中有什么可用,以及Builder JA涉及到什么类型的开销。


    编辑2:

    请注意,我们正在做脊椎 -使用给定点对样条曲线的拟合作为决定是否消除它的方法-因为数据是 ,我们有一个多步骤的点消除过程,因此样条曲线是 完整的


    编辑2.5:我们使用具有固定节数(0-5节)的样条曲线对一组点进行最小二乘近似。如果我们必须重新实现它,事情会变得很危险,因为现在我们正在使用MATLAB提供的库。

    8 回复  |  直到 17 年前
        1
  •  9
  •   mmr    17 年前

    将Matlab代码转换为Java代码有几个常见的陷阱。我已经把MATLAB转换成C++代码,所以我的建议来自于这些经验。

    1. 如果您在Matlab中使用for循环,一般来说,您是做错了。添加矩阵(图像等)非常简单:

      a=b+c;

      不管图像的大小。过滤也是一个相当简单的调用:

      JAI(Java Advanced Imaging)中也存在类似的函数调用,因此请查看是否可以找到它们。我不知道中位数过滤要求的具体内容(我假设medfilt1是一个3x3的本地中位数过滤内核,而不是在数据上运行的1D过滤内核,因为这意味着您只在一个方向上进行过滤),所以请看一下其中的内容 the documentation. 但是,如果您自己编写,上面的添加可以像双重嵌套for循环一样简单,也可以像实现类似

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

      我的观点是,Matlab的简单性可以掩盖所有需要做出的设计决策,从而使其成为一个高效的java程序。

    2. 记住,当您执行for循环时,matlab和java的行/列顺序是相反的。Matlab是column major,java是 row-major . 您将需要重写循环以将该更改考虑在内,否则您的代码将比应该的慢。

    3. 就我个人而言,我倾向于避免JAI,但我需要完成的具体操作除外。例如,只需将其用于中值滤波操作等。我认为使用它是一个优化,但这只是因为我是老学校,往往写我自己的图像处理操作。如果采用这种方法,您可以完全按照自己的要求编写代码,然后可以添加JAI调用,并确保输出与代码已经执行的操作相匹配。在C++中使用像JAI或英特尔IPP这样的高级库的问题是,有很多库特定的GOTCHAS(像是平铺,或者每行是否分配成一个位图,在末尾有几个额外的像素,或者其他的细节),您不希望在处理这些问题的同时将代码移到另一个位置。JAI很快,但它不是一颗神奇的子弹;如果你不知道如何使用它,最好先确定你有东西,然后再快速得到。

    4. 如果我能读懂一点字里行间的意思,看起来你在对医学影像数据进行某种分割。我不知道java库在DICOM图像中是什么,但是GDCM对于C++和C语言很好,而且还有java包装器。Matlab掩盖了图像处理的易用性,尤其是DICOM图像处理,因此您可能会发现自己必须学习一些DICOM库才能处理图像文件操作。多年来,我学习了一小部分DICOM标准;这个 specification 是非常完整的,也许过于完整,但你可以在极其详细的细节中找出如何做你需要做的事情。如果您试图对医疗数据进行分割,那么在数据上保存样条线并不是正确的做法,这样您的图像就可以与其他DICOM读取器一起操作。请查看指定轮廓的方式。

    根据进一步信息进行编辑:

    样条曲线拟合最好从数值方法而不是库方法来完成。在JAI中可能有一种方法可以做到这一点,但我对这门语言还不够熟悉。

    相反,我会查看数字配方,特别是 Chapter 3 ,用于样条曲线拟合的代码。代码是基于一的,而不是基于零的,所以它需要一些翻译,但它是完全可行的。

    如果尝试从边界中删除噪波点,可能还需要尝试模糊最初从中导出点的边。如果不知道您正在尝试进行的样条曲线拟合(有许多变体),就很难用另一种语言推荐完全相同的样条曲线拟合。

    编辑2.5:如果通过贡献库中的样条曲线拟合,您的意思是 this code ? 如果出现最坏的情况,你至少有源代码。如果你最终不得不做这样的事情,另一个非常有用的提示是Matlab都是双精度的,除非你强迫它(即使这样,很多操作在非双精度上也不起作用)。因此,为了保持合理的一致性,您还需要双倍地编写代码。我还做了一些测试。如果您最终重写了该代码(或类似代码),那么拥有一组已知的输入和预期的输出(在合理的误差范围内,您必须定义“合理”的含义)对于确保您正在复制(而不是真正重新发明)的机轮与原始机轮具有相同的每距离旋转是至关重要的。最后一句话中可能有太多的偏执表达。

    还有一个编辑:如果上面所有的内容都是头疼的话,那么考虑JA Builder已经指出了。否则,我所概述的方法,或类似的方法,很可能就是你的结局。

        2
  •  4
  •   jitter    17 年前

    用电脑怎么样 MATLAB Builder JA

        3
  •  3
  •   Nick Fortescue    16 年前

    当我在过去将MATLAB代码转换为Java代码时,我发现 CERN COLT 图书馆非常有用。他们不会做你的图像处理,但他们通过快速转换矩阵数学代码为我节省了很多时间。

        4
  •  2
  •   Clint    17 年前

    ImageJ . 这是一个开源Java应用程序,有许多用于图像分析和操作的插件。中值滤波是内置的。

    如果您能更详细地描述样条线操作,我很可能会为您提供所需ImageJ操作的信息。

    java中的样条曲线拟合示例: http://www.mste.uiuc.edu/exner/java.f/leastsquares/

        5
  •  1
  •   dlamblin    17 年前

    this way . 我打算建议您了解Weka使用什么来实现矩阵运算(我从未使用过),但我想它可能不会使用其他库来实现这一点。即使是这样,它也可能不像matlab,也不支持图像。

        6
  •  1
  •   Paulo    17 年前

    您可以编译一个MATLAB脚本,使其独立运行。这并不是在所有情况下都有效,但如果有效,您可以不使用快速的MATLAB代码,尝试从Java调用图像处理器。

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

        7
  •  0
  •   Matthew Flaschen    17 年前

    我相信 Raster.getPixels WritableRaster.setPixels 允许您所说的像素数据修改。

    不过,我不会假装这个端口很简单。

        8
  •  0
  •   Dima    17 年前

    一般来说,图像处理操作耗时,因此它们通常是为了速度而在C或C++中实现的,因此,对于您需要的java代码来说,很难找到Java代码。你可能最终不得不为其中的至少一部分人自己翻滚。您提到的操作,如形态学或中值滤波器,都有很好的文档记录,而且实现起来相当简单,特别是当您需要查看和测试matlab函数时。