Per prima cosa però, se già non l'avete fatto, dovete scaricarvi la versione 2.4.4 o superiore della libreria dal sito ufficiale. Per la configurazione su Windows o su Linux vi rimando alle nostre guide, così come per Eclipse. Ora che avete installato l'ultima versione della libreria, aprite Eclipse e create un nuovo progetto Java.
- Andate sulle proprietà del progetto (Project
Properties).
- Cercate Java Build Path, aprite la tab Libraries e cliccate su Add Library....
- Scegliete User Library. Nella nuova finestra cliccate su User Libraries...
New...
- Date un nome alla libreria (opencv-2.4.4 o come volete) e cliccate Ok.
- Adesso dovete aggiungere la libreria al progetto: cliccate su Add External JARs... e cercate il file .jar nella cartella java di opencv.
- Fatto ciò, selezionate Native library location e cliccate Edit...
- Aggiungete il path per indirizzare le librerie (sotto Windows, aggiungete il path che vi porta a opencv_java244.dll).
- Cliccate su Finish
Adesso siete pronti per creare la vostra applicazione Java. Vi aggiungo un esempio di progetto Java che ho scritto racimolando esempi su forum e tutorial. Purtroppo le informazioni che circolano sono ancora molte poche. Dopotutto è da pochi mesi che sono uscite queste funzionalità.
// ******* Main class: import org.opencv.core.Mat; import org.opencv.core.Size; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; import javax.swing.JFrame; import javax.swing.SwingUtilities;; public class Main { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run(){ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); Mat img = Highgui.imread("lena.bmp"); Mat edges = new Mat(); Imgproc.blur(img, edges, new Size(10, 10)); JFrame frameOriginal = new ShowFrame ("Original", img); frameOriginal.setSize(img.cols(), img.rows()); frameOriginal.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frameOriginal.setVisible(true); JFrame frameBlur = new ShowFrame ("Blur", edges); frameBlur.setSize(edges.cols(), edges.rows()); frameBlur.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frameBlur.setVisible(true); } }); } } // ******* ShowFrame Class: import java.awt.Container; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.InputStream; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import org.opencv.core.Mat; import org.opencv.core.MatOfByte; import org.opencv.highgui.Highgui; public class ShowFrame extends JFrame { public ShowFrame(String title, Mat image){ super(title); MatOfByte matTmp = new MatOfByte(); Highgui.imencode(".jpg", image, matTmp); byte[] bytes = matTmp.toArray(); BufferedImage bufferedImage = null; try { InputStream in = new ByteArrayInputStream(bytes); bufferedImage = ImageIO.read(in); } catch (Exception e) { e.printStackTrace(); } JLabel imageLabel = new JLabel(new ImageIcon(bufferedImage)); Container c = getContentPane(); c.add(imageLabel); } }
Il programmino semplicemente prende in ingresso un'immagine, ci applica un blur e mostra le due immagini.
Se date un'occhiata agli import vi accorgerete che, se avete acquisito un po' di dimestichezza con la libreria per C++, i nomi delle classi e delle funzioni sono gli stessi, così come i criteri per applicarli.
Molto importante è l'istruzione:
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
La funzione di sistema loadLibrary vi consente di caricare le librerie a partire dal java.build.path che avete impostato durante i passi che vi ho elencato all'inizio dell'articolo.
I più attenti dei miei lettori avranno notato che ho utilizzato la libreria Java Swing per mostrare a video le immagini. Purtroppo in Imgproc non esistono ancora funzioni che svolgono il ruolo di imshow e namedWindow per C++. Per questo motivo dobbiamo appoggiarci ad un'altra libreria per quel minimo di GUI di cui abbiamo bisogno.
Vi invito inoltre a dare un'occhiata al costruttore di ShowFrame, la classe che eredita da JFrame, creata per l'occasione allo scopo di mostrare a video le due immagini. Purtroppo non sono riuscito a trovare un modo elegante per fare un cast da Mat a BufferedImage. L'unica soluzione trovata è stata quella di fare un passaggio intermedio usando un oggetto MatOfByte. Invito chiunque trovasse una soluzione migliore (e soprattutto più leggibile) a commentare questo articolo.
Per dubbi ed imprecisioni trovate nell'articolo, scriveteci come sempre.
