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:
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:
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.
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:
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?