具有反射边界的双边滤波器

时间:2012-12-05 20:47:01

标签: c++

我遇到的问题是我得到负值。我认为问题属于新的i,j值,它们是针对反射条件重新计算的。这里的代码: 第一部分已经实施,只有以待办事项开头的部分必须完成。

#include <math.h>
#include <stdio.h>
#include "BilateralFilter.h"

/* Constructor creates an Bilateral filter.
* sigma is the standard deviation of the spatial weight and
* delta is the standard deviation of the grayvalue differences weight. */
BilateralFilter::BilateralFilter( const double sigma, const double delta )
{
m_Sigma = sigma;
m_Delta = delta;
}
/* Destructor (does nothing) */
BilateralFilter::~BilateralFilter()
{
}

/* Internal Method to compute the Gaussian weights
 * depending on sigma (or delta) and x.
 * The return value is G(sigma,x)=exp(-(x*x)/2*sigma*sigma).
 *
 * The factor  1/(sigma*sqrt(2*pi)) of the Gaussian distribution is
 * constant and therefore not necessary to compute. */
 double BilateralFilter::Gaussian( const double sigma, const double x )
 {
 //printf("wert: %f\n",exp( -(x * x) / (2 * sigma * sigma) ) );
 return exp( -(x * x) / (2 * sigma * sigma) );

 }

/* Execute the bilateral filter. */
bool BilateralFilter::Execute()
{
// First, create a valid output image
// This fails if no valid input image is available.
if( !CreateOutputImage() )
return false;

// Define some often used constant variables to speed up the computation.
const int imageSizeX = m_InputImage->GetSizeX();
const int imageSizeY = m_InputImage->GetSizeY();

// The half size of the mask is defined as three times the
// standard deviation of the spatial Gaussian function.
const int filterHalfSizeX = static_cast<int>( 3 * m_Sigma );
const int filterHalfSizeY = static_cast<int>( 3 * m_Sigma );

/*
 * TODO: Aufgabe 2: Vervollstaendigen Sie die Implementierung des BilateralFilter.
 * Fuer die genaue Definition des Filters beachten sie das Aufgabenblatt und die Folien
 * zur Uebung.
 * Die Schleifen zur Iteration ueber die Bildpixel und die Nachbarschaften, sowie die
 * Ueberpruefung der Randbedingungen sind bereits vorgegeben.
 *
 * Sie muessen folgende Werte berechnen, um den Bilateralen Filter zu implementieren.
 * Der Punkt p ist dabei der aktuelle Zentrums-Pixel und q ein Punkt in der
 * Nachbarschaft von p.
 *
 * Die (Gauss-)Gewichtung des euklidischen Abstandes der Punkte p und q:
 *
 *     G_sigma(||p-q||)
 *
 * Die (Gauss-)Gewichtung der Differenz der Grauwerte im Eingangsbild an den Punkten   p    und q:
 *
 *     G_delta(I(p)-I(q))
 *
 * Den Normalisierungsfaktor als Summe des Produkts dieser Gewichtungen ueber alle Nachbarpunkte q:
 *
 *   W = Sum_{q in N} G_sigma(||p-q||)*G_delta(I(p)-I(q))
 *
 * Die Summe der gewichteten Grauwerte in der Nachbarschaft:
 *
 *   Sum_{q in N} G_sigma(||p-q||)*G_delta(I(p)-I(q))I(q)
 *
 * Hinweis 1: Verwenden Sie moeglichst double-Werte bei Ihren Berechnungen und casten Sie erst das
 * fertig berechnete Ergebnis auf den Typ Image::PixelType um Typfehler zu vermeiden.
 * Hinweis 2: Verwenden Sie die interne Methode Gaussian() um G_sigma bzw. G_delta zu berechnen. Uebergeben
 * Sie dabei das korrekte sigma/delta!
 * Hinweis 3: Vergessen sie nicht die Normalisierung 1/W !
 */

 // Iterate over all pixels.
 for(  int y = 0; y < imageSizeY; y++ )
 {
for( int x = 0; x < imageSizeX; x++ )
{
  // The coordinates of point p are given by (x,y).

  // Get the value of the center pixel.
  double centerValue = m_InputImage->GetPixel( x, y );

  // Variable to accumulate weighted greyvalues.
  double sumValue = 0;

  // Variable für gewichtete Gaußwerte-Abstand
  double G_sigma = 0;

  // Variable für gewichtete Grauwerte
  double G_delta = 0;
  double ende = 0;

  // Variable to accumulate weights for normalization.
  double sumCoeffcients = 0;

  // Iterate over all points in a neighborhood of p.
  for( int m = -filterHalfSizeY; m <= filterHalfSizeY; m++ )
  {
    // Calculate the y-coordinate of the current pixel.
    int j = y + m;

    // Apply reflecting boundary conditions on the current y-coordinate.
    if( j < 0 )
    {
      j = -j - 1;
    }
    else if( j >= imageSizeY )
    {
      j = 2 * imageSizeY - j - 1;
    }

    for( int k = -filterHalfSizeX; k <= filterHalfSizeX; k++ )
    {
      // Calculate the x-coordinate of the current neighbor pixel.
      int i = x + k;

      // Apply reflecting boundary conditions on the current x-coordinate.
      if( i < 0 )
      {
        i = -i - 1;
      }
      else if( i >= imageSizeX )
      {
        i = 2 * imageSizeX - i - 1;
      }

      // TODO The coordinates of the point q in a neighborhood of p are
      // now given by  (i,j). Mind that on the coordinates (i,j) the
      // boundary conditions have already been applied. The distance
      // ||(x,y)-(i,j)|| therefore differs from ||(x,y)-(x+k,y+m)||
      // near the boundary.

      //Berechnung G_sigma

      G_sigma = Gaussian(m_Sigma, sqrt(static_cast<double>(((x-i)*(x-i))+((y-j)*(y-j)))));
      //printf("m_Sigma: %f\nGauss: %f\n", m_Sigma, Gaussian(m_Sigma,x));

      // Berechnung G_delta

      G_delta = Gaussian(m_Delta, abs((centerValue-m_InputImage->GetPixel(i,j))));

      // Normalisierungsfaktor W

      sumCoeffcients += (G_sigma * G_delta);
      //printf("hallo: %f\n", sumCoeffcients);



      // Gesamtsumme

      sumValue += sumCoeffcients * m_InputImage->GetPixel(i,j);
      ende =(1/sumCoeffcients)*sumValue;
     //printf("i: %d\nj: %d\nsumme: %f\nsumvalue: %f\nG_sigma: %f\nG_delta: %f\n", i, j, sumCoeffcients, sumValue, G_sigma, G_delta);
    }
  }
  // TODO Set the pixel of the output image. Remember to cast the double
  // values to Image::PixelType, e.g. by static_cast<double>( value ).
  m_OutputImage->SetPixel(x,y,static_cast<Image::PixelType>(ende));
  printf("grauwert: %d\n", ende);
}
}

return true;
}

0 个答案:

没有答案