我正在为一个新程序而苦苦挣扎。
该程序旨在从网络摄像头获取光谱,并将其与参考光谱进行比较。这是在用户单击一个名为"captureButton"的按钮时完成的。
操作结束时,程序在消息对话框中显示频谱图(通过Scilab通过批处理文件从外部创建(。这一切都如预期的那样完美地发生了。但是,如果再次运行该操作(再次按下按钮(,该过程会正常进行,但消息对话框中显示的图像是上次运行的旧图像。
尽管在操作开始时,所有旧文件都会被擦除,然后使用新数据重新创建,但还是会发生这种情况。
然后我怀疑旧图像是以某种方式存储在内存中的,而不是第二次从新文件中调用。
我尝试过请求垃圾收集器,但没有效果。
这是代码(我已经删除了不相关的片段,因为这是一个相当长的代码(。。。
//Imports etc here
public class VSAWindow extends javax.swing.JFrame {
public VSAWindow() {
initComponents();
//Set defaults for user input
sampleText.setText("50");
toleranceText.setText("1");
acceptanceText.setText("10");
//Clear Calibration window and set calibration spectrum image
jLabel10.setText("");
jLabel11.setText("");
ImageIcon icon = new ImageIcon("reference/mainspectrum.png");
jLabel10.setIcon(icon);
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
captureButton = new javax.swing.JButton();
// Some other declarations...
jButton1 = new javax.swing.JButton();
calibrateButton = new javax.swing.JButton();
jLabel10 = new javax.swing.JLabel();
jLabel11 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
captureButton.setText("Capture");
captureButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
captureButtonActionPerformed(evt);
}
});
//Some code which sets a load of text on screen...
jButton1.setText("EXIT");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jLabel10.setText("jLabel10");
jLabel11.setText("jLabel11");
//A load of code added by the IDE for adding various components
private void captureButtonActionPerformed(java.awt.event.ActionEvent evt) {
//CLEAR ALL PREVIOUS IF POSSIBLE
System.gc();
//Check user input values for validity
try {
String smpIn = sampleText.getText();
String tolIn = toleranceText.getText();
String accIn = acceptanceText.getText();
int smpVl = Integer.parseInt(smpIn);
double tolVl = Integer.parseInt(tolIn);
int accVl = Integer.parseInt(accIn);
int stopgo = 0; //Condition variable to prevent invalid operation
if (smpVl >= 0 && smpVl <= 766 && tolVl >= 0 && tolVl <= 100 && accVl >= 0 && accVl <= 100) {
stopgo = 1;
}
if (stopgo == 1) {//Proceed if input values have been checked for validity
try {
//BEFORE BEGINNING CLEAR ALL FILES FROM PREVIOUS RUNS
//This will prevent old data from being displayed in
//the event of system slowdown
File del1 = new File("convert.bat");
File del2 = new File("inplot.png");
File del3 = new File("newdata.csv");
File del4 = new File("peakdata.csv");
File del5 = new File("peaks.sce");
File del6 = new File("refbat.bat");
File del7 = new File("refplot.png");
File del8 = new File("rgb.sce");
File del9 = new File("rgbbat.bat");
File del10 = new File("test.png");
File del11 = new File("spectra\newspectrum.ppm");
File del12 = new File("spectra\convspectrum.doc");
del1.delete();
del2.delete();
del3.delete();
del4.delete();
del5.delete();
del6.delete();
del7.delete();
del8.delete();
del9.delete();
del10.delete();
del11.delete();
del12.delete();
//CAPTURE SPECTRUM IMAGE
Webcam webcam = Webcam.getDefault();
Dimension size = new Dimension(640, 480);
webcam.setViewSize(size);
webcam.open();
BufferedImage image = webcam.getImage();
try {
ImageIO.write(image, "PNG", new File("test.png"));
} catch (IOException ex) {
Logger.getLogger(VSAWindow.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Obtaining data from spectrometer...");
//CREATE BATCH FILE FOR IMAGE CONVERSION TO .PPM FORMAT
String filename = "convert.bat";
WriteFile data = new WriteFile(filename, false);
WriteFile dataline = new WriteFile(filename, true);
data.WriteToFile("cd "C:\Program Files (x86)\IrfanView"");
dataline.WriteToFile("i_view32.exe C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser\test.png /convert=C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser\spectra\newspectrum.ppm");
dataline.WriteToFile("exit");
//Wait for processes to finish...
File f = new File("test.png");
int msgCheck = 0;//Variable to prevent repeated i/o
while (!f.exists()) {
if (msgCheck == 0) {
System.out.println("Building spectral data...");
}
msgCheck = 1;
}
//Shuts webcam and proceeds as long as input has been obtained
webcam.close();
//EXECUTE CONVERSION BATCH FILE
Runtime.getRuntime().exec("cmd /c start convert.bat");
//CONVERSION BY TO LINE BY LINE FORMAT - NEEDS STREAMLINING SOMEHOW
//Wait for file to be created:
File fn = new File("spectra\newspectrum.ppm");
int msgCheck2 = 0;//Variable to prevent repeated i/o
while (!fn.exists()) {
if (msgCheck2 == 0) {
System.out.println("Performing file operations....");
}
msgCheck2 = 1;
}//Proceeds once file has been converted and placed in 'spectra' folder
//Open file for format conversion
ReadFile open = new ReadFile("C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser\spectra\newspectrum.ppm");
String[] readLines;
readLines = open.OpenFile();
//Prepare Writefile
WriteFile begin = new WriteFile("C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser\spectra\convspectrum.doc", false);
begin.WriteToFile("");
//Create file append code
WriteFile write = new WriteFile("C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser\spectra\convspectrum.doc", true);
//Begin looping and adding to new file
String columns = readLines[2].split("\ ")[0];
int nos = Integer.parseInt(columns);
for (int i = 0; i < readLines.length; i++) {
if (i < 4) {
write.WriteToFile(readLines[i]);
} else if (i == 2) {
//Splits condensed data and rebuilds as line-by-line format
} else if (i >= 4 && i < nos) {
String[] lnMk = readLines[i].split("[\W]");
for (int j = 0; j < lnMk.length; j++) {
write.WriteToFile(lnMk[j]);
}
}
}
//BEGIN DATA ANALYSIS
//FILE READING PROCEDURE
ReadFile file = new ReadFile("spectra/convspectrum.doc");//Read in filename to be opened
String aryLines[];//Declare string array for file contents in line by line read
aryLines = file.OpenFile();//Read file line by line and assign each line to a sequential array index
//DECLARE VARIABLES
String beforeSpc = aryLines[3].split("\ ")[0];
System.out.println("Number of columns = " + beforeSpc);
int docWidth = Integer.parseInt(beforeSpc);//Gets spectrum width from file header
int rgbCount = 0;//Index for counting final RGB indices
int sample = smpVl;//Declares lower limit for sampling (Sample = r+g+b)(min=0, max = 765)
String[] rgbArray = new String[aryLines.length];//Declare array for storage of final RGB values
//CREATE CSV FILE FOR SCILAB - INPUT SPECTRUM
WriteFile newData = new WriteFile("newdata.csv", false);
newData.WriteToFile("");
//CREATE SCILAB SCRIPT FILE - INPUT SPECTRUM
WriteFile createSciRGB = new WriteFile("rgb.sce", false);
createSciRGB.WriteToFile("");
//CONFIGURE SCILAB SCRIPT FOR RGB DATA - INPUT SPECTRUM
WriteFile addSciRGB = new WriteFile("rgb.sce", true);
addSciRGB.WriteToFile("cd("C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser");");
addSciRGB.WriteToFile("y = evstr(read_csv("newdata.csv"));");
addSciRGB.WriteToFile("xlabel("Wavelength (nm)")");
addSciRGB.WriteToFile("ylabel("Intesity (Combined RGB Value)")");
addSciRGB.WriteToFile("plot2d(y)");
addSciRGB.WriteToFile("xs2png(0, "inplot.png" )");
addSciRGB.WriteToFile("exit");
//CREATE BATCH FILE FOR RUNNING SCILAB (RGB INPUT SPECTRUM)
WriteFile rgbBat = new WriteFile("rgbbat.bat", false);
rgbBat.WriteToFile(""C:/Program Files/scilab-5.5.0/bin/Scilex.exe" scilab-adv-cli -f "rgb.sce" -nw");
WriteFile addRgbBat = new WriteFile("rgbbat.bat", true);
addRgbBat.WriteToFile("exit");
//BEGIN LOOPING THROUGH INPUT FILE
for (int i = 0; i < 3 * docWidth; i++) {//Restricts loop to single line by stopping after 1x width of sample spectrum
//System.out.println(aryLines[i]);
if (i >= 6 && i % 3 == 0) {
//ASSIGN R,G,B VALUES
int r = Integer.parseInt(aryLines[i - 2]);
int g = Integer.parseInt(aryLines[i - 1]);
int b = Integer.parseInt(aryLines[i]);
int dataR = Integer.parseInt(aryLines[i - 2]);
int dataG = Integer.parseInt(aryLines[i - 1]);
int dataB = Integer.parseInt(aryLines[i]);
int lineSpec = dataR + dataG + dataB;
String dataPoint = Integer.toString(lineSpec);
//ADD RGB DATA TO SCILAB FILE - INPUT SPECTRUM
WriteFile peaks = new WriteFile("newdata.csv", true);
peaks.WriteToFile(dataPoint);
int pixSum = r + g + b;//Creates measure of pixel significance
if (pixSum > sample) {
rgbArray[rgbCount] = aryLines[i - 2] + " " + aryLines[i - 1] + " " + aryLines[i];
rgbCount++;
}
}
}
//OUTPUT ARRAY OF FINAL RGB VALUES
for (int j = 0; j < rgbArray.length; j++) {
if (rgbArray[j] != null) {
System.out.println(rgbArray[j]);
}
}
//END COLLECTION OF INPUT DATA
//BEGIN CREATION OF COMPARISON DATA
//FILE READING PROCEDURE FOR REFERENCE SPECTRUM
ReadFile specFile = new ReadFile("reference/mainspectrum.ppm");//Read in filename to be opened
String specLines[];//Declare string array for file contents in line by line read
specLines = specFile.OpenFile();//Read file line by line and assign each line to a sequential array index
//DECLARE VARIABLES
String specBeforeSpc = specLines[2].split("\ ")[0];//Gets spectrum width from file header
System.out.println("Number of columns = " + specBeforeSpc);
int specWidth = Integer.parseInt(specBeforeSpc);
int specCount = 0;//Index for counting reference RGB indices
String[] specArray = new String[specWidth];//Declare array for storage of reference RGB values
//CREATE CSV FILE FOR SCILAB - REFERENCE SPECTRUM
WriteFile stFile = new WriteFile("peakdata.csv", false);//Creates and clears file for line spectrum data
stFile.WriteToFile("");
//CREATE SCILAB SCRIPT FILE - REFERENCE SPECTRUM
WriteFile createSciSpec = new WriteFile("peaks.sce", false);
createSciSpec.WriteToFile("");
//CONFIGURE SCILAB SCRIPT FOR RGB DATA - REFERENCE SPECTRUM
WriteFile addSciSpec = new WriteFile("peaks.sce", true);
addSciSpec.WriteToFile("cd("C:\Users\Guy\Documents\NetBeansProjects\VSpecAnalyser");");
addSciSpec.WriteToFile("y = evstr(read_csv("peakdata.csv"));");
addSciSpec.WriteToFile("xlabel("Wavelength (nm)")");
addSciSpec.WriteToFile("ylabel("Intesity (Combined RGB Value)")");
addSciSpec.WriteToFile("plot2d(y)");
addSciSpec.WriteToFile("xs2png(0, "refplot.png" )");
addSciSpec.WriteToFile("exit");
//CREATE BATCH FILE FOR RUNNING SCILAB (REFERENCE SPECTRUM)
WriteFile refBat = new WriteFile("refbat.bat", false);
refBat.WriteToFile(""C:/Program Files/scilab-5.5.0/bin/Scilex.exe" scilab-adv-cli -f "peaks.sce" -nw");
WriteFile addRefBat = new WriteFile("refbat.bat", true);
addRefBat.WriteToFile("exit");
//BEGIN LOOPING THROUGH SPECTRUM REFERENCE FILE
for (int i = 0; i < 3 * specWidth; i++) {//Restricts loop to single line by stopping after 1x width of reference spectrum
//Eliminate header and compress RGB lines into single, 3 point entries
if (i >= 6 && i % 3 == 0) {
//ASSIGN R,G,B VALUES TO REFERENCE SPECTRUM ARRAY
specArray[specCount] = specLines[i - 2] + " " + specLines[i - 1] + " " + specLines[i];
specCount++;
int dataR = Integer.parseInt(specLines[i - 2]);
int dataG = Integer.parseInt(specLines[i - 1]);
int dataB = Integer.parseInt(specLines[i]);
int lineSpec = dataR + dataG + dataB;
String dataPoint = Integer.toString(lineSpec);
//ADD DATA TO SCILAB FILE - REFERENCE SPECTRUM
WriteFile peaks = new WriteFile("peakdata.csv", true);
peaks.WriteToFile(dataPoint);
}
}
System.out.println("Reference Spectrum Obtained");
//COMPARE INPUT AND REFERENCE SPECTRA
//Set matching tolerance:
double tol = (765 / 100) * tolVl;
//Set lower threshold for partial matches
int disp = 100 - accVl;
//Find length of input RGB input array to prevent null pointers
int rgbLength = 0;
//Declare null variables for match counts
int matchCount = 0;
int perfCount = 0;
int possCount = 0;
//Determine length of RGB Input data array
for (int x = 0; x < rgbArray.length; x++) {
if (rgbArray[x] != null) {
rgbLength++;
}
}
//BEGIN COMPARISON
//Check each input RGB value...
for (int l = 0; l < rgbLength; l++) {
String[] colours = rgbArray[l].split(" ");
String sred = colours[0];
String sgreen = colours[1];
String sblue = colours[2];
int red = Integer.parseInt(sred);
int green = Integer.parseInt(sgreen);
int blue = Integer.parseInt(sblue);
//...against each reference value
for (int m = 0; m < specArray.length - 2; m++) {
String[] cols = specArray[m].split(" ");
String sr = cols[0];
String sg = cols[1];
String sb = cols[2];
int r = Integer.parseInt(sr);
int g = Integer.parseInt(sg);
int b = Integer.parseInt(sb);
double wavelength = 380 + m / 3;
//Identify perfect matches
if (red == r && green == g && blue == b) {
perfCount++;
matchCount++;
System.out.println("PERFECT MATCH! Found at " + m + " of reference and " + l + " of input");
//Some code to output results
//Identify imperfect matches based on tolerance
} else if (red - r < tol && green - g < tol && blue - b < tol && red - r > -tol && green - g > -tol && blue - b > -tol) {
//Calculate possible matches regardless of parameters
possCount++;
//CALCULATE MATCH QUALITY
//Initialise variables
double rperc = 100;
double gperc = 100;
double bperc = 100;
double tperc = 100;
//Provide conditions
if (red > r) {
rperc = (100 / (double) red) * (double) r;
} else if (red < r) {
rperc = (100 / (double) r) * (double) red;
}
if (green > g) {
gperc = (100 / (double) green) * (double) g;
} else if (green < g) {
gperc = (100 / (double) g) * (double) green;
}
if (blue > b) {
bperc = (100 / (double) blue) * (double) b;
} else if (blue < b) {
bperc = (100 / (double) b) * (double) blue;
}
//Small discrepancies involving zero values are automatically given a 95% quality rating
if (r == 0 || red == 0) {
rperc = 95;
}
if (g == 0 || green == 0) {
gperc = 95;
}
if (b == 0 || blue == 0) {
bperc = 95;
}
if (red == r) {
rperc = 100;
}
if (green == g) {
gperc = 100;
}
if (blue == b) {
bperc = 100;
}
double tot = (tperc / 300) * (rperc + gperc + bperc);
//Check whether available matches are within specified range
if (tot > disp) {
matchCount++;
//Display Match parameters
System.out.println("Partial MATCH! Found at " + m + " of reference and " + l + " of input");
//Some more code to output results
//Calculate and display final quality value and breakdown
System.out.println("Match Quality: " + tot + "% (R: " + rperc + " G: " + gperc + " B: " + bperc);
}
}
}
}
//More results
//CHECK THAT BATCH FILES FOR PLOTTING EXIST
File chkrgb = new File("rgbbat.bat");
File chkref = new File("refbat.bat");
while (!chkrgb.exists()) {
//Do nothing, just wait
}
while (!chkref.exists()) {
//Do nothing, just wait
}
//PRODUCE SCILAB PLOTS FOR BOTH REFERENCE AND INPUT SPECTRA
Runtime.getRuntime().exec("cmd /c start refbat.bat");
Runtime.getRuntime().exec("cmd /c start rgbbat.bat");
//CHECK PNG PLOTS HAVE BEEN GENERATED
File chkrgbpng = new File("inplot.png");
File chkrefpng = new File("refplot.png");
while (!chkrgbpng.exists()) {
System.out.println("Loading RGB Plot...");
Thread.sleep(2000);
}
while (!chkrefpng.exists()) {
System.out.println("Loading Reference Plot...");
Thread.sleep(2000);
}
//PLACE RGB PLOT IN WINDOW
System.out.println("Setting plot to screen...");
ImageIcon icon2 = new ImageIcon("inplot.png");
String msgTitle = "";
String msgCaption = "Wavelength in nm";
JOptionPane.showMessageDialog(null, msgCaption, msgTitle, JOptionPane.INFORMATION_MESSAGE, icon2);
} catch (IOException ex) {
Logger.getLogger(VSAWindow.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
JOptionPane.showMessageDialog(null, "Please select valid input values!");
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(VSAWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new VSAWindow().setVisible(true);
}
});
}
// Variables declaration - do not modify
// End of variables declaration
}
有问题的图像是"icon2",位于代码末尾附近,注释"//在窗口中放置RGB绘图"下方,即:
System.out.println("Setting plot to screen...");
ImageIcon icon2 = new ImageIcon("inplot.png");
String msgTitle = "";
String msgCaption = "Wavelength in nm";
JOptionPane.showMessageDialog(null, msgCaption, msgTitle, JOptionPane.INFORMATION_MESSAGE, icon2);
我在Windows8.1上的Netbeans 8中工作。
为什么系统会记住上一次运行中的图像,我该如何停止?
非常感谢,并对代码的长度表示歉意,我不想遗漏任何可能导致此问题的内容。如果我能以任何方式改进这个问题,请让我知道,这样我就可以防止自己被屏蔽!
首选的解决方案是使用ImageIO.read
而不是ImageIcon(String)
,但如果必须这样做,则应在尝试重新加载之前调用icon2.flush()
。
有关更多详细信息,请参阅Image#flush
和读取/加载图像