content: package com.isaac.utils;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import org.opencv.core.Core;
  import org.opencv.core.CvType;
  import org.opencv.core.Mat;
  
  public class ColorBalance {
  
  	/**
  	 * Simplest Color Balance. Performs color balancing via histogram
  	 * normalization.
  	 *
  	 * @param img
  	 *            input color or gray scale image
  	 * @param percent
  	 *            controls the percentage of pixels to clip to white and black.
  	 *            (normally, choose 1~10)
  	 * @return Balanced image in CvType.CV_32F
  	 */
  	public static Mat SimplestColorBalance(Mat img, int percent) {
  		if (percent <= 0)
  			percent = 5;
  		img.convertTo(img, CvType.CV_32F);
  		List<Mat> channels = new ArrayList<Mat>();
  		int rows = img.rows(); // number of rows of image
  		int cols = img.cols(); // number of columns of image
  		int chnls = img.channels(); //  number of channels of image
  		double halfPercent = percent / 200.0;
  		if (chnls == 3) {
  			Core.split(img, channels);
  		} else {
  			channels.add(img);
  		}
  		List<Mat> results = new ArrayList<Mat>();
  		for (int i = 0; i < chnls; i++) {
  			// find the low and high precentile values (based on the input percentile)
  			Mat flat = new Mat();
  			channels.get(i).reshape(1, 1).copyTo(flat);
  			Core.sort(flat, flat, Core.SORT_ASCENDING);
  			double lowVal = flat.get(0, (int) Math.floor(flat.cols() * halfPercent))[0];
  			double topVal = flat.get(0, (int) Math.ceil(flat.cols() * (1.0 - halfPercent)))[0];
  			// saturate below the low percentile and above the high percentile
  			Mat channel = channels.get(i);
  			for (int m = 0; m < rows; m++) {
  				for (int n = 0; n < cols; n++) {
  					if (channel.get(m, n)[0] < lowVal)
  						channel.put(m, n, lowVal);
  					if (channel.get(m, n)[0] > topVal)
  						channel.put(m, n, topVal);
  				}
  			}
  			Core.normalize(channel, channel, 0, 255, Core.NORM_MINMAX);
  			channel.convertTo(channel, CvType.CV_32F);
  			results.add(channel);
  		}
  		Mat outval = new Mat();
  		Core.merge(results, outval);
  		return outval;
  	}
  
  }
  