显示图像数据的直方图 [英] Displaying a histogram of image data

查看:175
本文介绍了显示图像数据的直方图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有时需要以直方图的形式显示

  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 method getSamples() extracts the values of each color band from the BufferedImage.

  • The HistogramDataset method addSeries() adds each band's counts to the dataset.

  • A StandardXYBarPainter replaces the ChartFactory 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 using ChartMouseListener 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆