Java显示图像数据的直方图

有时我需要以直方图的形式显示图像数据的表示形式。我对访问图像数据的方式特别感兴趣。我熟悉JFreeChart,其中包括直方图支持,但我会考虑其他方法。

回答:

下面的示例使用多种技术来创建任意图像的RGB直方图:

  • Raster方法getSamples()从中提取每个色带的值BufferedImage。

  • HistogramDataset方法addSeries()将每个频段的计数添加到dataset

  • 一个StandardXYBarPainter替换ChartFactory默认,如图所示这里。

  • 定制DefaultDrawingSupplier提供每个系列所需的颜色;它包含半透明的颜色。

  • 一种变型VisibleAction,讨论在这里,用于控制每个带的可见性; 这里ChartMouseListener显示了一种补充方法。

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.EventQueue;

import java.awt.Paint;

import java.awt.event.ActionEvent;

import java.awt.image.BufferedImage;

import java.awt.image.Raster;

import java.io.IOException;

import java.net.URL;

import javax.imageio.ImageIO;

import javax.swing.AbstractAction;

import javax.swing.ImageIcon;

import javax.swing.JCheckBox;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;

import org.jfree.chart.ChartPanel;

import org.jfree.chart.JFreeChart;

import org.jfree.chart.plot.DefaultDrawingSupplier;

import org.jfree.chart.plot.PlotOrientation;

import org.jfree.chart.plot.XYPlot;

import org.jfree.chart.renderer.xy.StandardXYBarPainter;

import org.jfree.chart.renderer.xy.XYBarRenderer;

import org.jfree.data.statistics.HistogramDataset;

/**

* @see https://stackoverflow.com/q/40537278/230513

* @see https://stackoverflow.com/q/11870416/230513

* @see https://stackoverflow.com/a/28519356/230513

*/

public class Histogram {

private static final int BINS = 256;

private final BufferedImage image = getImage();

private HistogramDataset dataset;

private XYBarRenderer renderer;

private BufferedImage getImage() {

try {

return ImageIO.read(new URL(

"http://i.imgur.com/kxXhIH1.jpg"));

} catch (IOException e) {

e.printStackTrace(System.err);

}

return null;

}

private ChartPanel createChartPanel() {

// dataset

dataset = new HistogramDataset();

Raster raster = image.getRaster();

final int w = image.getWidth();

final int h = image.getHeight();

double[] r = new double[w * h];

r = raster.getSamples(0, 0, w, h, 0, r);

dataset.addSeries("Red", r, BINS);

r = raster.getSamples(0, 0, w, h, 1, r);

dataset.addSeries("Green", r, BINS);

r = raster.getSamples(0, 0, w, h, 2, r);

dataset.addSeries("Blue", r, BINS);

// chart

JFreeChart chart = ChartFactory.createHistogram("Histogram", "Value",

"Count", dataset, PlotOrientation.VERTICAL, true, true, false);

XYPlot plot = (XYPlot) chart.getPlot();

renderer = (XYBarRenderer) plot.getRenderer();

renderer.setBarPainter(new StandardXYBarPainter());

// translucent red, green & blue

Paint[] paintArray = {

new Color(0x80ff0000, true),

new Color(0x8000ff00, true),

new Color(0x800000ff, true)

};

plot.setDrawingSupplier(new DefaultDrawingSupplier(

paintArray,

DefaultDrawingSupplier.DEFAULT_FILL_PAINT_SEQUENCE,

DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE,

DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE,

DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE,

DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE));

ChartPanel panel = new ChartPanel(chart);

panel.setMouseWheelEnabled(true);

return panel;

}

private JPanel createControlPanel() {

JPanel panel = new JPanel();

panel.add(new JCheckBox(new VisibleAction(0)));

panel.add(new JCheckBox(new VisibleAction(1)));

panel.add(new JCheckBox(new VisibleAction(2)));

return panel;

}

private class VisibleAction extends AbstractAction {

private final int i;

public VisibleAction(int i) {

this.i = i;

this.putValue(NAME, (String) dataset.getSeriesKey(i));

this.putValue(SELECTED_KEY, true);

renderer.setSeriesVisible(i, true);

}

@Override

public void actionPerformed(ActionEvent e) {

renderer.setSeriesVisible(i, !renderer.getSeriesVisible(i));

}

}

private void display() {

JFrame f = new JFrame("Histogram");

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.add(createChartPanel());

f.add(createControlPanel(), BorderLayout.SOUTH);

f.add(new JLabel(new ImageIcon(image)), BorderLayout.WEST);

f.pack();

f.setLocationRelativeTo(null);

f.setVisible(true);

}

public static void main(String[] args) {

EventQueue.invokeLater(() -> {

new Histogram().display();

});

}

}

以上是 Java显示图像数据的直方图 的全部内容, 来源链接: utcz.com/qa/431279.html

回到顶部