Вся моя проблема в этой части (закрытый класс IconButtonHandler). Как получить все кадры для воспроизведения в одном кадре? Я устал создавать один jframe в классе, а затем добавлять к нему значки изображений внутри камеры с надписью l oop, однако jframe остается белым и показывает только последний кадр. Кто-нибудь может помочь?
class VideoDecoder {
int frame_number;
int frames_per_second;
int video_length;
String videoFilename;
VideoCapture camera;
int intensityBins[] = new int[25];
int intensityMatrix[][];
double distance[];
double ts;
double tb;
int tor = 2;
public VideoDecoder(String videoFilename) {
this.videoFilename = videoFilename;
}
public void initialize() {
if (!Paths.get(this.videoFilename).toFile().exists()) {
System.out.println("File " + this.videoFilename + " does not exist!");
return;
}
camera = new VideoCapture(this.videoFilename);
if (!camera.isOpened()) {
System.out.println("Error! Camera can't be opened!");
return;
} else {
video_length = (int) camera.get(Videoio.CAP_PROP_FRAME_COUNT);
frames_per_second = (int) camera.get(Videoio.CAP_PROP_FPS);
frame_number = (int) camera.get(Videoio.CAP_PROP_POS_FRAMES);
}
}
public void seek(int i) {
camera.set(Videoio.CAP_PROP_POS_FRAMES, i);
frame_number = (int) camera.get(Videoio.CAP_PROP_POS_FRAMES);
}
public void getIntensity(BufferedImage image, int height, int width, int imageCount) {
for (int x = 0; x < width; x = x + 1) { // nested for loop to go over each pixel in each image, going over width
for (int y = 0; y < height; y = y + 1) { // going over height
Color mycolor = new Color(image.getRGB(x, y)); // get RGB values in a new color object
double I = (0.299 * mycolor.getRed()) + (0.587 * mycolor.getGreen()) + (0.114 * mycolor.getBlue()); // calculate the
//intensity of the pixel as per the equation in the assignment
//System.out.println("Intensity is " + I + " for x=" + x + " and y=" + y); // print the intensity of each pixel
if (I <= 10) { // if statements to create the intinsity bins, increement the bin value if the intensity falls into the bin intensity range
intensityBins[0]++;
} else if (I <= 20) {
intensityBins[1]++;
} else if (I <= 30) {
intensityBins[2]++;
} else if (I <= 40) {
intensityBins[3]++;
} else if (I <= 50) {
intensityBins[4]++;
} else if (I <= 60) {
intensityBins[5]++;
} else if (I <= 70) {
intensityBins[6]++;
} else if (I <= 80) {
intensityBins[7]++;
} else if (I <= 90) {
intensityBins[8]++;
} else if (I <= 100) {
intensityBins[9]++;
} else if (I <= 110) {
intensityBins[10]++;
} else if (I <= 120) {
intensityBins[11]++;
} else if (I <= 130) {
intensityBins[12]++;
} else if (I <= 140) {
intensityBins[13]++;
} else if (I <= 150) {
intensityBins[14]++;
} else if (I <= 160) {
intensityBins[15]++;
} else if (I <= 170) {
intensityBins[16]++;
} else if (I <= 180) {
intensityBins[17]++;
} else if (I <= 190) {
intensityBins[18]++;
} else if (I <= 200) {
intensityBins[19]++;
} else if (I <= 210) {
intensityBins[20]++;
} else if (I <= 220) {
intensityBins[21]++;
} else if (I <= 230) {
intensityBins[22]++;
} else if (I <= 240) {
intensityBins[23]++;
} else if (I <= 255) {
intensityBins[24]++;
}
}
}
for (int p = 0; p < 25; p++) { // for loop to copy the array into the intensity matrix
intensityMatrix[imageCount][p] = intensityBins[p]; // copy the intensity bin array for the current image to its row in the bigger intensity matrix
intensityBins[p] = 0; // reset the intensity matrix before running sgain on the next image
}
}
public void getIntensityMatrix(int startFrame, int endFrame) {
this.intensityMatrix = new int[(endFrame - 1000) + 1][25];
Mat frame = new Mat();
while (camera.read(frame)) //the last frame of the movie will be invalid. check for it !
{
try {
BufferedImage image;
if (frame_number >= 1000 && frame_number <= endFrame) {
Imgcodecs.imwrite("x.jpg", frame);
image = ImageIO.read(new File("x.jpg")); // read each image sequential
int width = image.getWidth(); // get picture width to be used at getIntensity and getcolorCode functions
int height = image.getHeight();
getIntensity(image, height, width, frame_number - 1000);
frame_number++;
} else {
break;
}
} catch (IOException e) {
System.out.println("Error occurred when reading the file."); // printed if an exception is caught
}
}
}
public double getStandardDeviation(double[] distArray) {
int rows = distArray.length;
//System.out.println("rows in STD function is " + rows);
int columns = distArray.length;
//double[] average = new double[columns];
double average = getAverage(distArray);
double std = 0;
double stdd = 0;
for (int p = 0; p < columns; p++) {
stdd += Math.pow((distArray[p] - average), 2); // calculate the standard deviation
}
std = Math.sqrt(stdd / (rows - 1));
System.out.println("std is " + std);
return std;
}
public double calculateSD(double distArray[]) {
double sum = 0.0, standardDeviation = 0.0;
int length = distArray.length;
for (double num : distArray) {
sum += num;
}
double mean = sum / length;
for (double num : distArray) {
standardDeviation += Math.pow(num - mean, 2);
}
System.out.println("StandardDev is " + Math.sqrt(standardDeviation / length));
return Math.sqrt(standardDeviation / length);
}
public double getAverage(double[] distArray) {
int columns = distArray.length;
double average = 0;
double sum = 0;
for (int p = 0; p < columns; p++) {
sum += distArray[p];
}
average = sum / columns;
return average;
}
public double getTb() {
double Tb = 0;
Tb = getAverage(distance) + getStandardDeviation(distance) * 11;
System.out.println("Tb is " + Tb);
return Tb;
}
public double getTs() {
double Ts = 0;
Ts = getAverage(distance) * 2;
System.out.println("Ts is " + Ts);
return Ts;
}
public void identifyCuts(double[] distArray) {
int columns = distArray.length;
double tb = this.getTb();
double ts = this.getTs();
boolean potentialStartFound = false;
boolean oneLessThanTsFound = false;
int Ce = 0 + 1000;
int Cs = 0 + 1000;
int FsCandi = 0 + 1000;
int FeCandi = 0 + 1000;
for (int p = 0; p < columns; p++) {
if (distArray[p] > tb) {
Cs = p + 1000;
Ce = p + 1000 + 1;
System.out.println("There is a cut start at " + Cs);
System.out.println("There is a cut end at " + Ce);
}
}
}
public ArrayList<Integer> getListGradualTransition(double[] distArray) {
ArrayList<Integer> gradualTransitionList = new ArrayList<Integer>();
int columns = distArray.length;
this.tb = this.getTb();
this.ts = this.getTs();
int counter = tor;
boolean potentialStartFound = false;
int Ce = 1000;
int Cs = 1000;
int FsCandiInitial = 1000;
int FeCandiInitial = 1000;
int FeCandi = 1000;
int FsCandi = 1000;
double sum = 0;
System.out.println("Columns is " + columns);
System.out.println("tor is " + counter);
for (int p = 0; p <= columns; p++) {
if (p == columns) {
if (counter == 0) {
FeCandi = FeCandiInitial + p - tor - 1;
if (sum > tb && potentialStartFound == true) {
System.out.println("Fs+1 is " + FsCandi + " and Found a real end for the Candidate Start at " + FeCandi);
gradualTransitionList.add(FsCandi);
gradualTransitionList.add(FeCandi);
}
} else {
System.out.println("Hit the end of distance Array");
}
} else if (distArray[p] > ts && distArray[p] < tb && potentialStartFound == false) {
FsCandi = FsCandiInitial + p;
potentialStartFound = true;
counter = tor;
sum = sum + distArray[p];
continue;
} else if ((distArray[p] > tb) && potentialStartFound == true) {
if (distArray[p - 1] < ts) { // needs to be a for loop to go back tor times and check if any values are less than ts
sum = sum - distArray[p - 1];
FeCandi = FeCandiInitial + p - 2;
} else {
FeCandi = FeCandiInitial + p - 1; // not sure if -1 or -2
}
if (sum > tb && potentialStartFound == true) {
FsCandi = FsCandi + 1;
System.out.println("Fs+1 is " + FsCandi + " and Found a real end for the Candidate Start at " + FeCandi);
gradualTransitionList.add(FsCandi);
gradualTransitionList.add(FeCandi);
}
potentialStartFound = false;
sum = 0;
} else if (distArray[p] < ts && potentialStartFound == true) {
sum = sum + distArray[p];
counter--;
if (counter == 0) {
FeCandi = FeCandiInitial + p - tor;
sum = sum - distArray[p];
if (distArray[p - 1] < ts) {
sum = sum - distArray[p - 1];
FeCandi = FeCandi - 1;
}
if (sum > tb && potentialStartFound == true) {
FsCandi = FsCandi + 1;
System.out.println("Fs+1 is " + FsCandi + " and Found a real end for the Candidate Start at " + FeCandi);
gradualTransitionList.add(FsCandi);
gradualTransitionList.add(FeCandi);
}
potentialStartFound = false;
sum = 0;
}
} else if (distArray[p] > ts && potentialStartFound == true && counter >= 1) {
sum = sum + distArray[p];
if (distArray[p] > ts) {
//System.out.println("resetting tor");
counter = tor;
}
}
}
return gradualTransitionList;
}
public class Video extends JFrame {
private JLabel photographLabel = new JLabel(); // new jlabel
private JButton[] button; //creates an array of JButtons for images
private int[] buttonOrder = new int[101]; //creates an array to keep up with the image order
private int[] selectedImages = new int[99];
private double[] imageSize = new double[100]; //keeps up with the image sizes
private GridLayout gridLayout1;
private GridLayout gridLayout2;
private GridLayout gridLayout3;
private GridLayout gridLayout4;
private JPanel panelBottom1;
private JPanel panelBottom2;
private JPanel panelTop;
private JPanel buttonPanel;
private double[][] colorCodeIntensityMatrix = new double[100][89];
//private Map<Double, LinkedList<Integer>> map;
int picNo = 0; // variable to hold the pic/image index
int imageCount = 1; //keeps up with the number of images displayed since the first page.
int selectedImagesIndex;
int pageNo = 1; // variable to hold the page number
int iteration = -1;
JButton previousPage;
JButton nextPage;
JCheckBox checkbox; // relevance feedback check box
JCheckBox iconCheckBox; // check box for each image in the first page
VideoDecoder vdec;
ArrayList<Integer> gradualTransitionList = new ArrayList<Integer>();
//String videoFilename;
//VideoCapture camera;
public static void main(String args[]) {
//new VideoDecoder();
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
String filePath = "";
VideoDecoder v = new VideoDecoder(filePath);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Video app = new Video(filePath);
app.setVisible(true);
}
});
}
public Video(String videoFilename) {
vdec = new VideoDecoder(videoFilename);
vdec.initialize();
this.gradualTransitionList = new ArrayList<Integer>(
Arrays.asList(1866, 1866, 2406, 2421, 2676, 2677, 3200, 3200, 3551, 3569, 3618, 3637, 3765, 3774, 3838, 3849, 3928, 3941, 4042, 4048, 4299, 4299, 4561, 4580, 4607, 4620, 4776, 4789, 4986, 4994));
System.out.println("Gradual Transition list is:");
System.out.println(Arrays.toString(this.gradualTransitionList.toArray()));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Video Shot Detection");
panelBottom1 = new JPanel();
panelBottom2 = new JPanel();
panelTop = new JPanel();
buttonPanel = new JPanel();
gridLayout1 = new GridLayout(4, 5, 5, 5);
gridLayout2 = new GridLayout(2, 1, 5, 5);
gridLayout3 = new GridLayout(1, 2, 5, 5);
gridLayout4 = new GridLayout(2, 3, 5, 5);
setLayout(gridLayout2);
panelBottom1.setLayout(gridLayout1);
panelBottom2.setLayout(gridLayout1);
panelTop.setLayout(gridLayout3);
add(panelTop);
add(panelBottom1);
photographLabel.setVerticalTextPosition(JLabel.BOTTOM);
photographLabel.setHorizontalTextPosition(JLabel.CENTER);
photographLabel.setHorizontalAlignment(JLabel.CENTER);
photographLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
buttonPanel.setLayout(gridLayout4);
panelTop.add(photographLabel);
panelTop.add(buttonPanel);
previousPage = new JButton("Previous Page"); // previous 20 images
nextPage = new JButton("Next Page"); // next 20 images
JButton intensity = new JButton("Intensity"); // intensity button to select intensity method
JButton colorCode = new JButton("Color Code"); // color code button to select color code method
JButton colorCodeIntensity = new JButton("Color Code and Intensity");
JButton refresh = new JButton("Refresh"); // refresh button to revert all images to their original positions without having to restart the program
buttonPanel.add(previousPage);
buttonPanel.add(nextPage);
buttonPanel.add(intensity);
buttonPanel.add(colorCode);
buttonPanel.add(colorCodeIntensity);
buttonPanel.add(refresh);
nextPage.addActionListener(new nextPageHandler()); // setting action for each button using ActionListener
previousPage.addActionListener(new previousPageHandler());
refresh.addActionListener(new refreshHandler());
setSize(1100, 750);
setLocationRelativeTo(null);
button = new JButton[(this.gradualTransitionList.size() / 2) + 1];
System.out.println("Size of button array is " + button.length);
Mat frame = new Mat();
BufferedImage image1;
for (int i = 0; i < this.gradualTransitionList.size(); i = i + 2) {
int y = this.gradualTransitionList.get(i);
System.out.println("will seek to " + y);
vdec.seek(y);
vdec.camera.read(frame);
Imgcodecs.imwrite(y + ".jpg", frame);
try {
image1 = ImageIO.read(new File(y + ".jpg"));
} catch (IOException e) {
System.out.println("Error occurred when reading the file."); // printed if an exception is caught
}
ImageIcon icon = new ImageIcon(y + ".jpg");
if (icon != null) {
int m = (i / 2) + 1;
System.out.println("i is " + i);
System.out.println("m is " + m);
button[m] = new JButton(icon); // add the image icon in the button array
button[m].addActionListener(new IconButtonHandler(m, icon, this.gradualTransitionList.get(i), this.gradualTransitionList.get(i + 1)));
buttonOrder[m] = m; // add the index of each button in the button order array that will be used later on for image preview
}
}
displayFirstPage(); // display first page method which shows the first 20 image icons
}
private void displayFirstPage() {
imageCount = 1;
pageNo = 1;
previousPage.setEnabled(false); // in the firstp age, previous page should be disabled
nextPage.setEnabled(true); // next page is enabled
int imageButNo = 0;
panelBottom1.removeAll(); // refresh the bottom panel
int u = 0;
for (int i = 1; i <= 15; i++) {
imageButNo = buttonOrder[i]; // get the image button number from the buttonOrder array
System.out.println("Image button number is " + imageButNo);
panelBottom1.add(button[imageButNo]); // add the button of imageButton number to the bottom panel
int p = this.gradualTransitionList.get(u);
JLabel label1 = new JLabel(p + ".jpg"); // add a label for the button
label1.setForeground(Color.BLACK); // set the color to balck
label1.setFont(new Font("SansSerif", Font.BOLD, 28)); // set the font type and font size
panelBottom1.add(label1); // add the label to the bottom panel for each new button
imageCount++; // increment the image count
u = u + 2;
}
panelBottom1.revalidate(); // revalidate and repaint the bottom panel
panelBottom1.repaint();
}
/*This class implements an ActionListener for each iconButton. When an icon button is clicked, the image on the
* the button is added to the photographLabel and the picNo is set to the image number selected and being displayed.
*/
private class IconButtonHandler implements ActionListener {
JLabel vidpanel = new JLabel();
//JFrame jframe = new JFrame("Video");
int pNo = 0;
ImageIcon iconUsed;
ImageIcon imagei;
Mat frame = new Mat();
BufferedImage image1;
int frameStart;
int frameEnd;
public BufferedImage Mat2BufferedImage(Mat m) {
int type = BufferedImage.TYPE_BYTE_GRAY;
if (m.channels() > 1) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = m.channels() * m.cols() * m.rows();
byte[] b = new byte[bufferSize];
m.get(0, 0, b); // get all the pixels
BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(b, 0, targetPixels, 0, b.length);
return image;
}
public void displayImage(BufferedImage img)
{
ImageIcon icon = new ImageIcon(img);
JFrame frame = new JFrame();
frame.setLayout(new FlowLayout());
frame.setSize(img.getWidth(null)+50, img.getHeight(null)+50);
JLabel lbl = new JLabel();
lbl.setIcon(icon);
frame.add(lbl);
frame.setVisible(true);
// try {
// Thread.sleep(500);
// //jframe.setVisible(true);
// } catch (InterruptedException u) {
// u.printStackTrace();
// }
//frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
//frame.setVisible(false); //you can't see me!
//frame.dispose(); //Destr
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
IconButtonHandler(int i, ImageIcon j, int s, int e) {
pNo = i; // variable to store the image number when clicked
iconUsed = j; //sets the icon to the one used in the button
frameStart = s;
frameEnd = e;
//photographLabel.repaint();
//photographLabel.setVisible(true);
//panelTop.add(videoLabel);
}
public void actionPerformed(ActionEvent e) {
Mat frame = new Mat();
//VideoCapture camera = new VideoCapture("C:/MyName/MyPc/Desktop/TheLordOfTheRings.mp4");
VideoCapture camera = vdec.camera;
//JFrame jframe = new JFrame("MyTitle");
//jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel vidpanel = new JLabel();
//jframe.setContentPane(vidpanel);
//jframe.setVisible(true);
int counter =0;
while (counter <5) {
if (camera.read(frame)) {
System.out.println("playing");
//image1 = this.Mat2BufferedImage(frame);
ImageIcon image = new ImageIcon(this.Mat2BufferedImage(frame));
//vidpanel.setIcon(image);
//vidpanel.repaint();
image1 =this.Mat2BufferedImage(frame);
this.displayImage(image1);
}
counter++;
}
}
}
}