BufferedImage ret=null;
if(bi==null)return ret;
Profile.begin();
//create current frame image and scale it
IImage2d inputNow=new ImageRGBA();
inputNow.create(bi);
sfNow.init(inputNow.getWidth(), inputNow.getHeight(), 16, 2);
sfNow.filter(inputNow);
Profile.out();
if(inputPrev!=null){
IImage2d calcatedFlow=new ImageRGBA_SNORM_INT16();;
calcatedFlow.create(1, 1, true);
Helpers.getInstance().clear(calcatedFlow);
//for all scaled images,from small to large
for(int i=sfPrev.outputs.size()-1;i>=0;--i){
IImage2d i1=sfPrev.outputs.get(i),i2=sfNow.outputs.get(i);
//create preprocessed image
IImage2d preprocessed=new ImageRGBA_SNORM_INT16();
preprocessed.create(i1.getWidth(), i1.getHeight(), true);
preprocess.filter(i1, preprocessed);
Profile.out("pre");
IImage2d flowout=new ImageRGBA_SNORM_INT16();
flowout.create(preprocessed.getWidth(), preprocessed.getHeight(), true);
solve.filter(i2, preprocessed,calcatedFlow,flowout);
calcatedFlow.dispose();
//iterate current level
if(iterateCount>0){
IImage2d flowout1=new ImageRGBA_SNORM_INT16();
flowout1.create(preprocessed.getWidth(), preprocessed.getHeight(), true);
IImage2d fin=flowout;
for(int k=0;k<iterateCount;++k){
IImage2d fnext=fin==flowout?flowout1:flowout;
solve_k.filter(i2, preprocessed,fin,fnext);
fin=fnext;
}
IImage2d fnext=fin==flowout?flowout1:flowout;
fnext.dispose();
flowout=fin;
}