Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Allgemeines (OffTopic) » Gausscher Weichzeichner

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
09.07.2007, 13:47 Uhr
Blubber2063



Also ich hab folgendes Problem, für Merkmalserkennung in Bildern brauche ich einen Faltungskern der nen Gausschen Weichzeichner auf das Bild legt. Wir hatten einen im Netz gefunden, wollten das jetzt aber noch mal nach den Formeln die im Foliensatz standen probieren damit wir den blur Radius bestimmen können. Wenden wir aber folgende Funktionen an und falten dann mit dem enstehenden Kern kommt das Bild sehr abgedunkelt raus und das war nicht sinn und Zweck der Operation. Vielleicht hat ja einer von euch Ahnung von der Materie und sieht unseren Fehler.


C++:
void PoiPanel::gaussfilterx(int sizex, int sizey, Matrix& out){
    double pi = 2 * asin(1);
    double const deriv = 1.4;
    double nenn = 2 * pi * pow(deriv, 4);
    double nennexp = 2 * pow(deriv, 2);
    out.resize(sizex, sizey);
    for( int i = 1; i <= sizex; i++){
        for( int j = 1; j <= sizey; j++){
            out(i,j) = (-i / nenn) * exp(-((i*i+j*j) / nennexp));
        }
    }
};
void PoiPanel::gaussfiltery(int sizex, int sizey, Matrix& out){
    double pi = 2 * asin(1);
    double const deriv = 1.0;
    double nenn = 2 * pi * pow(deriv, 4);
    double nennexp = 2 * pow(deriv, 2);
    out.resize(sizex, sizey);
    for( int i = 1; i <= sizex; i++){
        for( int j = 1; j <= sizey; j++){
            out(i,j) = (-j / nenn) * exp(-((i*i+j*j) / nennexp));
        }
    }
};
void PoiPanel::betrag(Matrix &img1, Matrix &img2, Matrix&out){
    out.resize(img1.Nrows(), img1.Ncols());
        for (int i=1; i <= img1.Nrows(); i++) {
            for (int j=1; j <= img1.Ncols(); j++) {
                out(i,j) = sqrt(img1(i,j)*img1(i,j)+img2(i,j)*img2(i,j));
            }
        }
};


Wobei hier aus den beiden Filtern mit der betrags Funktion der Faltungskern gemacht wird.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
10.07.2007, 08:54 Uhr
mike
Pinguinhüpfer
(Operator)


Hi

Man kann X/Y getrennt machen - hab ich nie gemacht. Hab jetzt nur schnell drüber geschaut - aber es fehlt eine Randbehandlung soweit ich sehe (normieren der Maske). So hab ichs mal gemacht - man sollte das Prinzip heraussehen - Bildklasse is anders gestaltet:


C++:
Filter5::Filter5(const double k[5][5], bool normalize = true)
{
  
  double sum = 0.0;
  
  for(int row = 0; row < 5; row++)
    for(int col = 0; col < 5; col++){
      m_kernel[col][row] = k[col][row];
      sum += k[col][row];
    }
  
  if(normalize)
    m_factor = 1.0/sum;
  else
    m_factor = 1.0;
  
  cout << "Filter5: Constructor, normalized = " << normalize << endl;
  
}

PnmImage* Filter5::filter(const PnmImage* source) const
{
  cout << "Filter5: filtering image" << endl;
  
  int width = source->width();
  int height = source->height();
  int planes = source->planes();
  
  PnmImage* filter_img = new PnmImage(width, height, planes);

  double factor;
  double sum;
  double gnew[3];

  for(int x=0; x < width; x++) {
    for(int y=0; y < height; y++) {
      /* Durchschauen der gesamten Maske */
      /* gx = w1*z1 +...+ w25*z25 */
      gnew[0] = gnew[1] = gnew[2] = 0.0;
      sum = 0.0;


      for(int row = 0; row < 5; row++) {
        for(int col = 0; col < 5; col++) {
  
          /* Überprüfen ob pixel gültig oder nicht */
          if(x-2+col >= 0 && x-2+col < width &&
             y-2+row >= 0 && y-2+row < height) {

             gnew[0] += m_kernel[col][row] * static_cast<double>((*source)(x-2+col, y-2+row, 0)) * m_factor;
             if(planes == 3) {
               gnew[1] += m_kernel[col][row] * static_cast<double>((*source)(x-2+col, y-2+row, 1)) * m_factor;
               gnew[2] += m_kernel[col][row] * static_cast<double>((*source)(x-2+col, y-2+row, 2)) * m_factor;
             }
            
             sum += m_kernel[col][row];
                    
          }
        }
      } /* Ende Mask Multiplikation */

      gnew[0] *= (1.0 / sum); /* Eine normierte Matrix ist wieder eine normierte da sum ja 1 ist */
      if(planes == 3) {
        gnew[1] *= (1.0 / sum); /* Eine normierte Matrix ist wieder eine normierte da sum ja 1 ist */
        gnew[2] *= (1.0 / sum); /* Eine normierte Matrix ist wieder eine normierte da sum ja 1 ist */
      }

      (*filter_img)(x, y, 0) = static_cast<unsigned char>(gnew[0]);
      if(planes == 3) {
        (*filter_img)(x, y, 1) = static_cast<unsigned char>(gnew[1]);
        (*filter_img)(x, y, 2) = static_cast<unsigned char>(gnew[2]);
      }
    } /* y loop */
  } /* x loop */

  //filter_img->write("tmp.pnm");

  return filter_img;
}



Weiters empfiehlt es sich den Filter immer vorher zu berechnen - wird um einiges schneller.

lg


Bearbeitung:
Falscher Codeteil *g*

--

Dieser Post wurde am 10.07.2007 um 09:07 Uhr von mike editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
10.07.2007, 16:03 Uhr
Blubber2063



Jo das ist klar, da wird ja auch nur der Filter berechnet, das Problem hat sich erledigt, lag im wesentlichen daran das wir einem Missverständnis aufgesessen sind und zwar war die x-y Trennung was anderes. Das war die Kombination aus gausschem Weichzeichner und einem Kantendetektor, deshalb war das ganze dann auch nicht richtig.

Der Weichzeichner ist nicht nach x y zu trennen da hast du recht. Aber danke für dein Codebeispiel reicht zwar leider die Zeit nicht mehr um zu schaun ob die jetzt mit meiner Lösung übereinstimmt, aber ich werd mir das trotzdem später mal in Ruhe anschauen, thx.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
10.07.2007, 17:05 Uhr
mike
Pinguinhüpfer
(Operator)


Der Filter wird hier nicht berechnet. In meinem Programm gehe ich von einem Filter mit der Fixgröße 5x5 aus welcher mit [1] berechnet wird - mein Code faltet den Filter nur übers Bild.
Man kann den Gauss schon nach X und Y trennen - das ist der Vorteil - verwendet hab ichs noch nie

Hmm. Welcher Kantendetektor ist da drinnen?

[1] http://homepages.inf.ed.ac.uk/rbf/HIPR2/gsmooth.htm
--
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
10.07.2007, 22:23 Uhr
Blubber2063



Ja den Filter haben wir mittlerweile auch implementiert auf der Seite ham wir auch regelmässig geschaut, aber wo war da die x,y Trennung ? Naja die Funktionen die ich gepostet haben berechnen einen Filterkernel angegebener Größe, welcher Kantendetektor da drinne steckt frag mich jetzt nicht hat uns der Tutor gesagt und beim testen liefert er auch die Kanten eines Bildes. Vermutlich ist das ein Gradientenverfahren, aber da bin ich jetzt überfragt.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ Allgemeines (OffTopic) ]  


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: