显示图像数据的直方图 [英] Displaying a histogram of image data
问题描述
我有时需要以直方图的形式显示
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
* /
公共类直方图{
private static final int BINS = 256 ;
private final BufferedImage image = getImage();
私有HistogramDataset数据集;
私有XYBarRenderer渲染器;
private BufferedImage getImage(){
try {
return ImageIO.read(new URL(
http://i.imgur.com/kxXhIH1.jpg ));
} catch(IOException e){
e.printStackTrace(System.err);
}
返回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);
//图表
JFreeChart chart = ChartFactory.createHistogram(Histogram,Value,
Count,数据集,PlotOrientation.VERTICAL,true,true,false);
XYPlot plot =(XYPlot)chart.getPlot();
renderer =(XYBarRenderer)plot.getRenderer();
renderer.setBarPainter(new StandardXYBarPainter());
//半透明的红色,绿色和& 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面板=新ChartPanel(图表);
panel.setMouseWheelEnabled(true);
返回面板;
}
私人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)));
返回面板;
}
私有类VisibleAction扩展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() ;
});
}
}
I sometimes need to display a representation of image data in the form of a histogram. I'm especially interested in ways to access the image data. I'm familiar with JFreeChart
, which includes histogram support, but I'd consider other approaches.
The example below uses several techniques to create an RGB histogram of an arbitrary image:
The
Raster
methodgetSamples()
extracts the values of each color band from theBufferedImage
.The
HistogramDataset
methodaddSeries()
adds each band's counts to thedataset
.A
StandardXYBarPainter
replaces theChartFactory
default, as shown here.A custom
DefaultDrawingSupplier
supplies the color required for each series; it contains translucent colors.A variation of
VisibleAction
, discussed here, is used to control the visibility of each band; a complementary approach usingChartMouseListener
is shown here.
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();
});
}
}
这篇关于显示图像数据的直方图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!