@SuppressWarnings("unused")
	public static Mat GuidedImageFilter_Color(Mat origI, Mat p, int r, double eps, double s, int depth) {
		//Pre-defined parameters
		ArrayList<Mat> Ichannels = new ArrayList<>();
		ArrayList<Mat> Isubchannels = new ArrayList<>();
		int Idepth;
		double r_sub;
		Mat mean_I_r;
		Mat mean_I_g;
		Mat mean_I_b;
		Mat invrr = new Mat();
		Mat invrg = new Mat();
		Mat invrb = new Mat();
		Mat invgg = new Mat();
		Mat invgb = new Mat();
		Mat invbb = new Mat();
		// Process
		Mat I;
		if (origI.depth() == CvType.CV_32F || origI.depth() == CvType.CV_64F) {
			I = origI.clone();
		} else {
			I = convertTo(origI, CvType.CV_32F);
		}
		Idepth = I.depth();
		Core.split(I, Ichannels);
		Mat I_sub = new Mat();
		Imgproc.resize(I, I_sub, new Size(I.cols() / s, I.rows() / s), 0.0, 0.0, Imgproc.INTER_NEAREST);
		Core.split(I_sub, Isubchannels);
		r_sub = r / s;
		mean_I_r = boxfilter(Isubchannels.get(0), (int) r_sub);
		mean_I_g = boxfilter(Isubchannels.get(1), (int) r_sub);
		mean_I_b = boxfilter(Isubchannels.get(2), (int) r_sub);

		// variance of I in each local patch: the matrix Sigma in Eqn (14).
		// Note the variance in each local patch is a 3x3 symmetric matrix:
		//           rr, rg, rb
		//   Sigma = rg, gg, gb
		//           rb, gb, bb    	
		Mat var_I_rr = new Mat();
		Mat var_I_rg = new Mat();
		Mat var_I_rb = new Mat();
		Mat var_I_gg = new Mat();
		Mat var_I_gb = new Mat();
		Mat var_I_bb = new Mat();
		Mat temp1 = new Mat();

		Core.subtract(boxfilter(Isubchannels.get(0).mul(Isubchannels.get(0)), (int) r_sub), 
				mean_I_r.mul(mean_I_r), temp1);
		Core.add(temp1, new Scalar(eps), var_I_rr);
		Core.subtract(boxfilter(Isubchannels.get(0).mul(Isubchannels.get(1)), (int) r_sub), 
				mean_I_r.mul(mean_I_g), var_I_rg);
		Core.subtract(boxfilter(Isubchannels.get(0).mul(Isubchannels.get(2)), (int) r_sub), 
				mean_I_r.mul(mean_I_b), var_I_rb);
		Core.subtract(boxfilter(Isubchannels.get(1).mul(Isubchannels.get(1)), (int) r_sub), 
				mean_I_g.mul(mean_I_g), temp1);
		Core.add(temp1, new Scalar(eps), var_I_gg);
		Core.subtract(boxfilter(Isubchannels.get(1).mul(Isubchannels.get(2)), (int) r_sub), 
				mean_I_g.mul(mean_I_b), var_I_gb);
		Core.subtract(boxfilter(Isubchannels.get(2).mul(Isubchannels.get(2)), (int) r_sub), 
				mean_I_b.mul(mean_I_b), temp1);
		Core.add(temp1, new Scalar(eps), var_I_bb);

		// Inverse of Sigma + eps * I
		Core.subtract(var_I_gg.mul(var_I_bb), var_I_gb.mul(var_I_gb), invrr);
		Core.subtract(var_I_gb.mul(var_I_rb), var_I_rg.mul(var_I_bb), invrg);
		Core.subtract(var_I_rg.mul(var_I_gb), var_I_gg.mul(var_I_rb), invrb);
		Core.subtract(var_I_rr.mul(var_I_bb), var_I_rb.mul(var_I_rb), invgg);
		Core.subtract(var_I_rb.mul(var_I_rg), var_I_rr.mul(var_I_gb), invgb);
		Core.subtract(var_I_rr.mul(var_I_gg), var_I_rg.mul(var_I_rg), invbb);

		Mat covDet = new Mat();
		Core.add(invrr.mul(var_I_rr), invrg.mul(var_I_rg), temp1);
		Core.add(temp1, invrb.mul(var_I_rb), covDet);

		Core.divide(invrr, covDet, invrr);
		Core.divide(invrg, covDet, invrg);
		Core.divide(invrb, covDet, invrb);
		Core.divide(invgg, covDet, invgg);
		Core.divide(invgb, covDet, invgb);
		Core.divide(invbb, covDet, invbb);

		Mat p2 = convertTo(p, Idepth);
		Mat result = new Mat();
		if (p.channels() == 1) {
			result = filterSingleChannel(p2, s, Isubchannels, Ichannels, mean_I_r, mean_I_g, mean_I_b, invrr, invrg, 
					invrb, invgg, invgb, invbb, r_sub);
		} else {
			ArrayList<Mat> pc = new ArrayList<>();
			Core.split(p2, pc);
			for (int i = 0; i < pc.size(); i++) {
				pc.set(i, filterSingleChannel(pc.get(i), s, Isubchannels, Ichannels, mean_I_r, mean_I_g, mean_I_b, invrr, 
						invrg, invrb, invgg, invgb, invbb, r_sub));
			}
			Core.merge(pc, result);
		}
		return convertTo(result, depth == -1 ? p.depth() : depth);
	}
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