I'm trying to set up face detection with JavaCV. I've got working code with cvLoadImage but when I try to load an image via Highgui.imread there's an error: 'Highgui cannot be resolved' and 'Highgui' has red wavy underlining. For some reason Eclipse cannot deal properly with imported com.googlecode.javacv.cpp.opencv_highgui or ...?
Problem here:
CvMat myImg = Highgui.imread(myFileName);
Full code:
import java.awt.EventQueue;
import java.awt.Insets;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import com.googlecode.javacv.cpp.opencv_core.CvMemStorage;
import com.googlecode.javacv.cpp.opencv_core.CvRect;
import com.googlecode.javacv.cpp.opencv_core.CvScalar;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_objdetect.CvHaarClassifierCascade;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;
import static com.googlecode.javacv.cpp.opencv_objdetect.*;
import java.awt.Button;
import java.io.File;
import javax.swing.SwingConstants;
import javax.swing.JLabel;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import com.googlecode.javacv.cpp.opencv_core.CvMat;
import com.googlecode.javacv.cpp.opencv_highgui;
//import opencv_highgui;
public class Form1 {
static private final String newline = "\n";
JButton openButton, saveButton;
JTextArea log;
JFileChooser fc;
String myFileName = "";
//Load haar classifier XML file
public static final String XML_FILE =
"resources/!--master--haarcascade_frontalface_alt_tree.xml";
private JFrame frame;
//Detect for face using classifier XML file
public static void detect(IplImage src){
//Define classifier
CvHaarClassifierCascade cascade = new CvHaarClassifierCascade(cvLoad(XML_FILE));
CvMemStorage storage = CvMemStorage.create();
//Detect objects
CvSeq sign = cvHaarDetectObjects(
src,
cascade,
storage,
1.1,
3,
0);
cvClearMemStorage(storage);
int total_Faces = sign.total();
//Draw rectangles around detected objects
for(int i = 0; i < total_Faces; i++){
CvRect r = new CvRect(cvGetSeqElem(sign, i));
cvRectangle (
src,
cvPoint(r.x(), r.y()),
cvPoint(r.width() + r.x(), r.height() + r.y()),
CvScalar.RED,
2,
CV_AA,
0);
}
//Display result
cvShowImage("Result", src);
cvWaitKey(0);
}
/**
* Create the application.
*/
public Form1() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
JLabel Label1 = new JLabel(" ");
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 301, 222);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnDetect = new JButton("Detect");
btnDetect.setVerticalAlignment(SwingConstants.TOP);
btnDetect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//IplImage img = cvLoadImage("resources/lena.jpg");
IplImage img = cvLoadImage(myFileName);
CvMat myImg = Highgui.imread(myFileName);
detect(img);
}
});
frame.getContentPane().add(btnDetect, BorderLayout.SOUTH);
Label1.setHorizontalAlignment(SwingConstants.CENTER);
frame.getContentPane().add(Label1, BorderLayout.CENTER);
JButton btnNewButton = new JButton("Open");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JFileChooser fileopen = new JFileChooser();
int ret = fileopen.showDialog(null, "Открыть файл");
if (ret == JFileChooser.APPROVE_OPTION) {
File file = fileopen.getSelectedFile();
myFileName = file.getAbsolutePath();
Label1.setText(myFileName);
}
}
});
frame.getContentPane().add(btnNewButton, BorderLayout.NORTH);
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Form1 window = new Form1();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
//Load image
//IplImage img = cvLoadImage("resources/lena.jpg");
//detect(img);
}
}
External JARs: http://pasteboard.co/jwqNHC9.png
Full project in ZIP
I've also followed all steps from here: http://opencvlover.blogspot.in/2012/04/javacv-setup-with-eclipse-on-windows-7.html
Any help will be appreciated.
Mat m = Highgui.imread(myFileName); is from the builtin opencv java wrappers , not from javacv ( which is a independant, 3rd party wrapper ).
unfortunately, both concurrent apis are pretty incompatible, as javacv is wrapping the outdated c-api, and the opencv ones are wrapping the more modern c++ api.
Related
My Java code below places a image on a label.The button when triggered should export the image. There are no runtime error but nothing is being exported. I assume the issue is during the conversion from image icon to buffered image which occurs in b3.addActionListener(new ActionListener() {. I am not seeing anything exported at all not even a blank image.
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class ren {
Frame f;
JLabel b2 = new JLabel("");
ren() throws IOException {
f = new JFrame();
b2.setIcon(new ImageIcon("/Users/johnzalubski/Desktop/dropIn/Complete-Audi-Buying-Guide-gear-patrol-lead-full.jpg"));
JButton b3 = new JButton("Exported");
File file = new File("aa.png");
f.add(b2, BorderLayout.CENTER);
f.add(b3, BorderLayout.SOUTH);
f.setSize(400, 500);
f.setVisible(true);
b3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Icon ico = b2.getIcon();
// Create a buffered image
BufferedImage bimg = new BufferedImage(ico.getIconWidth(), ico.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
// Create the graphics context
Graphics g = bimg.createGraphics();
// Now paint the icon
ico.paintIcon(null, g, 0, 0);
g.dispose();
BufferedImage scaledButtonImage =
new BufferedImage(400, 1000, bimg.getType());
Graphics g1 = scaledButtonImage.createGraphics();
g1.drawImage(scaledButtonImage, 0, 0, 400, 1000, null);
//
g1.dispose();
b2.setIcon(new ImageIcon(bimg));
try {
ImageIO.write(bimg, "png", file);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
}
public static void main(String[] args) throws IOException {
new ren();
}
}
JLabel two = new JLabel();
ImageIcon jaina= new ImageIcon("images/jaina.gif");
two.setBounds(0,0,300,300);
two.setIcon(jaina);
then i added the Label to my panel, it plays only once
If your gif is not set to loop, the correct solution is to modify the gif to have it loop.
Out of curiosity I mocked up this example. What if I want to animate a gif independent of its animation settings.
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;
import java.util.List;
import java.util.ArrayList;
import java.io.File;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.EventQueue;
public class GifLabel{
public static void startGui( List<ImageIcon> imgs){
JFrame frame = new JFrame("animated gif");
JLabel label = new JLabel( );
frame.add(label);
label.setIcon(imgs.get(0));
Timer t = new Timer( 30, new ActionListener(){
int i = 0;
#Override
public void actionPerformed( ActionEvent evt ){
label.setIcon ( imgs.get(i) );
i = (i+1)%imgs.size();
}
});
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
t.start();
}
public static void main(String[] args) throws Exception{
ImageReader reader = ImageIO.getImageReadersBySuffix("GIF").next();
reader.setInput( new FileImageInputStream( new File("images/jaina.gif")));
int n = reader.getNumImages( true );
List<ImageIcon> imgs = new ArrayList<>();
for(int i = 0; i<n; i++){
imgs.add( new ImageIcon(reader.read(i)) );
}
EventQueue.invokeLater( ()->{
startGui(imgs);
});
}
}
This is way more fragile than just making sure the GIF is the correct format. Also way more code, considering the original new ImageIcon("..."); handles everything.
I am creating a user interface for a pdf reader, and I want to have a list with recent open files. (Not the content of the files, just the name of the file).
From the snap shared, I assume that you are using JFileChooser for your dialog to open file. Hope this helps!
int result = fileChooser.showOpenDialog(panel);
//where panel is an instance of a Component such as JFrame, JDialog or JPanelwhich is parent of the dialog.
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
textArea.setText(selectedFile.getName());
}
The example below uses a JFileChooser with setMultiSelectionEnabled(true) to add() one or more files to a List<File> and update() a JTextArea with the current list. As suggested here, you can use Action to maintain a menu or tool bar of recent files.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
/**
* #see https://stackoverflow.com/a/37153404/230513
* #see https://stackoverflow.com/a/4039359/230513
*/
public class Test {
private final List<File> recentFiles = new ArrayList<>();
private final JTextArea textArea = new JTextArea(12, 12);
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textArea.setBorder(BorderFactory.createTitledBorder("Recent Files"));
f.add(textArea);
JPanel p = new JPanel(new FlowLayout(FlowLayout.RIGHT));
p.add(new JButton(new AbstractAction("Open") {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser jfc = new JFileChooser(".");
jfc.setMultiSelectionEnabled(true);
if (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
recentFiles.addAll(Arrays.asList(jfc.getSelectedFiles()));
update();
}
}
}));
f.add(p, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private void update() {
textArea.setText("");
for (File file : recentFiles) {
textArea.append(file.getName() + "\n");
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Test()::display);
}
}
I am looking to build a program to show pictures to friends and family. With the regular Windows Image Viewer there is a lot of unused screen space and it does not react on the USB presenter that I use for PPT presentations.
My idea is to have the user select a folder (easy), all images in that folder will be selected and the JFrame will display the first image in full screen mode (easy). On right arrow (easy) the presentation will jump to the next picture from the selection (difficult). Sounds simple, but I can't solve it.
Here is my code so far after Andrews suggestion:
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.KeyEvent;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
class ArrowAction extends AbstractAction {
private String cmd;
public ArrowAction(String cmd) {
this.cmd = cmd;
}
#Override
public void actionPerformed(ActionEvent e) {
if (cmd.equalsIgnoreCase("Backward")) {
System.out.println("Previous picture!");
} else if (cmd.equalsIgnoreCase("Forward")) {
System.out.println("Next Picture!");
}
}
}
class TestKeyBinding {
public TestKeyBinding() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
InputMap im = panel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = panel.getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "Forward");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "Backward");
am.put("Forward", new ArrowAction("Forward"));
am.put("Backward", new ArrowAction("Backward"));
GraphicsEnvironment ge = GraphicsEnvironment
.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
gs.setFullScreenWindow(frame);
BufferedImage myPicture;
try {
myPicture = ImageIO.read(new URL("http://upload.wikimedia.org/wikipedia/commons/1/13/Vancouver_ib.jpg"));
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
panel.add(picLabel);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
frame.add(panel);
frame.validate();
}
}
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
TestKeyBinding kb = new TestKeyBinding();
}
}
Any idea how to do the onKeyEvent and have the next image displayed? And any other best practices that I should get used to?
Thanks,
Florian
I faced a problem that the typed data can not be persistent. I want to store java Swing GUI to XML file and reuse them latter. Now I store the GUI successfully. But after I type some data into the textfield. The typed data can not be encoded into XML file. Could you help me store both the GUI and the typed content? Below is the code using javabeans XMLencoder:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import java.beans.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class ResourceName extends JFrame implements ActionListener{
static JFileChooser chooser;
JButton save,load;
JTextField tf;
static JFrame frame;
public ResourceName(){
chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("."));
frame = new JFrame("ResourceName");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
save = new JButton("Save");
save.setActionCommand("Save");
save.addActionListener(this);
load = new JButton("Load");
load.setActionCommand("Load");
load.addActionListener(this);
tf = new JTextField(10);
frame.add(save);
frame.add(tf);
frame.add(load);
frame.pack();
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e){
if((e.getActionCommand()).equals("Save"))
{
save();
}else if((e.getActionCommand()).equals("Load"))
{
load();
}
}
public void save()
{
if(chooser.showSaveDialog(null)==JFileChooser.APPROVE_OPTION)
{
try{
File file = chooser.getSelectedFile();
XMLEncoder encoder = new XMLEncoder(new FileOutputStream(file));
encoder.writeObject(frame);
encoder.close();
}
catch(IOException e)
{
JOptionPane.showMessageDialog(null, e);
}
}
}
public void load()
{
//show file chooser dialog
int r = chooser.showOpenDialog(null);
// if file selected, open
if(r == JFileChooser.APPROVE_OPTION)
{
try
{
File file = chooser.getSelectedFile();
XMLDecoder decoder = new XMLDecoder(new FileInputStream(file));
decoder.readObject();
decoder.close();
}
catch(IOException e)
{
JOptionPane.showMessageDialog(null, e);
}
}
}
public static void main(String[] args) {
ResourceName test = new ResourceName();
}
}
Please help me solve this problem. Many Thanks!
it may be that the text property, is transient, this means it won't be saved to the output automatically, by an ObjectOutputStream. You'll probably have to explicitly write that field.