private static Mat filterSingleChannel(Mat p, double s, ArrayList<Mat> Isubchannels, ArrayList<Mat> Ichannels, 
			Mat mean_I_r, Mat mean_I_g, Mat mean_I_b, Mat invrr, Mat invrg, Mat invrb, Mat invgg, Mat invgb, 
			Mat invbb, double r_sub) {
		Mat p_sub = new Mat();
		Imgproc.resize(p, p_sub, new Size(p.cols() / s, p.rows() / s), 0.0, 0.0, Imgproc.INTER_NEAREST);

		Mat mean_p = boxfilter(p_sub, (int) r_sub);

		Mat mean_Ip_r = boxfilter(Isubchannels.get(0).mul(p_sub), (int) r_sub);
		Mat mean_Ip_g = boxfilter(Isubchannels.get(1).mul(p_sub), (int) r_sub);
		Mat mean_Ip_b = boxfilter(Isubchannels.get(2).mul(p_sub), (int) r_sub);

		// convariance of (I, p) in each local patch
		Mat cov_Ip_r = new Mat();
		Mat cov_Ip_g = new Mat();
		Mat cov_Ip_b = new Mat();
		Core.subtract(mean_Ip_r, mean_I_r.mul(mean_p), cov_Ip_r);
		Core.subtract(mean_Ip_g, mean_I_g.mul(mean_p), cov_Ip_g);
		Core.subtract(mean_Ip_b, mean_I_b.mul(mean_p), cov_Ip_b);

		Mat temp1 = new Mat();
		Mat a_r = new Mat();
		Mat a_g = new Mat();
		Mat a_b = new Mat();
		Core.add(invrr.mul(cov_Ip_r), invrg.mul(cov_Ip_g), temp1);
		Core.add(temp1, invrb.mul(cov_Ip_b), a_r);
		Core.add(invrg.mul(cov_Ip_r), invgg.mul(cov_Ip_g), temp1);
		Core.add(temp1, invgb.mul(cov_Ip_b), a_g);
		Core.add(invrb.mul(cov_Ip_r), invgb.mul(cov_Ip_g), temp1);
		Core.add(temp1, invbb.mul(cov_Ip_b), a_b);

		Mat b = new Mat();
		Core.subtract(mean_p, a_r.mul(mean_I_r), b);
		Core.subtract(b, a_g.mul(mean_I_g), b);
		Core.subtract(b, a_b.mul(mean_I_b), b);

		Mat mean_a_r = boxfilter(a_r, (int) r_sub);
		Mat mean_a_g = boxfilter(a_g, (int) r_sub);
		Mat mean_a_b = boxfilter(a_b, (int) r_sub);
		Mat mean_b = boxfilter(b, (int) r_sub);

		Imgproc.resize(mean_a_r, mean_a_r, 
				new Size(Ichannels.get(0).cols(), Ichannels.get(0).rows()), 0.0, 0.0, Imgproc.INTER_LINEAR);
		Imgproc.resize(mean_a_g, mean_a_g, 
				new Size(Ichannels.get(0).cols(), Ichannels.get(0).rows()), 0.0, 0.0, Imgproc.INTER_LINEAR);
		Imgproc.resize(mean_a_b, mean_a_b, 
				new Size(Ichannels.get(0).cols(), Ichannels.get(0).rows()), 0.0, 0.0, Imgproc.INTER_LINEAR);
		Imgproc.resize(mean_b, mean_b, 
				new Size(Ichannels.get(0).cols(), Ichannels.get(0).rows()), 0.0, 0.0, Imgproc.INTER_LINEAR);

		Mat result = new Mat();
		Core.add(mean_a_r.mul(Ichannels.get(0)), mean_a_g.mul(Ichannels.get(1)), temp1);
		Core.add(temp1, mean_a_b.mul(Ichannels.get(2)), temp1);
		Core.add(temp1, mean_b, result);
		return result;
	}
Guided Image Filter for Color Image
@param origI guidance image (should be a gray-scale/single channel image)
@param p filtering input image (should be a gray-scale/single channel image)
@param r local window radius
@param eps regularization parameter
@param s blocks number, s * s
@param depth image depth
@return filtered image
src/main/java/com/isaac/utils/Filters.java