docs: protected void processLayer(GrayF32 image1 , GrayF32 image2 ,
  								GrayF32 deriv1X , GrayF32 deriv1Y,
  								GrayF32 deriv2X , GrayF32 deriv2Y,
  								GrayF32 deriv2XX , GrayF32 deriv2YY, GrayF32 deriv2XY) {
  
  		int N = image1.width*image1.height;
  		int stride = image1.stride;
  
  		// outer Taylor expansion iterations
  		for( int indexOuter = 0; indexOuter < numOuter; indexOuter++ ) {
  
  			// warp the image and the first + second derivatives
  			warpImageTaylor(image2, flowU, flowV, warpImage2);
  
  			warpImageTaylor(deriv2X, flowU, flowV, warpDeriv2X);
  			warpImageTaylor(deriv2Y, flowU, flowV, warpDeriv2Y);
  
  			warpImageTaylor(deriv2XX, flowU, flowV, warpDeriv2XX);
  			warpImageTaylor(deriv2YY, flowU, flowV, warpDeriv2YY);
  			warpImageTaylor(deriv2XY, flowU, flowV, warpDeriv2XY);
  
  			gradient.process(flowU,derivFlowUX,derivFlowUY);
  			gradient.process(flowV,derivFlowVX,derivFlowVY);
  
  			computePsiSmooth(derivFlowUX,derivFlowUY,derivFlowVX,derivFlowVY,psiSmooth);
  
  			computeDivUVD(flowU, flowV,psiSmooth,divU,divV,divD);
  
  			// initialize the motion increments to zero
  			Arrays.fill(du.data,0,N,0);
  			Arrays.fill(dv.data,0,N,0);
  
  			for( int indexInner = 0; indexInner < numInner; indexInner++ ) {
  
  				computePsiDataPsiGradient(image1, image2,
  						deriv1X, deriv1Y,
  						deriv2X, deriv2Y, deriv2XX, deriv2YY, deriv2XY,
  						du, dv, psiData, psiGradient);
  
  				float error;
  				int iter = 0;
  
  				do {
  					// inner SOR iteration.
  					error = 0;
  
  					// inner portion
  					for (int y = 1; y < image1.height - 1; y++) {
  						int i = y * image1.width + 1;
  						for (int x = 1; x < image1.width - 1; x++, i++) {
  							error += iterationSor(image1, deriv1X, deriv1Y, i, i + 1, i - 1, i + stride, i - stride);
  						}
  					}
  
  					// border regions require special treatment
  					int y0 = 0;
  					int y1 = image1.height-1;
  					for (int x = 0; x < image1.width; x++ ) {
  						error += iterationSor(image1, deriv1X, deriv1Y,
  								s(x, y0), s(x + 1, y0), s(x - 1, y0), s(x, y0 - 1), s(x, y0 + 1));
  
  						error += iterationSor(image1, deriv1X, deriv1Y,
  								s(x, y1), s(x + 1, y1), s(x - 1, y1), s(x, y1 - 1), s(x, y1 + 1));
  					}
  
  					int x0 = 0;
  					int x1 = image1.width-1;
  					for (int y = 1; y < image1.height - 1; y++) {
  						error += iterationSor(image1, deriv1X, deriv1Y,
  								s(x0, y), s(x0 - 1, y), s(x0 + 1, y), s(x0, y - 1), s(x0, y + 1));
  						error += iterationSor(image1, deriv1X, deriv1Y,
  								s(x1, y), s(x1 - 1, y), s(x1 + 1, y), s(x1, y - 1), s(x1, y + 1));
  					}
  				} while (error > convergeTolerance * image1.width * image1.height && ++iter < maxIterationsSor);
  			}
  
  			// update the flow with the motion increments
  			PixelMath.add(flowU,du, flowU);
  			PixelMath.add(flowV,dv, flowV);
  		}
  	}