我有一张火星 1 的灰度图像,里面似乎混有奇数像素。
是否存在用于高亮度异常图像像素的Swing组件?如果没有,您将如何制作这样的组件?
它显示了引起我注意的火山口北唇上的斑点。以下是图像的一些变焦和裁剪,以突出3个黑点。大多数变焦显示距离较远的图像(较小),但最后一个显示双倍尺寸的部分(2倍放大)。
所有景点都位于火山口和山沟之间的边界。一个位于最后一个图像的右侧,而另外两个位于左侧。
答案 0 :(得分:3)
我使用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;
}
}
答案 1 :(得分:3)
对于另一个视图,我使用ImageJ
命令Analyze > Histogram
检查原始image。我专注于围绕异常的80 x 32像素区域;结果如下所示。使用ChartFactory.createHistogram()
呈现JFreeChart
的HistogramDataset
,如图here所示,可能是一个有用的补充。
我还使用Zoom
来检查ARGB值。最左边的一对是不透明的黑色,0xFF000000
,最右边的像素是0xFF070707
。类似的工具提示方法可能有助于显示像素值。