Utilisation de templates un peu spécifique

Résolu
wilvart Messages postés 47 Date d'inscription samedi 7 janvier 2006 Statut Membre Dernière intervention 13 décembre 2012 - 20 avril 2012 à 18:37
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 - 24 avril 2012 à 11:19
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

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
24 avril 2012 à 10:35
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
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
20 avril 2012 à 18:57
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
0
wilvart Messages postés 47 Date d'inscription samedi 7 janvier 2006 Statut Membre Dernière intervention 13 décembre 2012
24 avril 2012 à 10:19
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?
+
0
wilvart Messages postés 47 Date d'inscription samedi 7 janvier 2006 Statut Membre Dernière intervention 13 décembre 2012
24 avril 2012 à 11:10
... Je suis naze sur ce coup là...

Merci beaucoup en tout cas, ça marche à merveille !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
24 avril 2012 à 11:19
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
0
Rejoignez-nous