Filter sober in c++ don't pass test

26 views Asked by At

I am working on implementing the Sobel filter for image processing in C++. However, I am encountering unexpected results and failing test cases. I have reviewed the code multiple times, but I cannot pinpoint the source of the issue.

I have provided the relevant parts of my code below. The intensiteH and intensiteV functions are intended to calculate the horizontal and vertical gradients using the Sobel operator, and the intensite function combines these gradients to compute the overall intensity.

#include <stdexcept>
/** @file
 * Filtres de Sobel
 **/
#include <cmath>
#include <vector>
#include <stdexcept>
#include <iostream>
#include <fstream>
using namespace std;

/** Structure de donnee pour representer une image en teintes de gris **/
typedef vector<vector<double> > ImageGris;



/** Infrastructure minimale de test **/
#define CHECK(test) if (!(test)) cerr << "Test failed in file " << __FILE__ << " line " << __LINE__ << ": " #test << endl


/** Une image 4x4 en teintes de gris pour faire des tests **/
ImageGris imgGrisTest = {
    {0, 255, 54.213, 236.589},
    {18.411, 182.376, 200.787, 120},
    {139.583, 172.841, 94.0878, 88.4974},
    {158.278, 172.841, 89.0236, 80.0384}
};



/** Construire une image en teintes de gris depuis un fichier PGM
 * @param source le nom d'un fichier PGM
 * @return une image en teintes de gris
 **/
ImageGris lirePGM(string source) {
   // Déclarations
  ifstream pgm ;    
  pgm.open(source);
  ImageGris imagegris;
       if (!pgm) {
    throw runtime_error("Fichier non trouve: "+source);}
   
 
    if (pgm.is_open()) {
        char type[3]; // stocke type du fichier pbm sous forme de tableau contenant P,2,'\0
        int largeur, hauteur , max ;
       
       // Lecture de l'en-tête du fichier PBM
        pgm >> type >> largeur >> hauteur >> max ;

        if (type[0] == 'P' && type[1] == '2') {
           
          imagegris = vector<vector<double>>(hauteur, vector<double>(largeur)); // car ImageGris est un type                                                                                    et non une variable
           
                                             
                                               
      for (int i=0 ; i<hauteur ; i++){
        for (int j=0 ; j<largeur ; j++){
        pgm>>imagegris[i][j];}        
                                       }
                                     }
   
        pgm.close() ;
                     }
   
      return imagegris ;
                        
}



/** Ecrit une image en teintes de gris dans un fichier PGM
 * @param img une image en teintes de gris
 * @param cible le nom d'un fichier PGM
 **/
void ecrirePGM(ImageGris img, string cible) {
   ofstream pgm ;
  pgm.open(cible);
    if (!pgm) {
    throw runtime_error("Fichier non trouve: "+cible);}
   
    //écriture de l'en-tête
 
     if (pgm.is_open()) {
       pgm<<"P2"<<endl ;  
        pgm<<img[0].size()<<" "<<img.size()<<endl;  
        pgm<<255<<endl;
     
     //" " permet de séparer chaque pixel par un espace  // endl pour aller à la ligne une fois que tous les        pixels sur la ligne ont été écrits
                                                 
      for (int i=0 ; i<img[0].size() ; i++)  {
        for (int j=0 ; j<img.size() ; j++) {
         pgm<<(int)img[i][j]<<" ";         }        
                                             }
        pgm<<endl ;
                         }
        pgm.close();
}








/** Teste si deux images en teintes de gris sont égales modulo imprécision numérique
 * En cas de différence un message est affiché
 * @param a une image en teintes de gris
 * @param b une image en teintes de gris
 * @param precision un flottant positif: la précision souhaitée; typiquement 0.001
 * @return vrai si les images sont égales et faux sinon
 **/
bool ImageGrisEgal(ImageGris a, ImageGris b, float precision) {
    if (a.size() != b.size())  {
        cout << "Nombre de lignes différent" << endl;
        return false;
    }
    for (int i=0; i<a[0].size(); i++)
        if (a[0].size() != b[i].size()) {
            cout << "Nombre de colonnes différent" << endl;
            return false;
        }
    for (int i=0; i<a.size(); i++)
        for (int j=0; j<a[0].size(); j++)
            if (abs(a[i][j] - b[i][j]) > precision) {
                cout << "Valeur differentes en position " << i << "," << j
             << ": " << a[i][j] << " au lieu de " << b[i][j] << endl;
                return false;
            }
    return true;
}

/// BEGIN intensiteH

/** filtre de Sobel horizontal
 * @param img une image en teintes de gris
 * @return une image en teintes de gris de l'intensite horizontale de img
 **/
ImageGris intensiteH(ImageGris img) {
    double gradx ; // gradient horizontal de l'image
    ImageGris intensiteho(img.size(), vector<double>(img[0].size())); //image de retour est de même taille que 
  for ( int i=0; i<img.size();i++){
        for ( int j =0 ; j<img[0].size();j++){
            if (i > 0 && i < img.size() - 1 && j > 0 && j < img[0].size() - 1) {
    gradx = (img[i - 1][j - 1] + 2 * img[i][j - 1] + img[i + 1][j - 1]) - (img[i - 1][j + 1] + 2 * img[i][j + 1] + img[i + 1][j + 1]);
}

        }
   }
 return intensiteho ;
}


/// BEGIN intensiteV

/** filtre de Sobel vertical
 * @param img une image en teintes de gris
 * @return une image en teintes de gris de l'intensite verticale de img
 **/
ImageGris intensiteV(ImageGris img) {
    double grady ; // gradient vertical de l'image
    ImageGris intensitever(img.size(), vector<double>(img[0].size())); //image de retour est de même taille que 
  for ( int i=0; i<img.size();i++){
        for ( int j =0 ; j<img[0].size();j++){
              if (i > 0 && i < img.size() - 1 && j > 0 && j < img[0].size() - 1) {
           grady = img[i-1][j-1] + 2*img[i-1][j] + img[i-1][j+1] - img[i+1][j-1] - 2*img[i+1][j] - img[i+1][j+1] ;
            intensitever[i][j]=grady ;

        }
   }
  }
 return intensitever ;
}


/// BEGIN intensiteHV

/** filtre de Sobel
 * @param img une image en teintes de gris
 * @return une image en teintes de gris de l'intensite de img
 **/
ImageGris intensite(ImageGris img) {
    ImageGris IntensiteHo=intensiteH(img);
    ImageGris IntensiteVe=intensiteV(img);
    ImageGris Intensiteimg(img.size(), vector<double>(img[0].size()));
     for ( int i=0; i<img.size();i++){
        for ( int j =0 ; j<img[0].size();j++){
           double valintensite = sqrt(IntensiteHo[i][j]*IntensiteHo[i][j] +IntensiteVe[i][j]*IntensiteVe[i][j] ) ;
           Intensiteimg[i][j]=valintensite;

        }
    }
    return Intensiteimg ;
}


void testSobel() {
    CHECK( ImageGrisEgal(intensiteH(imgGrisTest),
              ImageGris( {
                  {0, 0, 0, 0},
                  {0, -373.47, 227.507, 0},
                  {0, -22.1312, 323.866, 0},
                  {0, 0, 0, 0}
              }),
              0.001) ); // precision changée
    CHECK( ImageGrisEgal(intensiteV(imgGrisTest),
              ImageGris( {
                  {0, 0, 0, 0},
                  {0, -15.1398, 150.501, 0},
                  {0, -9.0336, 273.023, 0},
                  {0, 0, 0, 0}
              }),
              0.001) );
    CHECK( ImageGrisEgal(intensite(imgGrisTest),
              ImageGris( {
                  {0, 0, 0, 0},
                  {0, 373.777, 272.782, 0},
                  {0, 23.9039, 423.593, 0},
                  {0, 0, 0, 0}
              }),
              0.001) );

    cout << "Vérifier que les images obtenues dans 'sobel/' sont semblables à celles fournies dans 'sobel/correction/'" << endl;
    ecrirePGM(intensite(lirePGM("images/Willis.512.pgm" )), "sobel/Willis.512.pgm");
    ecrirePGM(intensite(lirePGM("images/Baboon.512.pgm" )), "sobel/Baboon.512.pgm");
    ecrirePGM(intensite(lirePGM("images/Billes.256.pgm" )), "sobel/Billes.256.pgm");
    ecrirePGM(intensite(lirePGM("images/Embryos.512.pgm")), "sobel/Embryos.512.pgm");
    ecrirePGM(intensite(lirePGM("images/House.256.pgm"  )), "sobel/House.256.pgm");
}



int main(){

    testSobel();
    return 0 ;
}


I tried to run my code but the tests were failing , here is an example :Valeur differentes en position 1,1: -96.2992 au lieu de -373.47 Test failed in file sobel-tout-en-un.cpp line 200: ImageGrisEgal(intensiteH(imgGrisTest), ImageGris( { {0, 0, 0, 0}, {0, -373.47, 227.507, 0}, {0, -22.1312, 323.866, 0}, {0, 0, 0, 0} }), 0.01) Valeur differentes en position 1,1: 97.482 au lieu de 373.777 Test failed in file sobel-tout-en-un.cpp line 216: ImageGrisEgal(intensite(imgGrisTest), ImageGris( { {0, 0, 0, 0}, {0, 373.777, 272.782, 0}, {0, 23.9039, 423.593, 0}, {0, 0, 0, 0} }), 0.001)

0

There are 0 answers