001/* 002Copyright 2006 Jerry Huxtable 003 004Licensed under the Apache License, Version 2.0 (the "License"); 005you may not use this file except in compliance with the License. 006You may obtain a copy of the License at 007 008 http://www.apache.org/licenses/LICENSE-2.0 009 010Unless required by applicable law or agreed to in writing, software 011distributed under the License is distributed on an "AS IS" BASIS, 012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013See the License for the specific language governing permissions and 014limitations under the License. 015*/ 016 017package com.jhlabs.image; 018 019import java.awt.*; 020import java.awt.image.*; 021 022/** 023 * An image histogram. 024 */ 025public class Histogram { 026 027 public static final int RED = 0; 028 public static final int GREEN = 1; 029 public static final int BLUE = 2; 030 public static final int GRAY = 3; 031 032 protected int[][] histogram; 033 protected int numSamples; 034 protected int[] minValue; 035 protected int[] maxValue; 036 protected int[] minFrequency; 037 protected int[] maxFrequency; 038 protected float[] mean; 039 protected boolean isGray; 040 041 public Histogram() { 042 histogram = null; 043 numSamples = 0; 044 isGray = true; 045 minValue = null; 046 maxValue = null; 047 minFrequency = null; 048 maxFrequency = null; 049 mean = null; 050 } 051 052 public Histogram(int[] pixels, int w, int h, int offset, int stride) { 053 histogram = new int[3][256]; 054 minValue = new int[4]; 055 maxValue = new int[4]; 056 minFrequency = new int[3]; 057 maxFrequency = new int[3]; 058 mean = new float[3]; 059 060 numSamples = w*h; 061 isGray = true; 062 063 int index = 0; 064 for (int y = 0; y < h; y++) { 065 index = offset+y*stride; 066 for (int x = 0; x < w; x++) { 067 int rgb = pixels[index++]; 068 int r = (rgb >> 16) & 0xff; 069 int g = (rgb >> 8) & 0xff; 070 int b = rgb & 0xff; 071 histogram[RED][r]++; 072 histogram[GREEN][g]++; 073 histogram[BLUE][b]++; 074 } 075 } 076 077 for (int i = 0; i < 256; i++) { 078 if (histogram[RED][i] != histogram[GREEN][i] || histogram[GREEN][i] != histogram[BLUE][i]) { 079 isGray = false; 080 break; 081 } 082 } 083 084 for (int i = 0; i < 3; i++) { 085 for (int j = 0; j < 256; j++) { 086 if (histogram[i][j] > 0) { 087 minValue[i] = j; 088 break; 089 } 090 } 091 092 for (int j = 255; j >= 0; j--) { 093 if (histogram[i][j] > 0) { 094 maxValue[i] = j; 095 break; 096 } 097 } 098 099 minFrequency[i] = Integer.MAX_VALUE; 100 maxFrequency[i] = 0; 101 for (int j = 0; j < 256; j++) { 102 minFrequency[i] = Math.min(minFrequency[i], histogram[i][j]); 103 maxFrequency[i] = Math.max(maxFrequency[i], histogram[i][j]); 104 mean[i] += (float)(j*histogram[i][j]); 105 } 106 mean[i] /= (float)numSamples; 107 } 108 minValue[GRAY] = Math.min(Math.min(minValue[RED], minValue[GREEN]), minValue[BLUE]); 109 maxValue[GRAY] = Math.max(Math.max(maxValue[RED], maxValue[GREEN]), maxValue[BLUE]); 110 } 111 112 public boolean isGray() { 113 return isGray; 114 } 115 116 public int getNumSamples() { 117 return numSamples; 118 } 119 120 public int getFrequency(int value) { 121 if (numSamples > 0 && isGray && value >= 0 && value <= 255) 122 return histogram[0][value]; 123 return -1; 124 } 125 126 public int getFrequency(int channel, int value) { 127 if (numSamples < 1 || channel < 0 || channel > 2 || 128 value < 0 || value > 255) 129 return -1; 130 return histogram[channel][value]; 131 } 132 133 public int getMinFrequency() { 134 if (numSamples > 0 && isGray) 135 return minFrequency[0]; 136 return -1; 137 } 138 139 public int getMinFrequency(int channel) { 140 if (numSamples < 1 || channel < 0 || channel > 2) 141 return -1; 142 return minFrequency[channel]; 143 } 144 145 146 public int getMaxFrequency() { 147 if (numSamples > 0 && isGray) 148 return maxFrequency[0]; 149 return -1; 150 } 151 152 public int getMaxFrequency(int channel) { 153 if (numSamples < 1 || channel < 0 || channel > 2) 154 return -1; 155 return maxFrequency[channel]; 156 } 157 158 159 public int getMinValue() { 160 if (numSamples > 0 && isGray) 161 return minValue[0]; 162 return -1; 163 } 164 165 public int getMinValue(int channel) { 166 return minValue[channel]; 167 } 168 169 public int getMaxValue() { 170 if (numSamples > 0 && isGray) 171 return maxValue[0]; 172 return -1; 173 } 174 175 public int getMaxValue(int channel) { 176 return maxValue[channel]; 177 } 178 179 public float getMeanValue() { 180 if (numSamples > 0 && isGray) 181 return mean[0]; 182 return -1.0F; 183 } 184 185 public float getMeanValue(int channel) { 186 if (numSamples > 0 && RED <= channel && channel <= BLUE) 187 return mean[channel]; 188 return -1.0F; 189 } 190 191 192}