Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » operation auf verschiedene datentypen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
31.10.2011, 11:11 Uhr
cmos



Hallo,
ich habe ein paar Fragen zu operationen auf verschiedene Datentypen.
Es gibt viele Bibliotheken für die Bildverarbeitung z.B. opencv, evision, halcon, cimg etc.
Diese unterstützen verschieden Datentypen z.b. Bilder mit float, char oder integer als Pixelwert. Wenn nun ein Filter auf ein Bild angewandt wird, muss ja der Datentyp bekannt sein.
Wie handhaben es solche Bibliotheken mit verschiedenen Datentypen ? Ok, es können templates verwendet werden, aber da muss doch der Code, z.B. für einen Filter, mitgeliefert werden und ist nicht in der eigentlichen lib enthalten. Oder es kann im Filtercode nach dem Datentyp gefragt werden und der Code ist dann mehrmals für die unterstützen Datentypen vorhanden. Aber das is nicht sehr elegant und bei Änderungen muss an mehreren Stellen nachgebessert werden.

Wie kann z.B. der Code für einen Filter geschrieben werden, der für Bilder mit unterschiedlichen Datentyp nutzbar ist ohne dabei auf templates zurückzugreifen. Spätestens an der Stelle, an der mit einem Zeiger auf die Pixelzugegriffen wird muss doch der Datentyp klar sein.

Grüße,
cmos
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
31.10.2011, 13:59 Uhr
ao

(Operator)


MUSS auf Templates verzichtet werden? Oder willst du nur, dass das nicht sichtbar ist?

Spontan fällt mir sowas hier ein. Ist vermutlich ziemlich dreckig, aber so als Anregung, wie es gehen könnte ...

Soll es in C sein (Templates nicht möglich), dann müsste man das irgendwie mit dem Preprocessor hinkriegen. Ist aber wohl noch dreckiger ...


C++:
//

#include "stdafx.h"

enum FILTER_RESULT
{
    OK
    , ERROR
};

enum PIXEL_TYPE
{
    FLOAT
    , CHAR
    , INT
};

PIXEL_TYPE GetPixelType (const void * imageData)
{
    return INT;    //    den Datentyp irgendwie ausbaldowern
}

//  Diese Template-Funktion realisiert den Filter
//  für den gegebenen Datentyp T.
template <typename T>
FILTER_RESULT typedFilter (T * outPixels, const T * inPixels)
{
    *outPixels = *inPixels * 2;    // hier wird die Rechnerei hingeschrieben
    return OK;
}

//  Dieser Wrapper ermittelt den Pixeltyp und instanziert
//  die dazu passende Filterfunktion (typedFilter) und ruft sie auf.
FILTER_RESULT filter (
    void * outData                //    Generische Zeiger
    , const void * inData        //    auf die Daten
    //    hier kommen noch in irgendeiner Form die Abmessungen des Bildes
    //    sowie Parameter für den Filter
  )
{
  FILTER_RESULT result = ERROR;

  PIXEL_TYPE type = GetPixelType (inData);
  switch (type)
  {
  case FLOAT:
      {
          float * inPixels = (float *) inData;            //    Typisierte Zeiger auf die Daten. Um dem Compiler
          float * outPixels = (float *) outData;        //    zu zeigen, welche Instanzierung wir wollen.

          result = typedFilter (inPixels, outPixels);    //    Template-Funktion instanzieren für float-Daten
      }
      break;

  case INT:
      {
          int * inPixels = (int *) inData;
          int * outPixels = (int *) outData;

          result = typedFilter (inPixels, outPixels);    //    Template-Funktion instanzieren für int-Daten
      }
      break;

  case CHAR:
      {
          char * inPixels = (char *) inData;
          char * outPixels = (char *) outData;

          result = typedFilter (inPixels, outPixels);    //    Template-Funktion instanzieren für char-Daten
      }
      break;

  }
  return result;
}



int _tmain(int argc, _TCHAR* argv[])
{

    //  Beispiel: Float-Daten.
    //  Das "Bild" besteht aus einem Pixel und wird in-Place geändert.
    float f = 1;
    typedFilter (&f, &f);

    //  Dasselbe für int-Daten
    int i = 1;
    typedFilter (&i, &i);

    //  ... und für char-Daten.
    char c = 1;
    typedFilter (&c, &c);
    
    return 0;
}



Dieser Post wurde am 31.10.2011 um 14:01 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
31.10.2011, 15:32 Uhr
cmos



Hallo und vielen Dank für die ausfühliche Antwort.
Wenn man um templates nicht herumkommt, kann man mit Templatespezialisierung die Implementierung "unsichtbar" machen ? Templatedefinition und Implementierung kann ich zwar trennen, aber trotzdem muss ich bisher immer diese Implementierungsdatei mitliefern.


C++:
// file: FilterT.h
template<class T>
class CFilterT
{
  public:
    void Process();
};
#include "Filter.inl"

// file: FilterT.inl
template<class T>
CFilterT<T>::Process()
{
....
}



Ist die Templateimplementierung in der .cpp Datei, wird zwar kompiliert aber wenn ich das später benutzen möchte kommt ein Linkerfehler.

Grüße,
cmos
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
31.10.2011, 16:10 Uhr
cmos



Hallo nochmal,
das mit der Templatespezialisierung hat funktioniert.

Danke,
cmos
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
31.10.2011, 16:16 Uhr
ao

(Operator)


Verstehe ich das richtig, CFilterT<T> gehört zum API der Bibliothek?

Dann muss die Applikation das Bild untersuchen, den Pixeltyp ermitteln und eine passende CFilterT-Instanz erzeugen?

Ich würde sagen, das ist falsch entworfen. CFilterT sollte selbst kein Template sein. Du lieferst nur die Datei FilterT.h (ohne die .inl), und was in FilterT.cpp steckt (Template-Hexerei, Präprozessor-Magie oder was auch immer), geht keinen was an.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
31.10.2011, 17:09 Uhr
cmos



Hallo,
das mit CFilterT sollte nur am Beispiel die Problematik verdeutlichen. Da es mich interessiert wie beim Erstellen einer Bibliothek mit unterschiedlichen Datentypen umgegangen wird. Und da kam mir als Beispiel eben eine Bibliothek "X" für Bildverarbeitung in den Sinn, da dort oft unterschiedliche Bildformate unterstützt werden.

"CFilterT sollte selbst kein Template sein. Du lieferst nur die Datei FilterT.h (ohne die .inl), und was in FilterT.cpp steckt (Template-Hexerei, Präprozessor-Magie oder was auch immer), geht keinen was an."

Genau, so sollte es auch funktionieren.
Um mal bei der pathologischen Bildverarbeitungsbibliothek zu bleiben...

FilterT.h

C++:
template<class T>
class CFilterT
{
  public:
    CFilterT(void);
    ~CFilterT(void);
    void Add(T& a, T& b); // was auch immer Add im Filter zu suchen hat sei dahingestellt...
};

typedef CFilterT<char> Filter8;
typedef CFilterT<float> FilterF;



Filter.cpp

C++:
#include "FilterT.h"

template<class T>
CFilterT<T>::CFilterT(void)
{
}

template<class T>
CFilterT<T>::~CFilterT(void)
{
}

template<class T>
T CFilterT<T>::Add(T& a, T& b)
{
  return a+b;
}

template CFilterT<char>;
template CFilterT<float>;



Wenn ich das in meinem Lib-Projekt Compiliere brauche ich nur die Lib und die FitlerT.h mitzuliefern ohne den Code für die Template. Einschränkung ist hier, dass ich auf die Typen beschränkt bin die ich unten in der FilterT.cpp definiert habe.

Somit sollte es gehen.

Grüße.
cmos
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: