⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 histogram.java

📁 Digital Image Processing: A Practical Introduction Using Java Nick Efford
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************

  Histogram.java

  Written by Nick Efford.

  Copyright (c) 2000, Pearson Education Ltd.  All rights reserved.

  THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

***************************************************************************/


package com.pearsoneduc.ip.op;



import java.awt.image.*;
import java.io.*;



/**
 * A class which calculates the histogram of a BufferedImage, together
 * with associated statistics such as minimum and maximum values in all
 * bands, mean value in all bands, etc.
 *
 * @author Nick Efford
 * @version 1.3 [1999/06/30]
 *
 * @see java.awt.image.BufferedImage
 */

public final class Histogram implements Cloneable {


  /////////////////////////////// CONSTANTS ////////////////////////////////


  private static final String BAND_ERROR = "histogram band not specified";


  /////////////////////////// INSTANCE VARIABLES ///////////////////////////


  /**
   * Number of bands in the source image (1 for greyscale, 3 for colour).
   */

  private int bands;

  /**
   * Total number of samples processed.
   */

  private int samples;

  /**
   * 2D array holding frequency data for a greyscale or colour image.
   */

  private int[][] freq;

  /**
   * 2D array holding cumulative frequency data.
   */

  private int[][] cumFreq;

  /**
   * Array storing the minimum grey value or minimum R, G and B
   * values of the source image.
   */

  private int[] minValue;

  /**
   * Array storing the maximum grey value or maximum R, G and B
   * values of the source image.
   */

  private int[] maxValue;

  /**
   * Array storing the lowest frequencies recorded for each
   * band of the source image.
   */

  private int[] minFreq;

  /**
   * Array storing the highest frequencies recorded for each
   * band of the source image.
   */

  private int[] maxFreq;

  /**
   * Array holding the mean values for each band of the source image.
   */

  private double[] meanValue;


  ///////////////////////////// PUBLIC METHODS /////////////////////////////


  /**
   * Default constructor.
   */

  public Histogram() {
    allocateStorage();
  }

  /**
   * Constructs a histogram using a Reader as the data source.
   * @param reader the Reader used to obtain histogram data
   * @exception IOException if the input data are not formatted correctly.
   */

  public Histogram(Reader reader) throws IOException {
    allocateStorage();
    read(reader);
  }

  /**
   * Constructs the histogram of a BufferedImage.
   * @param image the image for which a histogram is required
   * @exception HistogramException if image is of wrong type.
   */

  public Histogram(BufferedImage image) throws HistogramException {
    allocateStorage();
    computeHistogram(image);
  }


  /**
   * Clones a histogram.
   */

  public Object clone() {
    Histogram h = new Histogram();
    if (samples > 0) {
      h.bands = bands;
      h.samples = samples;
      for (int i = 0; i < 3; ++i) {
        System.arraycopy(freq[i], 0, h.freq[i], 0, 256);
        System.arraycopy(cumFreq[i], 0, h.cumFreq[i], 0, 256);
      }
      System.arraycopy(minFreq, 0, h.minFreq, 0, 3);
      System.arraycopy(maxFreq, 0, h.maxFreq, 0, 3);
      System.arraycopy(minValue, 0, h.minValue, 0, 3);
      System.arraycopy(maxValue, 0, h.maxValue, 0, 3);
      System.arraycopy(meanValue, 0, h.meanValue, 0, 3);
    }
    return h;
  }


  /**
   * Tests for equivalence of Histogram objects.
   * @return true if histograms contain the same data, false otherwise.
   */

  public boolean equals(Object obj) {

    if (obj instanceof Histogram) {

      Histogram h = (Histogram) obj;
      if (bands != h.bands || samples != h.samples)
        return false;

      for (int k = 0; k < 256; ++k)
        for (int j = 0; j < bands; ++j)
          if (freq[j][k] != h.freq[j][k])
            return false;

      // Don't need to check contents of other arrays, since
      // they are derived from frequency data...

      return true;

    }
    else
      return false;

  }


  /**
   * @return a String object giving the number of bands and samples
   *   in the histogram.
   */

  public String toString() {
    return new String(getClass().getName() + ": " +
     bands + " bands, " + samples + " samples");
  }


  /**
   * Calculates histogram data for a BufferedImage.
   * @param image BufferedImage for which a histogram is required
   * @exception HistogramException if the image is of an unsupported type.
   */

  public void computeHistogram(BufferedImage image)
   throws HistogramException {

    initialize();   // zero arrays before accumulating frequency data

    if (image.getType() == BufferedImage.TYPE_BYTE_GRAY)
      bands = 1;
    else
      bands = 3;

    samples = image.getWidth()*image.getHeight();
    if (samples > 0) {
      accumulateFrequencies(image);
      computeStatistics();
    }

  }


  /**
   * Reads histogram data from the specified source.
   * @param source Reader used to obtain histogram data
   * @exception IOException if the input data are not formatted correctly.
   */

  public void read(Reader source) throws IOException {

    BufferedReader in = new BufferedReader(source);
    String line = in.readLine();

    initialize();
    if (line.equals("# grey histogram")) {       // one value per line
      bands = 1; 
      samples = 0;
      for (int i = 0; i < 256; ++i) {
        freq[0][i] = Integer.parseInt(in.readLine());
        samples += freq[0][i];
      }
      if (samples > 0)
        computeStatistics();
    }
    else if (line.equals("# RGB histogram")) {   // three values per line
      bands = 3;
      samples = 0;
      StreamTokenizer tok = new StreamTokenizer(in);
      for (int k = 0; k < 256; ++k) {
        for (int j = 0; j < 3; ++j) {
          tok.nextToken();
          if (tok.ttype == StreamTokenizer.TT_EOF)
            throw new EOFException("histogram appears to be truncated");
          if (tok.ttype == StreamTokenizer.TT_NUMBER)
            freq[j][k] = (int) tok.nval;
        }
        samples += freq[0][k];
      }
      if (samples > 0)
        computeStatistics();
    }
    else
      throw new IOException("invalid histogram file");

  }


  /**
   * Writes histogram data to the specified destination.
   * @param destination Writer used to output histogram data
   */

  public void write(Writer destination) {
    PrintWriter out =
     new PrintWriter(new BufferedWriter(destination));
    if (sourceIsGrey()) {
      out.println("# grey histogram");
      for (int i = 0; i < 256; ++i)
        out.println(freq[0][i]);         // no special formatting
    }
    else {
      out.println("# RGB histograms");
      for (int k = 0; k < 256; ++k) {
        for (int j = 0; j < 3; ++j)
          writeValue(freq[j][k], out);   // right-justified frequencies,
        out.println();                   // three values per line
      }
    }
    out.flush();
  }


  /**
   * Writes cumulative histogram data to the specified destination.
   * @param destination Writer used to output data
   */

  public void writeCumulative(Writer destination) {
    PrintWriter out =
     new PrintWriter(new BufferedWriter(destination));
    if (sourceIsGrey()) {
      out.println("# grey cumulative histogram");
      for (int i = 0; i < 256; ++i)
        out.println(cumFreq[0][i]);         // no special formatting
    }
    else {
      out.println("# RGB cumulative histograms");
      for (int k = 0; k < 256; ++k) {
        for (int j = 0; j < 3; ++j)
          writeValue(cumFreq[j][k], out);   // right-justified frequencies,
        out.println();                      // three values per line
      }
    }
    out.flush();
  }


  /**
   * Indicates whether histogram was computed from a greyscale image or not.
   * @return true if source is a greyscale image, false otherwise.
   */

  public boolean sourceIsGrey() {
    return bands == 1;
  }


  /**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -