Java Servlet调用Matlab算法

来源:互联网 发布:python turtle填色 编辑:程序博客网 时间:2024/04/17 03:36

最近做一个基于移动终端(手机为例)的人脸识别系统,要用到我自己的matlab算法,所以就写此博客为读者介绍和分析一下Java Servlet中调用Matlab算法的过程和需要注意的一些细节问题。

一、封装Matlab算法

将自己写的Matlab算法在.m文件中写成一个function,然后通过javabuilder打包成Java Servlet 可以调用的jar包。前提是该版本的Matlab支持javabuilder。封装步骤如下:

(1)在matlab的command窗口中输入“deploytool"回车,就会弹出一个窗口

(2)在弹出窗口中Name栏输入工程名称,Location栏输入文件的位置,在Target 栏选择Java Package,确定后会在Matlab中的右边弹出一个窗口,点击Add class输入jar包中的类名,如“Test”

接着点击Add files 就可以添加你需要直接调用或间接调用的matlab方法。最后点击按钮创建jar包。没有报错就说明创建完成。

(3)jar创建完成后,会生成一个工程文件夹和一个prj文件,prj文件是工程文件,文件夹中包含两个文件夹:distrb和src。接着将distrb->XXX.jar和src->class->XXX(类名)->XXX.ctf放在同一目录下,并将XXX.jar的路径添加到classpath环境变量中。

注意事项:在导出jar包之前要保证自己的matlab已经安装好了MCRInstaller.exe。如果没有安装可以在matlab安装路径中找到并安装。我的MCRInstaller.exe文件路径是C:\Program Files\MATLAB\R2009b\toolbox\compiler\deploy\win32\MCRInstaller.exe

二、在eclipse中添加jar包

在web工程中导入jar包,将之前生成的XXX.jar包复制到WebContent->WEB-INFO下lib文件夹中,右键点击jar包->build path -> add to build path。然后在matlab安装路径中找到javabuilder.jar包并复制到WebContent->WEB-INFO下lib文件夹中,同样右键点击jar包->build path -> add to build path。我的。javabuilder.jar包的路径为:C:\Program Files\MATLAB\R2009b\toolbox\javabuilder\jar\javabuilder.jar。

jar 包添加成功以后就可以在Servlet中正常调用了。

注意事项:右键单击工程->build path->configure build path->library->add external jars添加jar包会提示找不到jar包,因为jar包没有复制到工程中。

可能出现的异常:报MCR.exe错误 ,说明在第一步中MCRInstaller.exe没有安装。如果报类找不到说明第二步中添加jar包的方式不对。

三、实例

此实例将说明Matblab函数中存在函数之间的调用并且函数返回的是多个不同类型的参数组成的数组,实现Servlet与Matlab之间的各类型参数互传,图片传送等。

(1)Matlab函数编写

函数1:初始化一个大小的矩阵

function A = getSize(a,b,c,d)
A = [a,b;c,d];

函数2 :调用函数1 并传入参数类型有字符串,整型。

function [name,number,size] = imgInfo(name1,number1,a,b,c,d)
name = name1;
number = number1;
size = getSize(a,b,c,d);
end

(2)将以上方法打成jar包,步骤参照封装Matlab算法部分。

 (3)在Servlet中调用上述封装的Matlab方法

导入jar包之后,包中内容如下


(4)Servlet中主程序调用

核心代码如下

MWCharArray s = null;
MWNumericArray number = null;
MWNumericArray size = null;

try {
MyTest myTest = new MyTest();
s = new MWCharArray("Hello world!");
Object[] result = myTest.imgInfo(3, s,1,12,13,14,15);
number = new MWNumericArray(result[1],MWClassID.INT32);
size = new MWNumericArray(result[2]);
System.out.println(result[0].toString());
System.out.println(number);
System.out.println(size);
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
MWArray.disposeArray(s);
MWArray.disposeArray(number);
MWArray.disposeArray(size);
}

(5)输出结果


(6)程序分析

Matlab第一个函数是初始化一个二维数组,第二个函数是测试输入输出不同类型的参数。输出的第一个参数是字符串,第二个是整型,第三个是矩阵。

MWnumericArray是Java和Matlab之间的中间变量转换类型。

a、传字符串时用MWCharArray,传整型、Double、Float、int等类型及其相应矩阵时用MWNumericArray。传类、方法等结构体是用MWStructArray。

b、调用Matlab函数返回值都用Object[]接收,任何类型都可以。

c、myTest.imgInfo(3, s,1,12,13,14,15);函数的第一个参数表示返回值的个数,相应的输入参数类型要转换成对应的中间类型,整型可以不用转换。

d、程序调用完成最后要释放所有资源

(7)用第三方包进行图片传送

package binary_magic;

import java.util.ArrayList;

import ij.IJ;

import ij.ImagePlus;

import ij.process.ImageProcessor;

import imgbinary2.*;

import com.mathworks.toolbox.javabuilder.MWArray;

importcom.mathworks.toolbox.javabuilder.MWClassID;

importcom.mathworks.toolbox.javabuilder.MWNumericArray;

 

public class magic {

ImagePlus img,binimg;

ImageProcessor ip;

public void binary2(ImagePlus img,) {

  this.img=img;

  int w=img.getWidth();

  int h=img.getHeight();

  ImagePlus img1=IJ.createImage("newimage","",w,h,1);  

       ip=img1.getProcessor();       

     

  ArrayList<Object> tempList= new ArrayList<Object>();

  MWNumericArray n = null;

       Binary binMagic = null; /* Stores magic */

  try {  

    n= new MWNumericArray(Double.valueOf(3), MWClassID.DOUBLE);

   System.out.println("Magic square of order " +n.toString());  

   binMagic = new Binary();

/**

* made ImagePlus

**/ 

   Object Obimg[]=null;

    int num=0;

   Obimg=binMagic.bianry(1,);

   int[] k=((MWNumericArray)Obimg[0]).getDimensions();

//  IJ.log("width2="+k[1]+", height2="+k[0]);

   for(int i=0;i<k[1];i++){

    int offset=i*k[0];

    for(int j=0;j<k[0];j++){

     int pos=offset+j;

     num=((MWNumericArray)Obimg[0]).getInt(pos+1);

     //IJ.log("************"+num);

     if(num==0){

      ip.putPixel(i, j, num);

     }

     else{

      ip.putPixel(i, j, 255);

     }

    }

    }

   binimg=new ImagePlus("binary",ip);

   binimg.show();

/**

* end

**/ 

   }catch (Exception e) {

   System.out.println("Exception: " + e.getMessage());

   System.out.println("Exception: " + e.toString());

   }finally {  

   MWArray.disposeArray(n);

//  if (binMagic != null)

//   binMagic.dispose();

   }

}

public ImagePlus reBinary(){

  return binimg;

}

}

小结:本实例是参数图像处理项目写的一个小例子,实际项目算法程度复杂,调用传参过程多,在后续文章中再给出。



1 0