IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

"Espace insuffisant pour traiter cette commande"


Sujet :

Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 130
    Points : 46
    Points
    46
    Par défaut "Espace insuffisant pour traiter cette commande"
    * Bonjour *

    Espace insuffisant pour traiter cette commande
    Voilà l'erreur qui apparait après quelques minutes pendant lesquelles mon programme delphi tourne avec un algorithme qui sert à détecter des mouvements sur une caméra.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    function detecter_mouvement_camera(image_camera_actuelle,image_camera_precedente:TBitmap):Integer;
    var i,j,difference,noise:integer;
    var pixelPointer1,pixelPointer2:PByteArray;
    begin
      difference:=0;
      i:=0; j:=0;
      MaFeuille := MonClasseur.GetByName('Feuille6');
      Cellule := Mafeuille.getCellByPosition(1,262);
      noise:=Cellule.GetValue;
      while (image_camera_actuelle.Height-1>i) do
      begin
        pixelPointer1:=image_camera_actuelle.ScanLine[i];
        pixelPointer2:=image_camera_precedente.ScanLine[i];
        while (image_camera_actuelle.Width-1>j) do
        begin
          if (ABS(pixelPointer1[3*j]-pixelPointer2[3*j])>=noise) AND (ABS(pixelPointer1[2*j]-pixelPointer2[2*j])>=noise) AND (ABS(pixelPointer1[1*j]-pixelPointer2[1*j])>=noise) then difference:=difference+1;
          j:=j+5;
        end;
        i:=i+5;
      end;
      Cellule := Mafeuille.getCellByPosition(1,263);
      Cellule.SetValue(difference);
      result:=difference;
    end;
     
     
     
     
    procedure TForm1.Timer2Timer(Sender: TObject);
    var SPS: TSystemPowerStatus;
    var val:Integer;
    var seuil1,seuil2:Integer;
    var image_camera_actuelle:Tbitmap;
    begin
       if webcam_initialisation=True then
       begin
       if camera_affichage=False then Form1.Image29.Visible:=False;
       if (camera_affichage=True) and (Edit1.Text='') then 
       begin
       image_camera_actuelle:=Tbitmap.Create;
       MaFeuille := MonClasseur.GetByName('Feuille6');
       Cellule := Mafeuille.getCellByPosition(1,260);
       seuil1:=Cellule.GetValue;
       Cellule := Mafeuille.getCellByPosition(1,261);
       seuil2:=Cellule.GetValue;
       sendmessage(hcam,1084,0,0);
       sendmessage(hcam,1054,0,0);
       Form1.image29.Picture.LoadFromClipboardFormat(cf_bitmap,clipboard.GetAsHandle(cf_bitmap),0);
     
        image_camera_actuelle.FreeImage;
        FreeAndNil(image_camera_actuelle);
        image_camera_actuelle:=TBitmap.Create;
        image_camera_actuelle.Assign(Form1.image29.Picture.Bitmap);
        if bascule=True then begin image_camera_precedente.Assign(image_camera_actuelle); bascule:=False; end;
        if (detecter_mouvement_camera(image_camera_actuelle,image_camera_precedente)>=seuil2) and (mouvement_devant_camera=False) then begin mouvement_devant_camera:=True; affiche_6(256); image_camera_precedente.FreeImage; FreeAndNil(image_camera_precedente); image_camera_precedente:=TBitmap.Create; image_camera_precedente.Assign(image_camera_actuelle); exit; end;
        if (detecter_mouvement_camera(image_camera_actuelle,image_camera_precedente)<seuil1) and (mouvement_devant_camera=True) then begin mouvement_devant_camera:=False; affiche_6(257); image_camera_precedente.FreeImage; FreeAndNil(image_camera_precedente); image_camera_precedente:=TBitmap.Create; image_camera_precedente.Assign(image_camera_actuelle); exit; end;
        image_camera_precedente.FreeImage;
        FreeAndNil(image_camera_precedente);
        image_camera_precedente:=TBitmap.Create;
        image_camera_precedente.Assign(Form1.image29.Picture.Bitmap);
       end;
       end;
    end;
    C'est la fonction TForm1.Timer2Timer(Sender: TObject); qui à intervalles réguliers (1/2 seconde) prend une image de la webcam et la compare à l'image précédente.
    Le programme fonctionne très bien pendant quelques minutes. Et puis ça plante, l'erreur "Espace insuffisant pour traiter cette commande" se répète en boucle...
    J'ai pourtant mis des FreeImage et FreeAndNil mais il n'y a rien à faire...

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 130
    Points : 46
    Points
    46
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    image_camera_actuelle.FreeImage;
        FreeAndNil(image_camera_actuelle);
        image_camera_actuelle:=TBitmap.Create;
    Je viens de me rendre compte que je libérais la mémoire AVANT de créer la variable Bitmap. Du coup, j'imagine qu'à chaque appel de la procedure TTimer, je ne libérai aucune mémoire, le FreeImage et FreeAndNil n'accédant pas à l'appel précédent à la fonction.
    J'ai modifié le code et j'ai testé ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    image_camera_actuelle:=TBitmap.Create;
        image_camera_actuelle.Assign(Form1.image29.Picture.Bitmap);
        if bascule=True then begin image_camera_precedente.Assign(image_camera_actuelle); bascule:=False; end;
     
        if (detecter_mouvement_camera(image_camera_actuelle,image_camera_precedente)>=seuil2) and (mouvement_devant_camera=False) then begin mouvement_devant_camera:=True; affiche_6(256); image_camera_precedente.FreeImage; FreeAndNil(image_camera_precedente); image_camera_precedente:=TBitmap.Create; image_camera_precedente.Assign(image_camera_actuelle); exit; end;
        if (detecter_mouvement_camera(image_camera_actuelle,image_camera_precedente)<seuil1) and (mouvement_devant_camera=True) then begin mouvement_devant_camera:=False; affiche_6(257); image_camera_precedente.FreeImage; FreeAndNil(image_camera_precedente); image_camera_precedente:=TBitmap.Create; image_camera_precedente.Assign(image_camera_actuelle); exit; end;
        image_camera_actuelle.FreeImage;
        FreeAndNil(image_camera_actuelle);
        image_camera_precedente.FreeImage;
        FreeAndNil(image_camera_precedente);
        image_camera_precedente:=TBitmap.Create;
        image_camera_precedente.Assign(Form1.image29.Picture.Bitmap);
    Au bout d'un quart d'heure de test, pas de bug. J'ai l'impression d'être Edison qui teste sa première ampoule en espérant qu'elle ne grille pas trop vite

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 671
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    Ça m'empêchera pas d'avoir un memory leak puisque tu crées systématiquement une image_camera_actuelle qui n'est pas détruite s'il y a mouvement

    Il n'est pas non plus utile de faire un FreeImage suivi d'un FreeAndNil suivi d'un... Create et d'un Assign. Crée une fois pour toute les bitmaps dans OnCreate et détruis-les dans OnDestroy. Seul Assign reste.

    Enfin, ta détection de mouvement est assez bizarre ! Tu ne contrôles qu'une seule composante couleur par pixel et modifie la composante testée à chaque boucle tout en omettant un pixel toute les N boucle (+5 bytes sur un bitmap 24 bits) Sans parler que si Bascule vaut TRUE, tout ces tests sont inutiles puisque les deux images sont identiques

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 130
    Points : 46
    Points
    46
    Par défaut
    Il me semblait récupérer les 3 composantes RVB avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (ABS(pixelPointer1[3*j]-pixelPointer2[3*j])>=noise) AND (ABS(pixelPointer1[2*j]-pixelPointer2[2*j])>=noise) AND (ABS(pixelPointer1[1*j]-pixelPointer2[1*j])>=noise) then difference:=difference+1;
    J'ai changé ça en :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (ABS(pixelPointer1[j]-pixelPointer2[j])>=noise) then difference:=difference+1;
    Pour ce qui est de la bascule, c'est normal puisque mon logiciel ne nécessite pas l'utilisation de la webcam par défaut. C'est par un clic sur un bouton que le programme analyse les images.
    Sinon, oui pour la mémory leak en cas de mouvement, je vais modifier ça.

Discussions similaires

  1. [WD18] crash bizarre "Espace insuffisant pour traiter cette commande"
    Par alaclef dans le forum WinDev
    Réponses: 2
    Dernier message: 08/05/2015, 17h30
  2. Réponses: 5
    Dernier message: 24/03/2010, 23h20
  3. Gtk Gdk "Espace insuffisant pour traiter cette commande"
    Par gy0m76 dans le forum GTK+ avec C & C++
    Réponses: 2
    Dernier message: 19/05/2009, 13h24
  4. Mémoire insuffisante sur le serveur pour traiter cette commande
    Par Cr@zyDeep dans le forum Windows Serveur
    Réponses: 0
    Dernier message: 04/06/2008, 12h34
  5. Réponses: 4
    Dernier message: 09/06/2005, 00h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo