001 /* 002 * EqualizeHistogram 003 * 004 * Copyright (c) 2001, 2002, 2003 Marco Schmidt. 005 * All rights reserved. 006 */ 007 008 package net.sourceforge.jiu.color.adjustment; 009 010 import net.sourceforge.jiu.color.analysis.Histogram1DCreator; 011 import net.sourceforge.jiu.color.data.Histogram1D; 012 import net.sourceforge.jiu.data.IntegerImage; 013 import net.sourceforge.jiu.ops.LookupTableOperation; 014 import net.sourceforge.jiu.ops.OperationFailedException; 015 016 /** 017 * Equalize the image using histogram information separately for each channel. 018 * Works for intensity-based image types like {@link net.sourceforge.jiu.data.Gray8Image} or 019 * {@link net.sourceforge.jiu.data.RGB24Image}. 020 * 021 * @author Marco Schmidt 022 * @since 0.6.0 023 */ 024 public class EqualizeHistogram extends LookupTableOperation 025 { 026 /** 027 * Creates an object of this class and initializes the lookup 028 * tables with the argument input image. 029 * @param in the input image 030 */ 031 public EqualizeHistogram(IntegerImage in) throws OperationFailedException 032 { 033 super(in.getNumChannels()); 034 setInputImage(in); 035 initTables(in); 036 } 037 038 private void initTables(IntegerImage in) throws OperationFailedException 039 { 040 for (int channelIndex = 0; channelIndex < in.getNumChannels(); channelIndex++) 041 { 042 Histogram1DCreator hc = new Histogram1DCreator(); 043 hc.setImage(in, channelIndex); 044 hc.process(); 045 Histogram1D hist = hc.getHistogram(); 046 047 final int MAX_SAMPLE = in.getMaxSample(channelIndex); 048 int[] data = new int[MAX_SAMPLE + 1]; 049 int NUM_PIXELS = in.getWidth() * in.getHeight(); 050 long sum = 0; 051 for (int i = 0; i < data.length; i++) 052 { 053 sum += hist.getEntry(i); 054 long result = sum * MAX_SAMPLE / NUM_PIXELS; 055 if (result > (long)Integer.MAX_VALUE) 056 { 057 throw new IllegalStateException("Result does not fit into an int."); 058 } 059 data[i] = (int)result; 060 } 061 setTable(channelIndex, data); 062 } 063 } 064 }