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

OpenCV Discussion :

Segmentation fault lors de l'appel du destructeur d'un Mat


Sujet :

OpenCV

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Segmentation fault lors de l'appel du destructeur d'un Mat
    Bonsoir,
    je débute avec opencv et je galère...

    L'objectif est d'appliquer un filter gaussien mais le programme plante et je n'arrive pas à savoir pourquoi.
    Lorsque gaussian à fini de s’exécuter, le destructeur de old est appelé et release (qui est appelée par le destructeur) plante (Segmentation fault).
    Si je met la ZONE en commentaire, ça ne plante pas.

    Merci

    main.cpp
    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
    int main(int argc, char ** argv) {
     
        // Touche clavier
        char key;
     
        VideoCapture cam(0);
        if(!cam.isOpened()){
            cout << "impossible d'ouvrir la cam!";
            return 0;
        }
     
        Mat imgCam;
     
        cam.read(imgCam);
     
     
        //initlisation du filtre
        Filter filter;
        filter.gaussianKernelGeneration(0.625);
     
     
        cout << "Debut\n";
        // Boucle tant que l'utilisateur n'appuie pas sur la touche q (ou Q)
        while(key != 'q' && key != 'Q') {
            cam.read(imgCam);
            Mat laplace;
            laplace = imgCam.clone();
     
     
            filter.gaussian(laplace);
     
            imshow( "laplace", imgCam ); 
            imshow( "Cam", imgCam ); 
            key = waitKey(10);
        }
     
     
        return 0;
    }
    filter.cpp
    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
    void Filter::gaussian(Mat &img){
     
        Mat old = img.clone();
        //  cout << "Gaussian filter ...\n";
        for(int x = 0; x < img.cols; x++) {
            for(int y=0; y < img.rows; y++) {
               Filter::localGaussian(img, old, Point(x, y));
            }
        }
    }
     
    void Filter::localGaussian(Mat &img, const Mat &old, const Point &p){
    	float sommeR =0, sommeG=0, sommeB=0;
    	float diviseur = 0;
     
    	//(i,j) coordonnées sur le kernel
    	//(ii, jj) coordonnées sur l'image
    	int ii, jj;
        float valK; //coef du kernel
        unsigned char *input = (unsigned char*)(img.data);
     
    	for(int i = 0; i < this->gaussianKernel.rows; i++) {
    		ii= i + (p.x-this->gaussianKernel.rows);
     
            for(int j= 0; j < this->gaussianKernel.cols; j++) {
            	jj= j + (p.y - this->gaussianKernel.cols);
     
                if(jj>=0 && jj<old.cols && ii>=0 && ii<old.rows){
                    valK = this->gaussianKernel.at<float>(i, j);
     
                    sommeB += valK * input[old.step*j + i];
                    sommeG += valK * input[old.step*j + i + 1];
                    sommeR += valK * input[old.step*j + i + 2];
     
                    diviseur += valK;
                }
            }
        }
     
    /** ZONE  **/
        img.at<Vec3b>(p.x , p.y)[0] = diviseur > 0 ? (char)(sommeB/diviseur) : 0;
        img.at<Vec3b>(p.x , p.y)[1] = diviseur > 0 ? (char)(sommeG/diviseur) : 0;
        img.at<Vec3b>(p.x , p.y)[2] = diviseur > 0 ? (char)(sommeR/diviseur) : 0;
    /** FIN ZONE  **/
    }

    EDIT : Du coup j'ai utilisé IplImage à la place d'un Mat et c'est (preque) bon.
    Mais si quelqu’un me dit pourquoi mon code précédent ne marche pas je suis preneur.

  2. #2
    Membre actif

    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2008
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2008
    Messages : 170
    Points : 202
    Points
    202
    Par défaut Pourquoi reprogrammes tu le filtre gaussien?
    Je ne comprends pas bien pourquoi tu veux recoder un filtre gaussien, car il y a tout ce qu'il faut dans opencv pour faire du filtrage, et en plus ça s’exécutera 1000 fois plus vite que ton propre code.

    C'est assez rare que les cv::Mat plante, mais des fois on arrive à les tromper. Il y a un compteur de référence qui lorsqu'il arrive à zéros désalloue la mémoire. Or dans ton cas, la mémoire aurait déjà etait désalloué... Ca me parrait suspect, car il aurait fallu que tu passes par des pointeurs sur des cv::Mat pour metre un tel bordel dans la mémoire...

    As-tu vérifier ques tes cv::Mat contiennent bien ce qu'elles doivent contenir avant la dés-allocation?
    Sinon, quand je lis ton code, ca me parait étrange... Est-ce normal que tu lises tes données dans img et que tu y écrives aussi le résultat? Je ne pense pas que l'on puisse faire un filtre avec voisinage en 'in place", non?
    Ta matrice old ne te sert qu'a lire les dimensions pour tes boucles de parcours, alors que ce sont les memes que img... Peut-etre ai-je raté quelque chose, mais tout ca me semble pas correcte. Tu ne touche jamais aux données de old.

    Je pense que tu voulais écrire ca plutot, non?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
          /** ZONE  **/
          old.at<Vec3b>(p.x , p.y)[0] = diviseur > 0 ? (char)(sommeB/diviseur) : 0;
          old.at<Vec3b>(p.x , p.y)[1] = diviseur > 0 ? (char)(sommeG/diviseur) : 0;
          old.at<Vec3b>(p.x , p.y)[2] = diviseur > 0 ? (char)(sommeR/diviseur) : 0;
          /** FIN ZONE  **/
    PS: Tu travailles bien avec des images couleur?

Discussions similaires

  1. segmentation fault lors de l'utilisation de strcpy
    Par simplyc dans le forum Débuter
    Réponses: 18
    Dernier message: 17/01/2011, 19h52
  2. Segmentation Fault lors de mise à jour d'image par callback
    Par bboy_keen dans le forum GTK+ avec C & C++
    Réponses: 7
    Dernier message: 07/12/2010, 00h16
  3. segmentation fault lors d'un pthread_create
    Par Anouschka dans le forum POSIX
    Réponses: 2
    Dernier message: 09/06/2010, 17h53
  4. erreur "Segmentation Fault" lors de l'import d'un dump
    Par farenheiit dans le forum Import/Export
    Réponses: 13
    Dernier message: 28/11/2007, 10h17
  5. PB segmentation fault lors d'installation RPM
    Par Asce_ dans le forum RedHat / CentOS / Fedora
    Réponses: 3
    Dernier message: 06/11/2007, 11h22

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