Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1558 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  JMF acquisition des images saccadée

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

JMF acquisition des images saccadée

n°1705602
TheRom_S
Posté le 20-03-2008 à 19:00:34  profilanswer
 

Salut, je suis en train d'essayer de récupérer des images de ma webcam pour faire un traitement dessus avant affichage.
Mon problème est que mon flux devient saccadé par intermittences : pendant une seconde, je vais avoir un flux fluide et ensuite ça va bloquer pendant 2-3 secondes. Je ne sais pas trop d'où ça peut venir ni comment corriger donc je fais appel à vous.
 

Code :
  1. public class DeviceHandler {
  2.     private CaptureDeviceInfo device;
  3.     private Player player;
  4.     private FrameGrabbingControl frameGrabber;
  5.     private Buffer buffer;
  6.     private BufferToImage bufferUtil;
  7.     private boolean ready;
  8.     private int i;
  9.    
  10.     /** Creates a new instance of DeviceHandler */
  11.     public DeviceHandler(String deviceName) {//throws Exception {
  12.         this.ready = false;
  13.         this.device = null;
  14.         this.device = CaptureDeviceManager.getDevice(deviceName);
  15.         //if (this.device == null) { throw new Exception("Device : \"" + deviceName + "\" not found !" ); }
  16.         MediaLocator ml = this.device.getLocator();
  17.         //if (ml == null) { throw new Exception("Unable to find an appropriate media locator !" ); }
  18.         this.player = null;
  19.         try { this.player = Manager.createRealizedPlayer(ml); }
  20.         catch (NoPlayerException ex) {}// throw new Exception("Unable to find an appropriate player !", ex); }
  21.         catch (CannotRealizeException ex) {}// throw new Exception("Unable to get the player in realized state !", ex); }
  22.         catch (IOException ex) {}// throw new Exception("Unable to create a player !", ex); }
  23.         //if (this.player == null) { throw new Exception("Player is NULL !" ); }
  24.         this.player.start();
  25.         while ((this.player.getState() & Player.Started) == 0) {}
  26.         this.ready = true;
  27.         this.frameGrabber = (FrameGrabbingControl)this.player.getControl("javax.media.control.FrameGrabbingControl" );
  28.         this.buffer = frameGrabber.grabFrame();
  29.         this.bufferUtil = new BufferToImage((VideoFormat)buffer.getFormat());
  30.         this.i = 0;
  31.     }
  32.    
  33.     public Image grabImage() {
  34.         this.i++;
  35.         this.buffer = frameGrabber.grabFrame();
  36. // juste pour tester
  37. if (this.buffer.getData() != null) { System.out.println(this.buffer.getFormat().getEncoding() + " " + i); }
  38.         this.bufferUtil = new BufferToImage((VideoFormat)buffer.getFormat());
  39.         return this.bufferUtil.createImage(buffer);
  40.     }
  41.    
  42.     public boolean isReady() { return this.ready; }
  43. }
  44. // et le main
  45.     public static void main(String[] args) {
  46.         DeviceHandler dh = new DeviceHandler("vfw:Microsoft WDM Image Capture (Win32):0" );
  47.         while (!dh.isReady()) {}
  48.         JFrame jf = new JFrame("test" );
  49.         jf.setSize(400, 300);
  50.         JPanel jp = new JPanel();
  51.         jp.setSize(320, 240);
  52.         jf.getContentPane().add(jp);
  53.         jf.setVisible(true);
  54.         jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  55.         Graphics gc = jp.getGraphics();
  56. // j'ai essayé en ajoutant un controle sur le temps mais ça ne change rien
  57.         long time = System.currentTimeMillis();
  58.         while (true) {
  59.             if (System.currentTimeMillis() > time + 200) {
  60.                 time = System.currentTimeMillis();
  61. // ici je devrais faire un traitement sur l'image avant l'affichage (et même pas l'afficher au final)
  62.                 gc.drawImage(dh.grabImage(), 0, 0, jp);
  63.             }
  64.         }
  65.     }


 
Voilà, j'espère que vous avez des idées. Je peux éviter d'utiliser BufferToImage si besoin et m'attaquer directement au buffer si les données sont rangées correctement (j'imagine Byte[] RGBRGBRGBRGBRGB... d'après le "rgb" que me donne buffer.getFormat().getEncoding())

mood
Publicité
Posté le 20-03-2008 à 19:00:34  profilanswer
 

n°1706335
TheRom_S
Posté le 21-03-2008 à 20:37:03  profilanswer
 

puisque je vois que ça passionne tout le monde (et surtout qu'il y a pas beaucoup de ressources sur ce sujet sur le net), voilà la solution : attaquer directement le flux
 
Par contre, c'est parfaitement fluide mais il y a un gros décalage (environ 1 sec), ce qui n'est pas très bon vu que c'est sensé être utilisé en temps réel.
Des idées ?

Code :
  1. public class DeviceHandler {
  2.     private boolean ready;
  3.     private CaptureDeviceInfo device;
  4.     private PushBufferDataSource dataSource;
  5.    
  6.     /** Creates a new instance of DeviceHandler */
  7.     public DeviceHandler(String deviceName) throws Exception {
  8.         this.ready = false;
  9.         this.device = null;
  10.         this.device = CaptureDeviceManager.getDevice(deviceName);
  11.         if (this.device == null) { throw new Exception("Device : \"" + deviceName + "\" not found !" ); }
  12.         MediaLocator ml = this.device.getLocator();
  13.         if (ml == null) { throw new Exception("Unable to find an appropriate media locator !" ); }
  14.         this.dataSource = null;
  15.         DataSource ds = null;
  16.         try { ds = Manager.createDataSource(ml); }
  17.         catch (NoDataSourceException ex) { throw new Exception("Unable to find an appropriate data source !", ex); }
  18.         catch (IOException ex) { throw new Exception("Unable to create an appropriate data source !", ex); }
  19.         if (ds == null) { throw new Exception("Data source is NULL !" ); }
  20. //System.out.println(ds.getClass());
  21. // pour ma webcam, c'est PushBufferDataSource
  22.         if (!(ds instanceof PushBufferDataSource)) { throw new Exception("Wrong type of data source !" ); }
  23.         this.dataSource = (PushBufferDataSource)ds;
  24.         try { this.dataSource.connect(); }
  25.         catch (IOException ex) {}
  26.         try { this.dataSource.start(); }
  27.         catch (IOException ex) { throw new Exception("Unable to start data transfert !", ex); }
  28.         this.ready = true;
  29.     }
  30.    
  31.     public boolean isReady() { return this.ready; }
  32.    
  33.     public Object getBuffer() {
  34.         Buffer buf = new Buffer();
  35.         try { this.dataSource.getStreams()[0].read(buf); }
  36.         catch (IOException ex) {
  37.             ex.printStackTrace();
  38.         }
  39.         return buf.getData();
  40.     }
  41. }
  42. // le main
  43.     public static void main(String[] args) {
  44.         DeviceHandler dh = null;
  45.         try { dh = new DeviceHandler("vfw:Microsoft WDM Image Capture (Win32):0" ); }
  46.         catch (Exception ex) {
  47.             ex.printStackTrace();
  48.             System.exit(0);
  49.         }
  50.         while (!dh.isReady()) {}
  51.         BufferedImage img = new BufferedImage(320, 240, BufferedImage.TYPE_INT_RGB);
  52.         int tre = 15;
  53.         while (true) {
  54.             Object o = dh.getBuffer();
  55.             if ((o != null) && (o instanceof byte[])) {
  56.                 byte[] b = (byte[])o;
  57.                 int[] ib = new int[76800];
  58.                 for (int i = 0; i < b.length / 3; i++) {
  59.                     // on parcours le buffer à l'envers (BGRBGRBGR... du bas droit vers haut gauche)
  60.                     ib [76800 - i - 1] = (b[3 * i + 2] << 16) + (b[3 * i + 1] << 8) + b[3 * i];
  61.                 }
  62.                 img.setRGB(0, 0, 320, 240, ib, 0, 320);
  63. // traitements sur l'image
  64.             }
  65.         }
  66.        
  67.     }


---------------
The Rom's, à votre service

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  JMF acquisition des images saccadée

 

Sujets relatifs
[DELPHI] Afficher des images dans un listview.Bande Déroulante avec des images
système notation par imagesAide compréhension programme d'acquisition
Script d'upload d'images[HTML/CSS] Site avec images uniquement, votre avis !
Algorithme pour regrouper plein de petites images en une grosseFirefox affichage des img qui devraient etre masquées (blog)[résolu]
[RESOLU]decoupe d'images via le net 
Plus de sujets relatifs à : JMF acquisition des images saccadée


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR