// Catalano Imaging Library
// The Catalano Framework
//
// Copyright © Diego Catalano, 2012-2016
// diego.catalano at live.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
package Catalano.Imaging.Filters;
import Catalano.Imaging.FastBitmap;
import Catalano.Imaging.IApplyInPlace;
import Catalano.Imaging.Tools.ImageStatistics;
import Catalano.Statistics.Histogram;
/**
* Histogram adjust.
* Histogram adjust based on CDF.
* @author Diego Catalano
*/
public class HistogramAdjust implements IApplyInPlace{
private double tolerance;
private int min = 0;
private int max = 255;
/**
* Get the tolerance.
* @return Tolerance.
*/
public double getTolerance() {
return tolerance;
}
/**
* Set the tolerance.
* @param tolerance Tolerance.
*/
public void setTolerance(double tolerance) {
this.tolerance = tolerance;
}
/**
* Initializes a new instance of the HistogramAdjust class.
*/
public HistogramAdjust() {
this(0,255);
}
/**
* Initializes a new instance of the HistogramAdjust class.
* @param tolerance Tolerance.
*/
public HistogramAdjust(double tolerance) {
this(0,255,tolerance);
}
/**
* Initializes a new instance of the HistogramAdjust class.
* @param min Minimum value.
* @param max Maximum value.
*/
public HistogramAdjust(int min, int max){
this(min,max,0.01);
}
/**
* Initializes a new instance of the HistogramAdjust class.
* @param min Minimum value.
* @param max Maximum value.
* @param tolerance Tolerance.
*/
public HistogramAdjust(int min, int max, double tolerance){
this.min = min;
this.max = max;
this.tolerance = tolerance;
}
@Override
public void applyInPlace(FastBitmap fastBitmap) {
if(fastBitmap.isGrayscale()){
ImageStatistics stat = new ImageStatistics(fastBitmap);
int[] hist = stat.getHistogramGray().getValues();
//Compute CDF
double[] cdf = Histogram.CDF(hist);
int minV = 255;
int maxV = 0;
double maxTolerance = 1 - tolerance;
for (int i = 0; i < cdf.length; i++) {
if(cdf[i] > tolerance){
minV = i;
break;
}
}
for (int i = 0; i < cdf.length; i++) {
if(cdf[i] > maxTolerance){
maxV = i;
break;
}
}
int size = fastBitmap.getSize();
for (int x = 0; x < size; x++) {
int gray = fastBitmap.getGray(x);
double stretch = (((gray - minV)/(double)(maxV - minV)) * (double)(max - min)) + min;
fastBitmap.setGray(x, fastBitmap.clampValues((int)stretch,0,255));
}
}
else if(fastBitmap.isRGB()){
ImageStatistics stat = new ImageStatistics(fastBitmap);
int[] histR = stat.getHistogramRed().getValues();
int[] histG = stat.getHistogramGreen().getValues();
int[] histB = stat.getHistogramBlue().getValues();
//Compute CDF
double[] cdfR = Histogram.CDF(histR);
double[] cdfG = Histogram.CDF(histG);
double[] cdfB = Histogram.CDF(histB);
int minV_R = 255;
int minV_G = 255;
int minV_B = 255;
int maxV_R = 0;
int maxV_G = 0;
int maxV_B = 0;
double maxTolerance = 1 - tolerance;
for (int i = 0; i < cdfR.length; i++) {
if(cdfR[i] > tolerance){
minV_R = i;
break;
}
}
for (int i = 0; i < cdfG.length; i++) {
if(cdfG[i] > tolerance){
minV_G = i;
break;
}
}
for (int i = 0; i < cdfB.length; i++) {
if(cdfB[i] > tolerance){
minV_B = i;
break;
}
}
//Max
for (int i = 0; i < cdfR.length; i++) {
if(cdfR[i] > maxTolerance){
maxV_R = i;
break;
}
}
for (int i = 0; i < cdfG.length; i++) {
if(cdfG[i] > maxTolerance){
maxV_G = i;
break;
}
}
for (int i = 0; i < cdfB.length; i++) {
if(cdfB[i] > maxTolerance){
maxV_B = i;
break;
}
}
int size = fastBitmap.getSize();
for (int x = 0; x < size; x++) {
int r = fastBitmap.getRed(x);
int g = fastBitmap.getGreen(x);
int b = fastBitmap.getBlue(x);
int sR = fastBitmap.clampValues((int)(((r - minV_R)/(double)(maxV_R - minV_R)) * (double)(max - min)) + min,0,255);
int sG = fastBitmap.clampValues((int)(((g - minV_G)/(double)(maxV_G - minV_G)) * (double)(max - min)) + min,0,255);
int sB = fastBitmap.clampValues((int)(((b - minV_B)/(double)(maxV_B - minV_B)) * (double)(max - min)) + min,0,255);
fastBitmap.setRGB(x, sR, sG, sB);
}
}
}
}
Ads help maintain this website.