Utilisation de templates un peu spécifique [Résolu]

Signaler
Messages postés
47
Date d'inscription
samedi 7 janvier 2006
Statut
Membre
Dernière intervention
13 décembre 2012
-
Messages postés
3820
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
1 décembre 2020
-
Salut !

J'ai besoin d'un coup de main dans l'utilisation des templates.

J'utilise une lib de traitement d'image(opencv) dans laquelle une image est stockée dans une matrice class cv::Mat.
Cette classe a un argument qui m'interesse tout particulièrement, 'type'.
'type' est une énumération (CV_8UC1, CV8UC3, CV_32SC1...) qui décrit comment les informations contenues dans la matrice sont stockées en mémoire (int, uchar, short...).

Mon problème est le suivant, en fonction du type de matrice que j'utilise, le traitement n'est pas le même. Ainsi, pour colorier (oui oui colorier :D) mes pixels, je suis obligé de créer une fonction pour chaque type de matrice et je trouve pas ça très propre...
J'ai en prime une petite fonction de parsing pour me renvoyer vers la bonne fonction de coloriage.

Je vous sollicite donc pour savoir s'il est possible de définir le type d'un templates, OU si je dois utiliser une toute autre méthode (dans ce cas là vos propositions sont les bienvenues)


#ifndef ABSTRACT_COMMANDE_HPP
#define ABSTRACT_COMMANDE_HPP

#include "morphinAbstract.hpp"
#include <opencv2/opencv.hpp>

class AbstractCommand : public MorphinAbstract
{

};


#endif



#ifndef PAINT_BY_LEVEL_ALGORITHM_HPP
#define PAINT_BY_LEVEL_ALGORITHM_HPP

#include <opencv2/opencv.hpp>
#include "abstractAlgorithm.hpp"

class PaintByLevelAlgorithm : public AbstractAlgorithm
{
    public:
static void execute (const cv::Mat *input, cv::Mat *dst);

private:
static void execute8UC1 (const cv::Mat *input, cv::Mat *dst);
static void execute32SC1 (const cv::Mat *input, cv::Mat *dst);
};

#endif



#include "paintByLevelAlgorithm.hpp"

// input : 8UC1, 32SC1 image     output : 8UC3 image
void PaintByLevelAlgorithm::execute (const cv::Mat *input, cv::Mat *dst)
{
// Parse by type
switch ((*input).depth())
{
  case CV_8U :
PaintByLevelAlgorithm::execute8UC1(input, dst);
    break;

  case CV_32S : 
    PaintByLevelAlgorithm::execute32SC1(input, dst);
    break;

  default :
    cout << "default" << endl;

}
}


void PaintByLevelAlgorithm::execute8UC1 (const cv::Mat *input, cv::Mat *dst)
{
cv::Point point;
int greyValue;

for (point.x=0; point.x<(*input).size().width; point.x++)
{
for (point.y=0; point.y<(*input).size().height; point.y++)
{
if ((*input).at(point) > 0)
{
greyValue = (*input).at(point);
line(*dst, point, point, cv::Scalar((50+greyValue*5)%255, 50+greyValue*51%255, 255-(greyValue*13%255)), 1, 8, 0);
}
}
}
}


void PaintByLevelAlgorithm::execute32SC1 (const cv::Mat *input, cv::Mat *dst)
{
cv::Point point;
int greyValue;

for (point.x=0; point.x<(*input).size().width; point.x++)
{
for (point.y=0; point.y<(*input).size().height; point.y++)
{
if ((*input).at(point) > 0)
{
greyValue = (*input).at(point);
line(*dst, point, point, cv::Scalar((50+greyValue*5)%255, 50+greyValue*51%255, 255-(greyValue*13%255)), 1, 8, 0);
}
}
}
}

5 réponses

Messages postés
3820
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
1 décembre 2020
113
N'ayant pas ton code, j'ai crée un exemple minimaliste pour te montrer le principe:
#include 

typedef unsigned char uchar;

namespace cv
{
  struct Mat
  {
    int depth() const
    {
      return 0;
    }


  };
}

class PaintByLevelAlgorithm
{
public:
  void execute(const cv::Mat* input, cv::Mat* dst);

  template <typename T>
  void executeC1(const cv::Mat* input, cv::Mat* dst);
};

void PaintByLevelAlgorithm::execute(const cv::Mat* input, cv::Mat* dst)
{
  switch ((*input).depth())
  {
    case /*CV_8U*/ 1:
      executeC1(input, dst);
      break;

    case /*CV_32S*/ 2:
      executeC1(input, dst);
      break;
    default :
      std::cout << "default" << std::endl;

  }
}

template <typename T>
void PaintByLevelAlgorithm::executeC1(const cv::Mat*, cv::Mat*)
{
  std::cout << "ok" << std::endl;
}

int main()
{
  cv::Mat a;
  cv::Mat b;
  PaintByLevelAlgorithm algo;

  algo.execute(&a, &b);

  return 0;
}


Si ça ne fonctionne pas chez toi, ce n'est pas un problème de template, c'est une erreur ailleurs dans ton code.

error: prototype for ‘void PaintByLevelAlgorithm::executeC1(const cv::Mat*, cv::Mat*)’ does not match any in class ‘PaintByLevelAlgorithm’

Si tu lis le message d'erreur, ta fonction dans le fichier de code n'a pas d'équivalent dans le header. Tu as peut être oublié d'écrire "template" dans ton code ou dans ton header...

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
3820
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
1 décembre 2020
113
Bonjour.

Si les méthodes ne diffèrent que par le ".at<type>" alors oui c'est possible et c'est très simple :)

Pas testé, mais le principe devrait être le suivant:

void PaintByLevelAlgorithm::execute(const cv::Mat *input, cv::Mat *dst)
{
// Parse by type
switch ((*input).depth())
{
  case CV_8U :
            PaintByLevelAlgorithm::executeC1(input, dst);
    break;

  case CV_32S : 
    PaintByLevelAlgorithm::executeC1(input, dst);
    break;

  default :
    std::cout << "default" << std::endl;

}
}

template <typename T>
void PaintByLevelAlgorithm::executeC1(const cv::Mat *input, cv::Mat *dst)
{
cv::Point point;
int greyValue;

for (point.x=0; point.x<(*input).size().width; point.x++)
{
for (point.y=0; point.y<(*input).size().height; point.y++)
{
if ((*input).at<T>(point) > 0)
{
greyValue = (*input).at<T>(point);
line(*dst, point, point, cv::Scalar((50+greyValue*5)%255, 50+greyValue*51%255, 255-(greyValue*13%255)), 1, 8, 0);
}
}
}
}


PS: Évite les "using namespace", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Messages postés
47
Date d'inscription
samedi 7 janvier 2006
Statut
Membre
Dernière intervention
13 décembre 2012

Salut,

Je te remercie de ton aide mais je suis toujours perdu... Le compilo n'aime pas trop ce que t'as écris :

src/paintByLevelAlgorithm.cpp: In static member function ‘static void PaintByLevelAlgorithm::execute(const cv::Mat*, cv::Mat*)’:
src/paintByLevelAlgorithm.cpp:10: error: expected primary-expression before ‘>’ token

PaintByLevelAlgorithm::executeC1(input, dst);



src/paintByLevelAlgorithm.cpp:14: error: expected primary-expression before ‘int’
src/paintByLevelAlgorithm.cpp:14: error: expected `;' before ‘int’

PaintByLevelAlgorithm::executeC1(input, dst);



src/paintByLevelAlgorithm.cpp: At global scope:
src/paintByLevelAlgorithm.cpp:23: error: prototype for ‘void PaintByLevelAlgorithm::executeC1(const cv::Mat*, cv::Mat*)’ does not match any in class ‘PaintByLevelAlgorithm’
src/paintByLevelAlgorithm.hpp:13: error: candidate is: static void PaintByLevelAlgorithm::executeC1(const cv::Mat*, cv::Mat*)
src/paintByLevelAlgorithm.cpp:23: error: template definition of non-template ‘void PaintByLevelAlgorithm::executeC1(const cv::Mat*, cv::Mat*)’

template <typename T> void PaintByLevelAlgorithm::executeC1(const cv::Mat *input, cv::Mat *dst)


J'ai lu pas mal de doc sur les templates mais je n'arrive pas à 'reformuler' ce que tu m'as donné. T'as un tuto plutôt bien foutu?
+
Messages postés
47
Date d'inscription
samedi 7 janvier 2006
Statut
Membre
Dernière intervention
13 décembre 2012

... Je suis naze sur ce coup là...

Merci beaucoup en tout cas, ça marche à merveille !
Messages postés
3820
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
1 décembre 2020
113
T'as un tuto plutôt bien foutu?

J'ai oublié de répondre à ta question :).

Pour tout ce qui concerne les templates, il existe deux livres considérés comme des références. Ils ne sont pas destinés aux débutants, mais permettent de maîtriser en profondeur les templates:
- http://ecx.images-amazon.com/images/I/516030XDD8L._SS500_.jpg
- http://images-eu.amazon.com/images/P/0321227255.01.LZZZZZZZ.jpg

(À lire dans l'ordre, le deuxième étant bien plus dur à comprendre que le premier).

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question