Salut a tous,

En m'inspirant de ce site (introduction to programming with OpenCV) en particulier le paragraphe "Accessing image elements", dans la sous-section "Direct access using a c++ wrapper", j'ai réalisé une classe générique afin d'utiliser plus efficacement la bibliothèque OpenCV. Seulement je débute en programmation des template C++. Et j'ai quelque difficulté.

Tous d'abord voici mon code:
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
enum plan{GRIS=1, COULEUR=3};
 
struct RgbPixel{
	unsigned char b;
	unsigned char g;
	unsigned char r;
};
struct RgbPixelFloat{
	float b;
	float g;
	float r;
};
 
template<class T> class CCvImage{
 
public:
	CCvImage(void){m_img = NULL;}
	CCvImage(int hauteur, int largeur, plan canal= GRIS);
	CCvImage(string &name, plan canal = GRIS);
	CCvImage(IplImage* img) {m_img=img;}
	CCvImage(CCvImage<T>& img);
	~CCvImage();
	void free(){cvReleaseImage(&m_img);}
	void chargerImage(string &name, plan canal= GRIS);
	void allocation(int Hauteur, int Largeur, plan canal=GRIS);
	void toGrayScale();
	void affiche();
	void operator=(IplImage* img) {m_img=img;}
	CCvImage<T> operator= (CCvImage<T>& img);
	T* operator[] (const int x);
	operator IplImage *() const {return m_img;}
 
	//T* operator() (const int i);
 
	IplImage* getIplImage(){return m_img;}
	int getLargeur(){return m_img->width;}
	int getHauteur(){return m_img->height;}
	int getNbPixels(){return m_img->width*m_img->height;}
 
	void extract(CCvImage<T> &imgR, CCvImage<T> &imgG, CCvImage<T> &imgB, plan palette = GRIS);
 
private:
    T* CCvImage<T>::getPixel (const int x){return ((T*)(m_img->imageData + x*m_img->widthStep));}
	IplImage* m_img;
 
};
 
/*
  ////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
 ////                                                                          \\\\
                                     Définition
 \\\\                                                                          ////
  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////////
*/
template <typename T> CCvImage<T>::CCvImage(string &name, plan canal){
 
	chargerImage(name, canal);
 
}
template <typename T> CCvImage<T>::CCvImage(int hauteur, int largeur, plan canal){
 
	allocation(hauteur, largeur, canal);
 
}
template <typename T> CCvImage<T>::CCvImage(CCvImage<T>& img){
 
	this->m_img = cvCloneImage(img.getIplImage());
 
}
template <typename T> CCvImage<T>::~CCvImage(){
 
	free();
	m_img = NULL;
 
}
template <typename T> void CCvImage<T>::chargerImage(string &name, plan canal){
 
	switch(canal){
		case(1):
			m_img = cvLoadImage(name.c_str(),0);
			break;
		case(3):
			m_img = cvLoadImage(name.c_str(),1);
			break;
		default:
			m_img = cvLoadImage(name.c_str(),-1);
			break;
	}
 
}
template <typename T> void CCvImage<T>::allocation(int Hauteur, int Largeur, plan canal){
 
	m_img = cvCreateImage(cvSize(Largeur, Hauteur), 8, canal);
 
}
template <typename T> void CCvImage<T>::toGrayScale(){
 
	IplImage *temp = cvCreateImage(cvSize(getLargeur(), getHauteur()), 8, 1);
	cvCvtColor(m_img, temp, CV_BGR2GRAY);
	m_img = cvCloneImage(temp);
	cvReleaseImage(&temp);
 
}
template <typename T> void CCvImage<T>::affiche() {
 
    cvNamedWindow("Affichage", CV_WINDOW_AUTOSIZE);
    cvShowImage("Affichage", m_img);
    cvWaitKey(0);
    cvDestroyWindow("Affichage");
 
}
template <typename T> T* CCvImage<T>::operator[] (const int x){
 
	return ((T*)(m_img->imageData + x*m_img->widthStep));
 
}
template <typename T> CCvImage<T> CCvImage<T>::operator= (CCvImage<T>& img){
 
	this->m_img = cvCloneImage(img.getIplImage());
	return *this;
 
}
template <typename T> void CCvImage<T>::extract(CCvImage<T> &imgR, CCvImage<T> &imgG, CCvImage<T> &imgB, plan palette){
 
	if(this->m_img->nChannels == 1)
		throw string("Impossible d'extraire les plans RGB!");
 
	imgR.allocation(getHauteur(), getLargeur(), palette);
	imgG.allocation(getHauteur(), getLargeur(), palette);
	imgB.allocation(getHauteur(), getLargeur(), palette);
 
	IplImage* temp = cvCreateImage(cvSize(getLargeur(), getHauteur()), 8, palette);
	cvSplit((IplImage*)this->m_img, (IplImage*)imgR, (IplImage*)imgG, (IplImage*)imgB, temp);
	cvReleaseImage(&temp);
 
}
 
/*
  ////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
 ////                                                                          \\\\
                                  Fin Définition
 \\\\                                                                          ////
  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////////
*/
 
typedef CCvImage<RgbPixel> RgbImage;
typedef CCvImage<RgbPixelFloat> RgbImageFloat;
typedef CCvImage<unsigned char> BwImage;
typedef CCvImage<float> BwImageFloat;
Bon je reconnais, ce n'est pas très agréable à lire!
Mon problème se situe dans le fait que les pixels contenues dans ma classe image, sont soit représentés par une variable de type "unsigned char", "float" ou soit par une structure contenant un triplet de "unsigned char" ou de "float". En faite c'est le type de variable choisie pour représenté le pixel (en fonction que l'image est couleur ou non) qui est sensé être générique. Dans le cas de la fonction:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
template <typename T> void CCvImage<T>::extract(CCvImage<T> &imgR, CCvImage<T> &imgG, CCvImage<T> &imgB, plan palette)
je ne parvient pas à la rendre générique. L'objectif de cette fonction est d'extraire les trois plan RGB d'une image et de les stocker dans 3 images indépendantes.

C'est à ce niveau que j'ai besoin d'aide. J'espère être claire, et demandez-moi plus d'informations si nécessaire.
Merci d'avance!