有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

用于突出显示异常图像像素的java Swing组件

我有一张火星1的灰度图像,里面似乎混合了奇怪的像素

高亮度异常图像像素是否有摆动组件?如果没有,你将如何制作这样一个组件


  1. 有关火星Sirenum Fossae Trough - MGS MOC Release No. MOC2-248的原始(768x1536 px)图像,请参见火星全球探测器-火星轨道器相机页面

它显示了引起我注意的陨石坑北缘的斑点。下面是一些图像的缩放和裁剪,以突出显示3个黑点。大多数缩放显示的是距离更远(更小)的图像,但最后一个缩放显示的是两倍大小(2倍放大)的区域

1/4 Zoom1/2 Zoom2 x Zoom

所有这些地点都在火山口和峡谷之间的边界上。一个在最后一张图片的右边,而另外两个在左边


共 (1) 个答案

  1. # 1 楼答案

    我会使用JTable来显示和排序像素,使用带有小半透明十字线的图像来显示所选像素。在JLabel中显示图像,有一个基本的可操作组件,可以根据需要进行定制

    结果

    所有图像都以基于浏览器的8倍缩放比例显示(FF将平滑抖动,这使线条不那么锐利,但几乎同样清晰)

    以像素x/y、RGB&;表示的信息计算该像素与周围像素之间的灰度差,并将其显示在可排序表(3200行)中

    每个标题部分都显示一个图像,以及表的前六行,指示使用的排序键和选定的行

    感兴趣的图像-未选择任何内容

    最暗的3个像素看起来很明显,没有任何进一步的提示

    X   Y   RGB     Diff.   Select
    0   0   192     20.75   -
    1   0   186     21.625  -
    2   0   174     25.625  -
    3   0   177     23.375  -
    4   0   175     24.375  -
    5   0   181     24.25   -
    6   0   189     19.75   -
    

    最暗像素

    但这里是用绿色十字线高亮度照射的最暗像素,只是为了检查我们的逻辑

    X   Y   RGB ▲   Diff.   Select
    16  25  0       240.625 TRUE
    6   30  0       240.125 TRUE
    74  7   6       230.875 TRUE
    78  31  112     37.875  -
    79  34  112     22.75   -
    75  37  115     31.375  -
    

    下一个最暗像素

    “下一个最暗”像素和它们的近邻之间的灰度差异就不那么明显了。没有最暗的3个像素那么明显

    X   Y   RGB ▲   Diff.   Select
    16  25  0       240.625 -
    6   30  0       240.125 -
    74  7   6       230.875 -
    78  31  112     37.875  TRUE
    79  34  112     22.75   TRUE
    75  37  115     31.375  TRUE
    

    第二大区别

    像素灰度的第二大差异同样难以描述。差异从200多个像素下降到不到50个像素

    X   Y   RGB     Diff. ▼ Select
    16  25  0       240.625 -
    6   30  0       240.125 -
    74  7   6       230.875 -
    37  18  205     47.875  TRUE
    31  20  209     45.375  TRUE
    59  13  196     44.875  TRUE
    

    结论

    根据数据,这3个最暗的像素似乎是异常值;反常,所以我要说“图像故障”

    密码

    这是用于显示/排序亮度的Java代码&;色差;生成图像。它与第一张裁剪过的图片进行了热链接

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.util.ArrayList;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.*;
    import javax.swing.border.LineBorder;
    import javax.swing.event.*;
    import javax.swing.table.*;
    
    import java.io.*;
    import java.net.URL;
    
    class ImageBrightnessFilter {
    
        BufferedImage bi;
        JPanel gui = null;
        ArrayList<Point> points;
        JLabel l;
    
        ImageBrightnessFilter(BufferedImage bi) {
            this.bi = bi;
        }
    
        public static double getNeighborDifference(BufferedImage bi, int x, int y) {
            Color c = new Color(bi.getRGB(x, y));
            int r = c.getRed();
    
            int tot = 0;
            for (int xx = x - 1; xx < x + 2; xx++) {
                for (int yy = y - 1; yy < y + 2; yy++) {
                    try {
                        tot += new Color(bi.getRGB(xx, yy)).getRed();
                    } catch (ArrayIndexOutOfBoundsException aioobe) {
                        tot += r;
                    }
                }
            }
    
            return (tot / 8d) - r;
        }
    
        public JPanel getGui() {
            if (gui == null) {
                gui = new JPanel(new BorderLayout(2, 2));
    
                ImageTableModel itm = new ImageTableModel(bi);
                final JTable table = new JTable(itm);
                table.setAutoCreateRowSorter(true);
                JScrollPane tableScroll = new JScrollPane(table);
                Dimension d = tableScroll.getPreferredSize();
                Dimension shortTable = new Dimension(
                        (int) d.getWidth(),
                        table.getRowHeight() * 8
                        + table.getTableHeader().getPreferredSize().height);
                tableScroll.setPreferredSize(shortTable);
                gui.add(tableScroll, BorderLayout.CENTER);
    
                l = new JLabel(
                        new ImageIcon(
                        (bi.getSubimage(0, 0, 80, 40)).getScaledInstance(640, 320, 0)));
                l.setBorder(new LineBorder(Color.BLACK));
                gui.add(l, BorderLayout.PAGE_START);
    
                ListSelectionListener lsl = new ListSelectionListener() {
    
                    @Override
                    public void valueChanged(ListSelectionEvent e) {
                        points = new ArrayList<Point>();
                        if (!e.getValueIsAdjusting()) {
                            int[] rows = table.getSelectedRows();
                            for (int row : rows) {
                                int index = row;
                                int x = (Integer) table.getValueAt(index, 0);
                                int y = (Integer) table.getValueAt(index, 1);
                                Point p = new Point(x, y);
                                points.add(p);
                            }
                        }
                        l.setIcon(new ImageIcon(getHighlightImage().getScaledInstance(640, 320, 0)));
                        l.repaint();
                    }
                };
                table.getSelectionModel().addListSelectionListener(lsl);
    
                JToolBar tb = new JToolBar();
                gui.add(tb, BorderLayout.PAGE_END);
                JButton saveImage = new JButton("Save");
                tb.add(saveImage);
                ActionListener saveListener = new ActionListener() {
    
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        String s = JOptionPane.showInputDialog(gui, "name");
                        File home = new File(System.getProperty("user.home"));
                        File f = new File(home,s + ".png");
                        try {
                            ImageIO.write(getHighlightImage(), "png", f);
                        } catch (IOException ex) {
                            Logger.getLogger(
                                    ImageBrightnessFilter.class.getName()).log(
                                    Level.SEVERE, null, ex);
                        }
                    }
                };
                saveImage.addActionListener(saveListener);
            }
    
            return gui;
    
        }
    
        public BufferedImage getHighlightImage() {
            BufferedImage b = new BufferedImage(
                    bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_ARGB);
    
            Graphics2D g = b.createGraphics();
            g.drawImage(bi, 0, 0, null);
    
            g.setColor(new Color(0, 255, 0, 95));
            if (points!=null) {
                for (Point point : points) {
                    g.drawLine(point.x - 4, point.y, point.x - 2, point.y);
                    g.drawLine(point.x + 4, point.y, point.x + 2, point.y);
                    g.drawLine(point.x, point.y - 4, point.x, point.y - 2);
                    g.drawLine(point.x, point.y + 4, point.x, point.y + 2);
                }
            }
    
            g.dispose();
    
            return b;
        }
    
        public static void main(String[] args) throws Exception {
            String s = "I:\\pics\\Space\\Stellar\\2\\MarsSthHemisphereInSpring.gif";
            File f = new File(s);
            URL url = new URL("http://i.stack.imgur.com/z8U5w.png");
            BufferedImage bi0 =
                //ImageIO.read(f);
                ImageIO.read(url);
            final BufferedImage bi =
                //bi0.getSubimage(160, 799, 80, 40);
                bi0;
            Runnable r = new Runnable() {
    
                @Override
                public void run() {
                    ImageBrightnessFilter ibf = new ImageBrightnessFilter(bi);
                    JOptionPane.showMessageDialog(null, ibf.getGui());
                }
            };
            SwingUtilities.invokeLater(r);
        }
    }
    
    class ImageTableModel extends DefaultTableModel {
    
        BufferedImage bi;
        final static String[] columnName = {
            "X",
            "Y",
            "RGB",
            "Diff"
        };
    
        public ImageTableModel(BufferedImage bi) {
            super();
            this.bi = bi;
        }
    
        @Override
        public Object getValueAt(final int rowIndex, final int columnIndex) {
            Object o = null;
            int x = rowIndex % bi.getWidth();
            int y = rowIndex / bi.getWidth();
            int rgb = bi.getRGB(x, y);
            Color c = new Color(rgb);
            int r = c.getRed();
            switch (columnIndex) {
                case 0:
                    o = new Integer(x);
                    break;
                case 1:
                    o = new Integer(y);
                    break;
                case 2:
                    o = new Integer(r);
                    break;
                case 3:
                    o = new Double(ImageBrightnessFilter.getNeighborDifference(
                            bi, x, y));
                    break;
                default:
                    return null;
            }
            return o;
        }
    
        @Override
        public Class<?> getColumnClass(int columnIndex) {
            switch (columnIndex) {
                case 0:
                case 1:
                case 2:
                    return Integer.class;
                case 3:
                    return Double.class;
                default:
                    return null;
            }
        }
    
        @Override
        public int getColumnCount() {
            return columnName.length;
        }
    
        @Override
        public String getColumnName(int columnIndex) {
            return columnName[columnIndex];
        }
    
        @Override
        public int getRowCount() {
            if (bi == null) {
                return 80 * 40;
            }
            return bi.getHeight() * bi.getWidth();
        }
    
        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return false;
        }
    }