France Hardware : Forums de discussion
Retrouvez les prix près de chez vous :  
Index du forum | Liste des membres | Liste des groupes | Inscription | F-A-Q | Recherche
Pseudo :    Password :     
22 346 membres enregistrés - 1 873 035 posts - 95 166 topics
Index des forums FH  | Index des forums DegroupNews
      Programmation
           Sujets divers
                [Java] Detection de mouvements [RESOLU] - Projet SourceForge
23 connectés(record : 207 le 05 juin 2007 - 05 h 23)

Vous devez vous connecter pour répondre au topic.
Precedent | 1,2
[Java] Detection de mouvements [RESOLU] - Projet SourceForge

Petit_PimoOosE
rsqrtps & pshufb

Messages : 4 616
Inscrit le 15/06/03
Ville : Montréal
Non connecté
  Posté le 08 juillet 2005 - 22 h 39 m 41 s
Reprise du message précédent :

À mon avis en 1 seconde tu as largement le temps.

Le coup de la queue, c'est bien, mais s'il y a du monde dedans, c'est parce que le thread consumer ne suit pas. Si la tendance se maintient, il risque de prendre de plus en plus de retard et ça finit par exploser !

Tu peux aussi faire un système du genre : les images prises pendant un traitement sont sautées. Ça marche aussi.



Huile de fraise.

kha
Google is your best friend

Messages : 1 235
Inscrit le 01/03/02
Ville : Montreal
Non connecté
  Posté le 09 juillet 2005 - 00 h 21 m 43 s
C est bien ce que j ai fait quand j ai dit :

"le hic c est juste que si l utilisateur met une valeur maxi a la queue, ben le systeme de capture ne mettra pas ses captuere dedans et affichera uen exception mais sans planter."

La queue est soit a une valeur limite, soit a l infini, au choix.

Mais de ce cote le, il n y a pas de pb. Des que le consumer recoit une capture, il peut l envoyer au subscribers (differents agents d alerte charges de traiter la capture) et le motion detector en est un. Il peut tres bien partir un thread pour detecter le mouvent entre ces deux images sans probleme. Donc il n y aura en gros pas d attente dans la queue mais plusieurs thread.

Mais ca c est un detail.




kha
Google is your best friend

Messages : 1 235
Inscrit le 01/03/02
Ville : Montreal
Non connecté
  Posté le 09 juillet 2005 - 03 h 33 m 01 s


Le 07 juillet 2005 - 10 h 00, Gosseyn a écrit :
Bonjour,

J'ai deja fait cela. Sinon, il existe une solution Open Source GPL qui s'appelle motion en C et non en Java.
Voici comment j'ai procédé. J'ai gardé les couelurs d'origine de l'image et pour chaque pixel je compare les valeurs RGB. Sachant que les capteurs CCD ne sont pas parfaits, j'applique un coef de tolerance. Je considère que les pixels sont reellement differnts si la difference des valeurs RGB est superieure à la tolerance. D'autre part je considere qu'il y a mouvement si on a un nombre minimum de pixels differents. En jouant sur ces 2 parametres, on peut affiner la detection en la rendant plus ou moins sensible.

Pour mon cas, j'ai retenu un minimum de 200 pixels differents pour declarer un mouvement et la difference RGB devait etre superieure à 30, pour une image en 640x480.

Apres on peut aussi mesurer la distance entre 2 pixels differents car en general, c'est tout une zone qui bouge. et/ou choisir des zones...

Voala, hope that helps.


Je viens de me rendre compte que c ets ce que je fait depuis le debut.

Je passe en grayscale pour avoir une seule bande a traiter et je fait un diff.
Je recupere ensuite un histogramme de l image diff.

cet histogramme me donne pour chaque valeur de 0->255 le nombre de pixels qui ont cette valeur.

Ce que je fesais avant :

Je prenais la somme de tous les pixels dont la valeur etait inferieure a 10. En gros, ca reviens exactement au meme que toi puisque si un pixel un uen valeur de 50 par exemple, ca veut dire que le diff a donne 50 => que y avait une difference entre les pixels originaux.

Cette somme correspond chez moi au nombre de pixel qui restent tolere (qui sont noirs).

Ensuite je fais un ratio de ce nombre par les pixels au total.

J ai donc bien deux parametres. Mais je vais essayer de changer, pour faire comme tu as fait, c-a-d faire une somme de pixels qui ne sont pas dans les limites, que je vais fixer a 30.

J ai aussi essayer deux methodes differentes de diff.
1. avec le JAI
2. manuellement, en recuperant les deux arrays de la bande grayscale pour chaque image et en fesant un tableau donc le contenu est la valeur absolue de la difference des deux autres

Les resultats donnent une concentration de noirs plus grande pour le jai (il y a un gros groupe de pixel dont la valeur est inf a 10) alors que la methode a la main donne une concentration plus normalisee ou la, la valeur a 30 serait + efficace et donnerait un meileur ratio

Jvais refaire d autres tests.
a+




kha
Google is your best friend

Messages : 1 235
Inscrit le 01/03/02
Ville : Montreal
Non connecté
  Posté le 09 juillet 2005 - 15 h 55 m 34 s
Je viens de faire des tests sur des images 800/600 avec +/- de mouvement et la methode de calcul "manuelle" est de loin la meilleure. LE JAI dans son diff doit modifier la luminosite ou faire de l error diffusion car pour deux images ou l objet passe de gauche a droite de l image, le jai ne detecte pas de mouvement alors que la methode manuelle si, malgre qu il y ai un changement de luminosite. Ca doit etre ca qui affecte le diff du JAI.

En tout cas, je posterai + tard la classe de detecion des mouvement.




kha
Google is your best friend

Messages : 1 235
Inscrit le 01/03/02
Ville : Montreal
Non connecté
  Posté le 10 juillet 2005 - 21 h 48 m 19 s
    Code     
  1. /**
  2.  * @MotionDetector.java 12 juin 2005 19:40:09
  3.  */
  4. 
  5. package st.fr.kha.jideoguard.ids.impl;
  6. 
  7. import java.util.ArrayList;
  8. import java.util.Iterator;
  9. import java.util.List;
 10. 
 11. import javax.media.jai.PlanarImage;
 12. 
 13. import st.fr.kha.common.image.ImageUtils;
 14. import st.fr.kha.common.logging.ILog;
 15. import st.fr.kha.common.logging.LogManager;
 16. import st.fr.kha.jideoguard.capture.ICaptureEvent;
 17. import st.fr.kha.jideoguard.ids.IMotionDetector;
 18. import st.fr.kha.jideoguard.ids.IMotionEvent;
 19. import st.fr.kha.jideoguard.ids.IMotionListener;
 20. 
 21. /**
 22.  * @author kha
 23.  */
 24. public final class MotionDetector implements IMotionDetector
 25. {
 26.     /**
 27.      * Default sensibility of motion detector
 28.      */
 29.     public static final float DEFAULT_SENSIBILITY = 0.90F;
 30.     /**
 31.      * Default diff level
 32.      */
 33.     public static final int DEFAULT_DIFF_LEVEL = 5;
 34.     
 35.     private static final ILog LOG = LogManager.getLogger(MotionDetector.class);
 36.     private static final int MIN_PIXEL_VALUE = 0; 
 37.     private static final int MAX_PIXEL_VALUE = 255;
 38.     private static final int GRAYSCALE_BAND = 0; 
 39.     
 40.     private final List listeners = new ArrayList();
 41.     
 42.     private float sensibility = DEFAULT_SENSIBILITY;
 43.     private int diffLEvel = DEFAULT_DIFF_LEVEL;
 44.     
 45.     private ICaptureEvent oldCapture;
 46.     private ICaptureEvent newCapture;
 47.     private int[] oldBand;
 48.     private int[] newBand;
 49.     
 50.     /** 
 51.      * New motion detector system
 52.      */
 53.     public MotionDetector()
 54.     {
 55.         super();
 56.     }
 57. 
 58.     /**
 59.      * @see st.fr.kha.jideoguard.ids.IMotionDetector#setSensibility(float)
 60.      */
 61.     public void setSensibility(final float pSensibility)
 62.     {
 63.         this.sensibility = (pSensibility < 0.0F || pSensibility > 1.0F) ? DEFAULT_SENSIBILITY : pSensibility;
 64.         LOG.info("Sensibility changed to " + getSensibility());
 65.     }
 66. 
 67.     /**
 68.      * @see st.fr.kha.jideoguard.ids.IMotionDetector#getSensibility()
 69.      */
 70.     public float getSensibility()
 71.     {
 72.         return this.sensibility;
 73.     }
 74. 
 75.     /**
 76.      * @see st.fr.kha.jideoguard.ids.IMotionDetector#getAcceptedDiffLevel()
 77.      */
 78.     public int getAcceptedDiffLevel()
 79.     {
 80.         return this.diffLEvel;
 81.     }
 82.     
 83.     /**
 84.      * @see st.fr.kha.jideoguard.ids.IMotionDetector#setAcceptedDiffLevel(int)
 85.      */
 86.     public void setAcceptedDiffLevel(final int pLevel)
 87.     {
 88.         this.diffLEvel = (pLevel < MIN_PIXEL_VALUE || pLevel > MAX_PIXEL_VALUE) ? DEFAULT_DIFF_LEVEL : pLevel;
 89.         LOG.info("Diff level changed to " + getAcceptedDiffLevel());
 90.     }
 91.     
 92.     /**
 93.      * @see st.fr.kha.jideoguard.ids.IMotionDetector#addMotionListener(st.fr.kha.jideoguard.ids.IMotionListener)
 94.      */
 95.     public void addMotionListener(final IMotionListener pMotionListener)
 96.     {
 97.         if (pMotionListener == null)
 98.         {
 99.             throw new IllegalArgumentException("Listener cannot be null");
100.         }
101.         listeners.add(pMotionListener);
102.     }
103. 
104.     /**
105.      * @see st.fr.kha.jideoguard.ids.IMotionDetector#addCaptureEvent(st.fr.kha.jideoguard.capture.ICaptureEvent)
106.      */
107.     public synchronized void addCaptureEvent(final ICaptureEvent pCaptureEvent)
108.     {
109.         this.oldCapture = this.newCapture;
110.         this.oldBand = this.newBand;
111.         
112.         this.newCapture = pCaptureEvent;
113.         this.newBand = getBand(this.newCapture);
114.         
115.         if (this.oldCapture != null && this.newCapture != null)
116.         {
117.             // Get Diff Level
118.             final int diffLevel = getAcceptedDiffLevel();
119.             
120.             // We only take the smallest image. 
121.             // This has chance to trigger a motion although there is none but this is only for one comparison
122.             final long pxNum = (oldBand.length < newBand.length) ? oldBand.length : newBand.length;
123.             
124.             // Compute the number of pixels that are accepted at specified level
125.             long accepectedPixels = 0;
126.             for (int i = 0; i < pxNum; i++)
127.             {
128.                 if (Math.abs(oldBand[i] - newBand[i]) < diffLevel)
129.                 {
130.                     accepectedPixels++;
131.                 }
132.             }
133. 
134.             // Compute ratio of accepeted pixels
135.             final float ratio = (float) accepectedPixels / (float) pxNum;
136.             
137.             LOG.debug("addCaptureEvent: accepted: " + accepectedPixels + ", ratio: " + ratio);
138.             
139.             // Compare with sensibility and fire event if needed
140.             if (getSensibility() >= ratio)
141.             {
142.                 fireEvent(new MotionEvent(this.oldCapture, this.newCapture, ratio, accepectedPixels));
143.             }
144.         }
145.     }
146.     
147.     private int[] getBand(final ICaptureEvent e)
148.     {
149.         if (e == null)
150.         {
151.             return null;
152.         }
153.         final PlanarImage newGray = ImageUtils.toGrayScale(e.getImage());
154.         return newGray.getData()
155.             .getSamples(0, 0, newGray.getWidth(), newGray.getHeight(), GRAYSCALE_BAND, (int[]) null);
156.     }
157.     
158.     private void fireEvent(final IMotionEvent e)
159.     {
160.         LOG.debug("Fire motion event");
161.         final Iterator i = this.listeners.iterator();
162.         while (i.hasNext())
163.         {
164.             ((IMotionListener) i.next()).onMotion(e);
165.         }
166.     }
167. }
    Code     
 1. /**
 2.  * @ImageUtils.java 5 juil. 2005 20:58:42
 3.  */
 4. 
 5. package st.fr.kha.common.image;
 6. 
 7. import java.awt.color.ColorSpace;
 8. import java.awt.image.ColorConvertOp;
 9. import java.awt.image.renderable.ParameterBlock;
10. 
11. import javax.media.jai.JAI;
12. import javax.media.jai.PlanarImage;
13. 
14. /**
15.  * Utility class for images
16.  * 
17.  * @author kha
18.  */
19. public final class ImageUtils
20. {
21.     private ImageUtils()
22.     {
23.         super();
24.     }
25.     
26.     /**
27.      * Convert an image to gray scale
28.      *
29.      * @param src PlanarImage (JAI)
30.      * @return the image in grayscale
31.      */
32.     public static PlanarImage toGrayScale(final PlanarImage src) 
33.     {
34.         if (src == null)
35.         {
36.             return null;
37.         }
38.         final ColorConvertOp colorConvert = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
39.         final ParameterBlock pb = new ParameterBlock();
40.         pb.add(colorConvert.filter(src.getAsBufferedImage(), null));
41.         return JAI.create("AWTImage", pb, null);
42.     }
43. 
44. }




kha
Google is your best friend

Messages : 1 235
Inscrit le 01/03/02
Ville : Montreal
Non connecté
  Posté le 10 juillet 2005 - 21 h 53 m 42 s
Example d utilisation :

J obtient des bons resultats avec des images 800x600, un temps de traitement < 1sec et une difference maxi acceptee entre les valeurs des pixels de 10 et une sensibilite de 90%

    Code     
 1.     public final void testAddMotionListener() throws IOException
 2.     {
 3.         final ILog l = log;
 4.         final IMotionListener lisetner = new IMotionListener()
 5.         {
 6.             /**
 7.              * @see st.fr.kha.jideoguard.ids.IMotionListener#onMotion(st.fr.kha.jideoguard.ids.IMotionEvent)
 8.              */
 9.             public void onMotion(final IMotionEvent pMotionEvent)
10.             {
11.                 final String name = "" + pMotionEvent.getSensibility() + " = "
12.                     + (String) pMotionEvent.getOldCaptureEvent().getImage().getProperty("name") + " | "
13.                     + (String) pMotionEvent.getNewCaptureEvent().getImage().getProperty("name");
14.                 UIUtils.show(name , new PlanarImageDisplayer(pMotionEvent.getOldCaptureEvent().getImage()));
15.                 UIUtils.show(name , new PlanarImageDisplayer(pMotionEvent.getNewCaptureEvent().getImage()));
16.                 System.out.println("MOTION EVENT : " + name);
17.             }
18.         };
19. 
20.         final String[] folders = new String[] {"captures/no-diff", "captures/diff", "captures"};
21.         
22.         MotionDetector d = null;
23.         File[] files = null;
24.         CaptureEvent[] evt = null;
25.         
26.         for (int f = 0; f < folders.length; f++)
27.         {
28.             d = new MotionDetector();
29.             d.setSensibility(0.90F);
30.             d.setAcceptedDiffLevel(10);
31.             d.addMotionListener(lisetner);
32.             files = getDataFile(folders[f]).listFiles();
33.             evt = new CaptureEvent[files.length];
34.             for (int i = 0; i < evt.length; i++)
35.             {
36.                 if (files[i].isDirectory())
37.                 {
38.                     continue;
39.                 }
40.                 evt[i] = new CaptureEvent(JAI.create("fileload", new ParameterBlock().add(files[i].getAbsolutePath())));
41.                 evt[i].getImage().setProperty("name", files[i].getName());
42.                 l.debug("Adding: " + files[i].getName());
43.                 d.addCaptureEvent(evt[i]);
44.             }
45.             
46.             System.in.read();
47.             System.in.read();
48.         }
49.     }




kha
Google is your best friend

Messages : 1 235
Inscrit le 01/03/02
Ville : Montreal
Non connecté
  Posté le 30 août 2005 - 16 h 12 m 18 s
Pour ceux que ca interesse, j ai mis le projet sur sourceforge. C est juste un debut. Si vous avez envie de participer (doc, site, programmation java si vous connaissez tres bien le java et ANT, et surtout vos design patterns !) j ai aucun probleme a ce que vous rejoignez le projet !


Message édité 1 fois, la dernière par kha le 30 août 2005 - 16 h 12.


Petit_PimoOosE
rsqrtps & pshufb

Messages : 4 616
Inscrit le 15/06/03
Ville : Montréal
Non connecté
  Posté le 30 août 2005 - 16 h 26 m 01 s
Il s'appelle comment, le projet ?



Huile de fraise.

kha
Google is your best friend

Messages : 1 235
Inscrit le 01/03/02
Ville : Montreal
Non connecté
  Posté le 31 août 2005 - 00 h 13 m 20 s
oups.

il s appelle jideoguard.

NB : j ai oublie qu il faut avoir installe sur son PC le Java Media Framework et le Java Advanced Imaging, de Sun. Je verrais + tard si je eux les fournir en tant que librairies.




kernelfg


Messages : 1
Inscrit le 14/09/05
Ville : paris
Non connecté
  Posté le 14 septembre 2005 - 13 h 06 m 09 s
En ce qui concerne la détection de mouvement , il y a un projet en cours de création (un projet de vidéosurveillance) qui s'appelle evids.
Le code source devrait être disponible prochainement. Tu peux probablement t'en inspirer. A voir sur http://www.evids.net




kha
Google is your best friend

Messages : 1 235
Inscrit le 01/03/02
Ville : Montreal
Non connecté
  Posté le 15 septembre 2005 - 05 h 14 m 59 s
Merci je regarderai.
En attendant que la detection soit plus poussee (cf aussi sites en bas), j ai fais un simple diff entre les pixels avec une tolerance.

http://bart.sm.luth.se/~mathed-8/mDec/index.html
http://bart.sm.luth.se/~linjan-1/
http://darnok.com/programming/motion-detection/




Precedent | 1,2
Page genérée en 1.8583 secondes par RahForum 2.0 | Gzip off |  Stats |  Metaforums |  RSS
© 2004 Cerbere Systems.
Prix Matériel Informatique | Informatique Lyon | Informatique Grenoble | Informatique Annecy | Informatique Marseille | Informatique Bordeaux | Forum Informatique
ADSL |Actualité ADSL | e-commerce | Commande Au Volant
Creative Commons
Message Boards and Forums Directory